kernel: scheduling fix for ARM
[minix.git] / lib / libasyn / asyn_write.c
blob7e9878aff30a8cb7cd64d6082c70facc0af7a6a9
1 /* asyn_write() Author: Kees J. Bot
2 * 7 Jul 1997
3 */
4 #include "asyn.h"
5 #include <signal.h>
7 ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len)
8 /* Nonblocking write(). (See asyn_read()). */
10 asynfd_t *afd;
12 asyn->asyn_more++;
14 if ((unsigned) fd >= FD_SETSIZE) { errno= EBADF; return -1; }
15 afd= &asyn->asyn_afd[fd];
17 if (!afd->afd_seen) {
18 if ((afd->afd_flags= fcntl(fd, F_GETFL)) < 0) return -1;
19 afd->afd_seen= 1;
22 if (afd->afd_state[SEL_WRITE] == PENDING) {
23 sigset_t mask;
24 ssize_t result;
25 int err;
27 sigemptyset(&mask);
28 if (sigprocmask(SIG_SETMASK, &mask, &mask) < 0) return -1;
29 (void) fcntl(fd, F_SETFL, afd->afd_flags | O_NONBLOCK);
31 result= write(fd, buf, len);
32 err= errno;
34 (void) fcntl(fd, F_SETFL, afd->afd_flags);
35 (void) sigprocmask(SIG_SETMASK, &mask, nil);
37 errno= err;
38 if (result != -1 || errno != EAGAIN) {
39 afd->afd_state[SEL_WRITE]= IDLE;
40 return result;
44 afd->afd_state[SEL_WRITE]= WAITING;
45 FD_SET(fd, &asyn->asyn_fdset[SEL_WRITE]);
46 errno= EAGAIN;
47 asyn->asyn_more--;
48 return -1;