work around bug(?) in Mac OS X select()
Using select() to check whether a pipe is ready for writing seems to fail on Mac OS X 10.8 and 10.9. See the PR for a small C program to demonstrate. It's possible that the small program is broken and there's no bug, but the program works on Linux and on Mac OS X 10.7 and 10.6. Although poll() seems to work, switching completely to poll() is not a good option on Mac OS X, since poll() does not support devices on that platform. The kqueue() facility seems to handle pipes and writing ok, so work around the bug by enabling the use of kqueue() on pipes. Closes PR 14596
This commit is contained in:
parent
94a5c6e3fb
commit
5cbe6cfdcb
|
@ -6280,7 +6280,9 @@ static void filesystem_change_evt_need_wakeup (Scheme_Object *evt, void *fds)
|
|||
}
|
||||
#endif
|
||||
|
||||
int scheme_fd_regular_file(intptr_t fd, int dir_ok)
|
||||
int scheme_fd_regular_file(intptr_t fd, int or_other)
|
||||
/* or_other == 1 => directory
|
||||
or_other == 2 => directory or fifo */
|
||||
{
|
||||
#if defined(USE_FD_PORTS) && !defined(DOS_FILE_SYSTEM)
|
||||
int ok;
|
||||
|
@ -6290,11 +6292,16 @@ int scheme_fd_regular_file(intptr_t fd, int dir_ok)
|
|||
ok = fstat(fd, &buf);
|
||||
} while ((ok == -1) && (errno == EINTR));
|
||||
|
||||
if (!S_ISREG(buf.st_mode)
|
||||
&& (!dir_ok || !S_ISDIR(buf.st_mode)))
|
||||
return 0;
|
||||
|
||||
if (S_ISREG(buf.st_mode))
|
||||
return 1;
|
||||
|
||||
if ((or_other >= 1) && S_ISDIR(buf.st_mode))
|
||||
return 1;
|
||||
|
||||
if ((or_other >= 2) && S_ISFIFO(buf.st_mode))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -7669,6 +7676,10 @@ fd_write_ready (Scheme_Object *port)
|
|||
MZ_FD_SET(fop->fd, exnfds);
|
||||
|
||||
do {
|
||||
/* Mac OS X 10.8 and 10.9: select() seems to claim that a pipe
|
||||
is always ready for output. To work around that problem,
|
||||
kqueue() support is enabled for pipes, so we shouldn't get
|
||||
here much for pipes. */
|
||||
sr = select(fop->fd + 1, NULL, writefds, exnfds, &time);
|
||||
} while ((sr == -1) && (errno == EINTR));
|
||||
#endif
|
||||
|
|
|
@ -3723,7 +3723,7 @@ Scheme_Object *scheme_fd_to_semaphore(intptr_t fd, int mode, int is_socket)
|
|||
|
||||
# ifdef HAVE_KQUEUE_SYSCALL
|
||||
if (!is_socket) {
|
||||
if (!scheme_fd_regular_file(fd, 10))
|
||||
if (!scheme_fd_regular_file(fd, 2))
|
||||
return NULL; /* kqueue() might not work on devices, such as ttys */
|
||||
}
|
||||
if (scheme_semaphore_fd_kqueue < 0) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user