diff options
Diffstat (limited to 'x68/select.c')
-rw-r--r-- | x68/select.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/x68/select.c b/x68/select.c new file mode 100644 index 0000000000..b4bf464032 --- /dev/null +++ b/x68/select.c @@ -0,0 +1,167 @@ +/* + * PROJECT C Library, X68000 PROGRAMMING INTERFACE DEFINITION + * -------------------------------------------------------------------- + * This file is written by the Project C Library Group, and completely + * in public domain. You can freely use, copy, modify, and redistribute + * the whole contents, without this notice. + * -------------------------------------------------------------------- + * $Id$ + */ + +#ifndef __IOCS_INLINE__ +#define __IOCS_INLINE__ +#define __DOS_INLINE__ +#define __DOS_DOSCALL__ +#endif + +/* System headers */ +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <sys/dos.h> +#include <sys/iocs.h> +#include <sys/time.h> +#include <sys/types.h> +#if 0 +#include <sys/select.h> +#include <sys/xsocket.h> +#endif +#include <sys/xunistd.h> + +/* Macros */ +#define XFD_ISSET(fd,fds) ((fds) && FD_ISSET ((fd), (fds))) +#define isreadable(mode) ((mode) == O_RDONLY || (mode) == O_RDWR) +#define iswritable(mode) ((mode) == O_WRONLY || (mode) == O_RDWR) +#ifndef _POSIX_FD_SETSIZE +#define _POSIX_FD_SETSIZE OPEN_MAX +#endif + +/* Functions */ +int +select (int fds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *timeout) +{ + fd_set oread, owrite, oexcept; + int ticks, start; + int nfds; + + if (fds > _POSIX_FD_SETSIZE) + { + errno = EINVAL; + return -1; + } + + FD_ZERO (&oread); + FD_ZERO (&owrite); + FD_ZERO (&oexcept); + + nfds = 0; + ticks = -1; + + if (timeout) + { + ticks = timeout->tv_sec * 100 + timeout->tv_usec / 10000; + if (ticks < 0) + { + errno = EINVAL; + return -1; + } + } + + start = _iocs_ontime (); + for (;;) + { + { + int fd; + + for (fd = 0; fd < fds; fd++) + { + int accmode; + + if (_fddb[fd].inuse == _FD_NOTUSED) + continue; + + accmode = _fddb[fd].oflag & O_ACCMODE; + + if (isatty (fd)) + { + if (XFD_ISSET (fd, rfds) && isreadable (accmode) && _dos_k_keysns ()) + { + FD_SET (fd, &oread); + nfds++; + } + + if (XFD_ISSET (fd, wfds) && iswritable (accmode)) + { + FD_SET (fd, &owrite); + nfds++; + } + } +#if 0 + else if (_fddb[fd].sockno >= 0) + { + if (XFD_ISSET (fd, rfds) && _socklen (_fddb[fd].sockno, 0)) + { + FD_SET (fd, &oread); + nfds++; + } + + if (XFD_ISSET (fd, wfds) /* && _socklen (_fddb[fd].sockno, 1) == 0 */) + { + FD_SET (fd, &owrite); + nfds++; + } + } +#endif + else + { + if (XFD_ISSET (fd, rfds) && isreadable (accmode) && _dos_ioctrlis (fd)) + { + FD_SET (fd, &oread); + nfds++; + } + + if (XFD_ISSET (fd, wfds) && iswritable (accmode) && _dos_ioctrlos (fd)) + { + FD_SET (fd, &owrite); + nfds++; + } + } + } + } + + { + int rest; + + if ((rest = (_iocs_ontime () - start) % 8640000) < 0) + rest += 8640000; + + if (nfds != 0) + { + if (ticks >= 0) + { + int left; + + if ((left = ticks - rest) < 0) + left = 0; + + timeout->tv_sec = left / 100; + timeout->tv_usec = (left % 100) * 10000; + } + + if (rfds) + *rfds = oread; + if (wfds) + *wfds = owrite; + if (efds) + *efds = oexcept; + + return nfds; + } + + if (ticks >= 0 && rest > ticks) + return 0; + } + + _dos_change_pr (); + } +} |