source: trunk/minix/lib/other/asynchio.c@ 12

Last change on this file since 12 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.2 KB
Line 
1/* asyn_init(), asyn_read(), asyn_write(), asyn_ioctl(),
2 * asyn_wait(), asyn_synch(), asyn_close()
3 * Author: Kees J. Bot
4 * 26 Jan 1995
5 * Thise are just stub routines that are call compatible with
6 * the asynchio(3) library of Minix-vmd. See asynchio.h.
7 */
8#define nil 0
9#define alarm _alarm
10#define ioctl _ioctl
11#define read _read
12#define sigaction _sigaction
13#define sigfillset _sigfillset
14#define time _time
15#define write _write
16#include <lib.h>
17#include <time.h>
18#include <sys/ioctl.h>
19#include <sys/asynchio.h>
20#include <stdlib.h>
21#include <unistd.h>
22#include <string.h>
23#include <signal.h>
24
25#define IO_IDLE 0
26#define IO_INPROGRESS 1
27#define IO_RESULT 2
28
29#define OP_NOOP 0
30#define OP_READ 1
31#define OP_WRITE 2
32#define OP_IOCTL 3
33
34static asynchio_t *asyn_current;
35
36void asyn_init(asynchio_t *asyn)
37{
38 asyn->state= IO_IDLE;
39 asyn->op= OP_NOOP;
40}
41
42static ssize_t operation(int op, asynchio_t *asyn, int fd, int req,
43 void *data, ssize_t count)
44{
45 switch (asyn->state) {
46 case IO_INPROGRESS:
47 if (asyn_current != asyn && asyn->op != op) abort();
48 /*FALL THROUGH*/
49 case IO_IDLE:
50 asyn_current= asyn;
51 asyn->op= op;
52 asyn->fd= fd;
53 asyn->req= req;
54 asyn->data= data;
55 asyn->count= count;
56 asyn->state= IO_INPROGRESS;
57 errno= EINPROGRESS;
58 return -1;
59 case IO_RESULT:
60 if (asyn_current != asyn && asyn->op != op) abort();
61 errno= asyn->errno;
62 return asyn->count;
63 }
64}
65
66ssize_t asyn_read(asynchio_t *asyn, int fd, void *buf, size_t len)
67{
68 return operation(OP_READ, asyn, fd, 0, buf, len);
69}
70
71ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len)
72{
73 return operation(OP_WRITE, asyn, fd, 0, (void *) buf, len);
74}
75
76int asyn_ioctl(asynchio_t *asyn, int fd, unsigned long request, void *data)
77{
78 return operation(OP_IOCTL, asyn, fd, request, data, 0);
79}
80
81static void time_out(int sig)
82{
83 alarm(1);
84}
85
86int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to)
87{
88 time_t now;
89 unsigned old_timer, new_timer;
90 struct sigaction old_sa, new_sa;
91
92 if (asyn_current != asyn) abort();
93 if (flags & ASYN_NONBLOCK) abort();
94
95 if (asyn->state == IO_RESULT) {
96 asyn->state= IO_IDLE;
97 asyn->op= OP_NOOP;
98 return 0;
99 }
100
101 if (to != nil) {
102 now= time(nil);
103 if (to->tv_sec <= now) { errno= EINTR; return -1; }
104 old_timer= alarm(0);
105 new_sa.sa_handler= time_out;
106 sigfillset(&new_sa.sa_mask);
107 new_sa.sa_flags= 0;
108 sigaction(SIGALRM, &new_sa, &old_sa);
109 new_timer= to->tv_sec - now;
110 if (new_timer < old_timer) {
111 new_timer= old_timer;
112 }
113 alarm(new_timer);
114 }
115 switch (asyn->op) {
116 case OP_NOOP:
117 asyn->count= pause();
118 asyn->errno= errno;
119 case OP_READ:
120 asyn->count= read(asyn->fd, asyn->data, asyn->count);
121 asyn->errno= errno;
122 break;
123 case OP_WRITE:
124 asyn->count= write(asyn->fd, asyn->data, asyn->count);
125 asyn->errno= errno;
126 break;
127 case OP_IOCTL:
128 asyn->count= ioctl(asyn->fd, asyn->req, asyn->data);
129 asyn->errno= errno;
130 break;
131 }
132 if (to != nil) {
133 alarm(0);
134 sigaction(SIGALRM, &old_sa, (struct sigaction *)0);
135 alarm(old_timer);
136 }
137
138 if (asyn->count == -1 && asyn->errno == EINTR) {
139 errno= EINTR;
140 return -1;
141 } else {
142 asyn->state= IO_RESULT;
143 return 0;
144 }
145}
146
147int asyn_synch(asynchio_t *asyn, int fd)
148{
149}
150
151int asyn_close(asynchio_t *asyn, int fd)
152{
153 asyn_init(asyn);
154}
Note: See TracBrowser for help on using the repository browser.