1,4 → 1,34 |
/* |
* Copyright (c) 2005 Martin Decky |
* Copyright (c) 2008 Jakub Jermar |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <ipc/ipc.h> |
6,7 → 36,12 |
#include <libc.h> |
#include <console.h> |
#include <ipc/services.h> |
#include <vfs/vfs.h> |
#include <errno.h> |
#include <fcntl.h> |
#include "../../srv/vfs/vfs.h" |
|
|
static void kputint(unsigned i) |
{ |
unsigned dummy; |
57,6 → 92,72 |
return newphid; |
} |
|
ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags) |
{ |
ipc_callid_t callid; |
|
callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags); |
|
return callid; |
} |
|
ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, uint32_t usec) |
{ |
ipc_callid_t callid; |
|
callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE); |
|
return callid; |
} |
|
ipc_callid_t ipc_purge_answers(void) |
{ |
ipc_callid_t callid; |
ipc_call_t call; |
|
do { |
callid = ipc_wait_cycle(&call, 0, SYNCH_FLAGS_NON_BLOCKING); |
printf("ipc_wait_cycle->%d\n", callid); |
} while (callid != 0); |
|
return callid; |
} |
|
ipc_callid_t ipc_wait_for_answer(ipc_callid_t req, ipc_call_t *call) |
{ |
ipc_callid_t callid; |
|
do { |
callid = ipc_wait_cycle(call, 0, SYNCH_FLAGS_NONE); |
} while ((callid & ~IPC_CALLID_ANSWERED) != req); |
|
return callid; |
} |
|
static ipc_callid_t async_rid; |
|
void ipc_call_async_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, void *private, |
ipc_async_callback_t callback, int can_preempt) |
{ |
ipc_purge_answers(); |
async_rid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, method, arg1, |
arg2, arg3, arg4); |
printf("ipc_call_async_fast->%d\n", async_rid); |
} |
|
int ipc_data_write_start(int phoneid, void *src, size_t size) |
{ |
return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, |
(ipcarg_t) size); |
} |
|
int ipc_data_read_start(int phoneid, void *dst, size_t size) |
{ |
return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, |
(ipcarg_t) size); |
} |
|
static int console_phone = -1; |
|
ssize_t write_stderr(const void *buf, size_t count) |
154,10 → 255,138 |
return EOF; |
} |
|
void _putint(int i) |
{ |
if (i == 0) { |
putchar('0'); |
return; |
} |
|
if (i < 0) { |
i = -i; |
putchar('-'); |
} |
|
if (i >= 10) { |
_putint(i/10); |
} |
putchar('0' + (i%10)); |
} |
|
int printf(const char *fmt, ...) |
{ |
int c; |
int i; |
|
va_list ap; |
va_start(ap, fmt); |
while (*fmt) { |
putchar(*fmt++); |
c = *fmt++; |
if (c == '%') { |
c = *fmt++; |
if (c == 'd') { |
i = va_arg(ap, int); |
_putint(i); |
} else if (c == '\0') { |
break; |
} else { |
putchar('%'); |
putchar(c); |
} |
} else { |
putchar(c); |
} |
} |
va_end(ap); |
return 0; |
} |
|
size_t strlen(const char *s) |
{ |
int l = 0; |
|
while (*s) { ++s; ++l; } |
return l; |
} |
|
//int vfs_phone = -1; |
int vfs_phone = 2; /* reuse phone from loader */ |
|
static int vfs_connect(void) |
{ |
if (vfs_phone < 0) |
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0); |
return vfs_phone; |
} |
|
static int _open(const char *path, int lflag, int oflag, ...) |
{ |
int res; |
ipcarg_t rc; |
ipc_call_t answer; |
|
const char *pa = path; |
int pa_len = strlen(path); |
|
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
return res; |
} |
} |
ipc_call_async_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, NULL, NULL,0); |
rc = ipc_data_write_start(vfs_phone, (char *)pa, pa_len); |
if (rc != EOK) { |
ipc_wait_for_answer(async_rid, &answer); |
return (int) rc; |
} |
ipc_wait_for_answer(async_rid, &answer); |
return (int) IPC_GET_ARG1(answer); |
} |
|
int open(const char *path, int oflag, ...) |
{ |
return _open(path, L_FILE, oflag); |
} |
|
int close(int fildes) |
{ |
int res; |
ipcarg_t rc; |
|
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
return res; |
} |
} |
|
rc = ipc_call_sync_1_0(vfs_phone, VFS_CLOSE, fildes); |
|
return (int)rc; |
} |
|
ssize_t read(int fildes, void *buf, size_t nbyte) |
{ |
int res; |
ipcarg_t rc; |
ipc_call_t answer; |
|
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
return res; |
} |
} |
ipc_call_async_1(vfs_phone, VFS_READ, fildes, NULL, NULL, 0); |
rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte); |
if (rc != EOK) { |
ipc_wait_for_answer(async_rid, &answer); |
return (ssize_t) rc; |
} |
ipc_wait_for_call(&answer); |
if (rc == EOK) |
return (ssize_t) IPC_GET_ARG1(answer); |
else |
return -1; |
} |