2005-04-21 16:53:53 +02:00
|
|
|
/* asyn_init(), asyn_read(), asyn_write(), asyn_ioctl(),
|
|
|
|
* asyn_wait(), asyn_synch(), asyn_close()
|
|
|
|
* Author: Kees J. Bot
|
|
|
|
* 26 Jan 1995
|
|
|
|
* Thise are just stub routines that are call compatible with
|
|
|
|
* the asynchio(3) library of Minix-vmd. See asynchio.h.
|
|
|
|
*/
|
|
|
|
#define alarm _alarm
|
|
|
|
#define ioctl _ioctl
|
|
|
|
#define read _read
|
|
|
|
#define sigaction _sigaction
|
|
|
|
#define sigfillset _sigfillset
|
|
|
|
#define time _time
|
|
|
|
#define write _write
|
|
|
|
#include <lib.h>
|
2005-06-01 11:36:07 +02:00
|
|
|
#include <time.h>
|
2005-04-21 16:53:53 +02:00
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include <sys/asynchio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <signal.h>
|
|
|
|
|
2005-06-01 16:31:00 +02:00
|
|
|
#define IO_IDLE 0
|
|
|
|
#define IO_INPROGRESS 1
|
|
|
|
#define IO_RESULT 2
|
2005-04-21 16:53:53 +02:00
|
|
|
|
|
|
|
#define OP_NOOP 0
|
|
|
|
#define OP_READ 1
|
|
|
|
#define OP_WRITE 2
|
|
|
|
#define OP_IOCTL 3
|
|
|
|
|
|
|
|
static asynchio_t *asyn_current;
|
|
|
|
|
|
|
|
void asyn_init(asynchio_t *asyn)
|
|
|
|
{
|
2005-06-01 16:31:00 +02:00
|
|
|
asyn->state= IO_IDLE;
|
2005-04-21 16:53:53 +02:00
|
|
|
asyn->op= OP_NOOP;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ssize_t operation(int op, asynchio_t *asyn, int fd, int req,
|
|
|
|
void *data, ssize_t count)
|
|
|
|
{
|
|
|
|
switch (asyn->state) {
|
2005-06-01 16:31:00 +02:00
|
|
|
case IO_INPROGRESS:
|
2005-04-21 16:53:53 +02:00
|
|
|
if (asyn_current != asyn && asyn->op != op) abort();
|
|
|
|
/*FALL THROUGH*/
|
2005-06-01 16:31:00 +02:00
|
|
|
case IO_IDLE:
|
2005-04-21 16:53:53 +02:00
|
|
|
asyn_current= asyn;
|
|
|
|
asyn->op= op;
|
|
|
|
asyn->fd= fd;
|
|
|
|
asyn->req= req;
|
|
|
|
asyn->data= data;
|
|
|
|
asyn->count= count;
|
2005-06-01 16:31:00 +02:00
|
|
|
asyn->state= IO_INPROGRESS;
|
2005-04-21 16:53:53 +02:00
|
|
|
errno= EINPROGRESS;
|
|
|
|
return -1;
|
2005-06-01 16:31:00 +02:00
|
|
|
case IO_RESULT:
|
2005-04-21 16:53:53 +02:00
|
|
|
if (asyn_current != asyn && asyn->op != op) abort();
|
|
|
|
errno= asyn->errno;
|
|
|
|
return asyn->count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t asyn_read(asynchio_t *asyn, int fd, void *buf, size_t len)
|
|
|
|
{
|
|
|
|
return operation(OP_READ, asyn, fd, 0, buf, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len)
|
|
|
|
{
|
|
|
|
return operation(OP_WRITE, asyn, fd, 0, (void *) buf, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
int asyn_ioctl(asynchio_t *asyn, int fd, unsigned long request, void *data)
|
|
|
|
{
|
|
|
|
return operation(OP_IOCTL, asyn, fd, request, data, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void time_out(int sig)
|
|
|
|
{
|
|
|
|
alarm(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to)
|
|
|
|
{
|
|
|
|
time_t now;
|
|
|
|
unsigned old_timer, new_timer;
|
|
|
|
struct sigaction old_sa, new_sa;
|
|
|
|
|
|
|
|
if (asyn_current != asyn) abort();
|
|
|
|
if (flags & ASYN_NONBLOCK) abort();
|
|
|
|
|
2005-06-01 16:31:00 +02:00
|
|
|
if (asyn->state == IO_RESULT) {
|
|
|
|
asyn->state= IO_IDLE;
|
2005-04-21 16:53:53 +02:00
|
|
|
asyn->op= OP_NOOP;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-04-07 13:25:51 +02:00
|
|
|
if (to != NULL) {
|
|
|
|
now= time(NULL);
|
2005-04-21 16:53:53 +02:00
|
|
|
if (to->tv_sec <= now) { errno= EINTR; return -1; }
|
|
|
|
old_timer= alarm(0);
|
|
|
|
new_sa.sa_handler= time_out;
|
|
|
|
sigfillset(&new_sa.sa_mask);
|
|
|
|
new_sa.sa_flags= 0;
|
|
|
|
sigaction(SIGALRM, &new_sa, &old_sa);
|
|
|
|
new_timer= to->tv_sec - now;
|
|
|
|
if (new_timer < old_timer) {
|
|
|
|
new_timer= old_timer;
|
|
|
|
}
|
|
|
|
alarm(new_timer);
|
|
|
|
}
|
|
|
|
switch (asyn->op) {
|
|
|
|
case OP_NOOP:
|
|
|
|
asyn->count= pause();
|
|
|
|
asyn->errno= errno;
|
|
|
|
case OP_READ:
|
|
|
|
asyn->count= read(asyn->fd, asyn->data, asyn->count);
|
|
|
|
asyn->errno= errno;
|
|
|
|
break;
|
|
|
|
case OP_WRITE:
|
|
|
|
asyn->count= write(asyn->fd, asyn->data, asyn->count);
|
|
|
|
asyn->errno= errno;
|
|
|
|
break;
|
|
|
|
case OP_IOCTL:
|
|
|
|
asyn->count= ioctl(asyn->fd, asyn->req, asyn->data);
|
|
|
|
asyn->errno= errno;
|
|
|
|
break;
|
|
|
|
}
|
2010-04-07 13:25:51 +02:00
|
|
|
if (to != NULL) {
|
2005-04-21 16:53:53 +02:00
|
|
|
alarm(0);
|
|
|
|
sigaction(SIGALRM, &old_sa, (struct sigaction *)0);
|
|
|
|
alarm(old_timer);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (asyn->count == -1 && asyn->errno == EINTR) {
|
|
|
|
errno= EINTR;
|
|
|
|
return -1;
|
|
|
|
} else {
|
2005-06-01 16:31:00 +02:00
|
|
|
asyn->state= IO_RESULT;
|
2005-04-21 16:53:53 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int asyn_synch(asynchio_t *asyn, int fd)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int asyn_close(asynchio_t *asyn, int fd)
|
|
|
|
{
|
|
|
|
asyn_init(asyn);
|
|
|
|
}
|