1 /* asyn_read() Author: Kees J. Bot
7 ssize_t
asyn_read(asynchio_t
*asyn
, int fd
, void *buf
, size_t len
)
8 /* Asynchronous read(). Try if a read can be done, if not then set a flag
9 * indicating that select(2) should look out for it. Returns like a normal
10 * read or returns -1 with errno set to EAGAIN.
15 /* Asyn_wait() may block if this counter equals zero indicating that
16 * all of the asyn_* functions are "in progress".
20 if ((unsigned) fd
>= FD_SETSIZE
) { errno
= EBADF
; return -1; }
21 afd
= &asyn
->asyn_afd
[fd
];
23 /* If this is the first async call on this filedescriptor then
24 * remember its file flags.
27 if ((afd
->afd_flags
= fcntl(fd
, F_GETFL
)) < 0) return -1;
31 /* Try to read if I/O is pending. */
32 if (afd
->afd_state
[SEL_READ
] == PENDING
) {
38 if (sigprocmask(SIG_SETMASK
, &mask
, &mask
) < 0) return -1;
39 (void) fcntl(fd
, F_SETFL
, afd
->afd_flags
| O_NONBLOCK
);
41 /* Try the actual read. */
42 result
= read(fd
, buf
, len
);
45 (void) fcntl(fd
, F_SETFL
, afd
->afd_flags
);
46 (void) sigprocmask(SIG_SETMASK
, &mask
, nil
);
49 if (result
!= -1 || errno
!= EAGAIN
) {
50 afd
->afd_state
[SEL_READ
]= IDLE
;
55 /* Record this read as "waiting". */
56 afd
->afd_state
[SEL_READ
]= WAITING
;
57 FD_SET(fd
, &asyn
->asyn_fdset
[SEL_READ
]);