asynchio.c

Go to the documentation of this file.
00001 /*      asyn_init(), asyn_read(), asyn_write(), asyn_ioctl(),
00002  *      asyn_wait(), asyn_synch(), asyn_close()
00003  *                                                      Author: Kees J. Bot
00004  *                                                              26 Jan 1995
00005  * Thise are just stub routines that are call compatible with
00006  * the asynchio(3) library of Minix-vmd.  See asynchio.h.
00007  */
00008 #define nil 0
00009 #define alarm   _alarm
00010 #define ioctl   _ioctl
00011 #define read    _read
00012 #define sigaction _sigaction
00013 #define sigfillset _sigfillset
00014 #define time    _time
00015 #define write   _write
00016 #include <lib.h>
00017 #include <time.h>
00018 #include <sys/ioctl.h>
00019 #include <sys/asynchio.h>
00020 #include <stdlib.h>
00021 #include <unistd.h>
00022 #include <string.h>
00023 #include <signal.h>
00024 
00025 #define IO_IDLE         0
00026 #define IO_INPROGRESS   1
00027 #define IO_RESULT       2
00028 
00029 #define OP_NOOP         0
00030 #define OP_READ         1
00031 #define OP_WRITE        2
00032 #define OP_IOCTL        3
00033 
00034 static asynchio_t *asyn_current;
00035 
00036 void asyn_init(asynchio_t *asyn)
00037 {
00038         asyn->state= IO_IDLE;
00039         asyn->op= OP_NOOP;
00040 }
00041 
00042 static ssize_t operation(int op, asynchio_t *asyn, int fd, int req,
00043                                                 void *data, ssize_t count)
00044 {
00045         switch (asyn->state) {
00046         case IO_INPROGRESS:
00047                 if (asyn_current != asyn && asyn->op != op) abort();
00048                 /*FALL THROUGH*/
00049         case IO_IDLE:
00050                 asyn_current= asyn;
00051                 asyn->op= op;
00052                 asyn->fd= fd;
00053                 asyn->req= req;
00054                 asyn->data= data;
00055                 asyn->count= count;
00056                 asyn->state= IO_INPROGRESS;
00057                 errno= EINPROGRESS;
00058                 return -1;
00059         case IO_RESULT:
00060                 if (asyn_current != asyn && asyn->op != op) abort();
00061                 errno= asyn->errno;
00062                 return asyn->count;
00063         }
00064 }
00065 
00066 ssize_t asyn_read(asynchio_t *asyn, int fd, void *buf, size_t len)
00067 {
00068         return operation(OP_READ, asyn, fd, 0, buf, len);
00069 }
00070 
00071 ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len)
00072 {
00073         return operation(OP_WRITE, asyn, fd, 0, (void *) buf, len);
00074 }
00075 
00076 int asyn_ioctl(asynchio_t *asyn, int fd, unsigned long request, void *data)
00077 {
00078         return operation(OP_IOCTL, asyn, fd, request, data, 0);
00079 }
00080 
00081 static void time_out(int sig)
00082 {
00083         alarm(1);
00084 }
00085 
00086 int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to)
00087 {
00088         time_t now;
00089         unsigned old_timer, new_timer;
00090         struct sigaction old_sa, new_sa;
00091 
00092         if (asyn_current != asyn) abort();
00093         if (flags & ASYN_NONBLOCK) abort();
00094 
00095         if (asyn->state == IO_RESULT) {
00096                 asyn->state= IO_IDLE;
00097                 asyn->op= OP_NOOP;
00098                 return 0;
00099         }
00100 
00101         if (to != nil) {
00102                 now= time(nil);
00103                 if (to->tv_sec <= now) { errno= EINTR; return -1; }
00104                 old_timer= alarm(0);
00105                 new_sa.sa_handler= time_out;
00106                 sigfillset(&new_sa.sa_mask);
00107                 new_sa.sa_flags= 0;
00108                 sigaction(SIGALRM, &new_sa, &old_sa);
00109                 new_timer= to->tv_sec - now;
00110                 if (new_timer < old_timer) {
00111                         new_timer= old_timer;
00112                 }
00113                 alarm(new_timer);
00114         }
00115         switch (asyn->op) {
00116         case OP_NOOP:
00117                 asyn->count= pause();
00118                 asyn->errno= errno;
00119         case OP_READ:
00120                 asyn->count= read(asyn->fd, asyn->data, asyn->count);
00121                 asyn->errno= errno;
00122                 break;
00123         case OP_WRITE:
00124                 asyn->count= write(asyn->fd, asyn->data, asyn->count);
00125                 asyn->errno= errno;
00126                 break;
00127         case OP_IOCTL:
00128                 asyn->count= ioctl(asyn->fd, asyn->req, asyn->data);
00129                 asyn->errno= errno;
00130                 break;
00131         }
00132         if (to != nil) {
00133                 alarm(0);
00134                 sigaction(SIGALRM, &old_sa, (struct sigaction *)0);
00135                 alarm(old_timer);
00136         }
00137 
00138         if (asyn->count == -1 && asyn->errno == EINTR) {
00139                 errno= EINTR;
00140                 return -1;
00141         } else {
00142                 asyn->state= IO_RESULT;
00143                 return 0;
00144         }
00145 }
00146 
00147 int asyn_synch(asynchio_t *asyn, int fd)
00148 {
00149 }
00150 
00151 int asyn_close(asynchio_t *asyn, int fd)
00152 {
00153         asyn_init(asyn);
00154 }

Generated on Fri Apr 14 22:57:26 2006 for minix by  doxygen 1.4.6