stream.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Josef Cejka
00003  * Copyright (C) 2006 Jakub Vana
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * - Redistributions of source code must retain the above copyright
00011  *   notice, this list of conditions and the following disclaimer.
00012  * - Redistributions in binary form must reproduce the above copyright
00013  *   notice, this list of conditions and the following disclaimer in the
00014  *   documentation and/or other materials provided with the distribution.
00015  * - The name of the author may not be used to endorse or promote products
00016  *   derived from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00019  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00020  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00021  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00023  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00024  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00025  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00026  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00027  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00037 #include <io/io.h>
00038 #include <io/stream.h>
00039 #include <string.h>
00040 #include <malloc.h>
00041 #include <libc.h>
00042 #include <ipc/ipc.h>
00043 #include <ipc/ns.h>
00044 #include <ipc/fb.h>
00045 #include <ipc/services.h>
00046 #include <console.h>
00047 #include <unistd.h>
00048 #include <async.h>
00049 
00050 #define FDS 32
00051 
00052 typedef struct stream_t {
00053         pwritefn_t w;
00054         preadfn_t r;
00055         void * param;
00056         int phone;
00057 } stream_t;
00058 
00059 static int console_phone = -1;
00060 static stream_t streams[FDS];
00061 
00062 static ssize_t write_stderr(void *param, const void *buf, size_t count)
00063 {
00064         return count;
00065 }
00066 
00067 static ssize_t read_stdin(void *param, void *buf, size_t count)
00068 {
00069         ipcarg_t r0,r1;
00070         size_t i = 0;
00071 
00072         while (i < count) {
00073                 if (async_req_2(streams[0].phone, CONSOLE_GETCHAR, 0, 0, &r0, &r1) < 0) {
00074                         return -1;
00075                 }
00076                 ((char *) buf)[i++] = r0;
00077         }
00078         return i;
00079 }
00080 
00081 static ssize_t write_stdout(void *param, const void *buf, size_t count)
00082 {
00083         int i;
00084 
00085         for (i = 0; i < count; i++)
00086                 async_msg(streams[1].phone, CONSOLE_PUTCHAR, ((const char *) buf)[i]);
00087         
00088         return count;
00089 }
00090 
00091 
00092 static stream_t open_stdin(void)
00093 {
00094         stream_t stream;
00095         
00096         if (console_phone < 0) {
00097                 while ((console_phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0)) < 0) {
00098                         usleep(10000);
00099                 }
00100         }
00101         
00102         stream.r = read_stdin;
00103         stream.w = NULL;
00104         stream.param = 0;
00105         stream.phone = console_phone;
00106         
00107         return stream;
00108 }
00109 
00110 static stream_t open_stdout(void)
00111 {
00112         stream_t stream;
00113 
00114         if (console_phone < 0) {
00115                 while ((console_phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0)) < 0) {
00116                         usleep(10000);
00117                 }
00118         }
00119         
00120         stream.r = NULL;
00121         stream.w = write_stdout;
00122         stream.phone = console_phone;
00123         stream.param = 0;
00124         
00125         return stream;
00126 }
00127 
00128 static ssize_t write_null(void *param, const void *buf, size_t count)
00129 {
00130         return count;
00131 }
00132 
00133 
00134 fd_t open(const char *fname, int flags)
00135 {
00136         int c = 0;
00137 
00138         while (((streams[c].w) || (streams[c].r)) && (c < FDS))
00139                 c++;
00140         
00141         if (c == FDS)
00142                 return EMFILE;
00143         
00144         if (!strcmp(fname, "stdin")) {
00145                 streams[c] = open_stdin();
00146                 return c;
00147         }
00148         
00149         if (!strcmp(fname, "stdout")) {
00150                 streams[c] = open_stdout();
00151                 return c;
00152         }
00153         
00154         if (!strcmp(fname, "stderr")) {
00155                 streams[c].w = write_stderr;
00156                 return c;
00157         }
00158         
00159         if (!strcmp(fname, "null")) {
00160                 streams[c].w = write_null;
00161                 return c;
00162         }
00163         
00164         return -1;
00165 }
00166 
00167 
00168 ssize_t write(int fd, const void *buf, size_t count)
00169 {
00170 //      __SYSCALL3(SYS_IO, 1, (sysarg_t)buf, (sysarg_t) count);
00171 //      return count;
00172         if (fd < FDS)
00173                 return streams[fd].w(streams[fd].param, buf, count);
00174         
00175         return 0;
00176 }
00177 
00178 ssize_t read(int fd, void *buf, size_t count)
00179 {
00180         if (fd < FDS)
00181                 return streams[fd].r(streams[fd].param, buf, count);
00182         
00183         return 0;
00184 }
00185 
00186 int get_fd_phone(int fd)
00187 {
00188         if (fd >= FDS || fd < 0)
00189                 return -1;
00190         return streams[fd].phone;
00191 }
00192 
00193 

Generated on Sun Jun 18 18:00:18 2006 for HelenOS Userspace (ia64) by  doxygen 1.4.6