00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00171
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