int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *closure) { struct sigaction sa; struct sigaction osa; int i; int blocked; for (i = 0; i < MAX_FUNCS; i++) { if (!xf86SigIOFuncs[i].f) { if (xf86IsPipe (fd)) return 0; blocked = xf86BlockSIGIO(); if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_ASYNC) == -1) { #ifdef XFree86Server xf86Msg(X_WARNING, "fcntl(%d, O_ASYNC): %s\n", fd, strerror(errno)); #else fprintf(stderr,"fcntl(%d, O_ASYNC): %s\n", fd, strerror(errno)); #endif xf86UnblockSIGIO(blocked); return 0; } if (fcntl(fd, F_SETOWN, getpid()) == -1) { #ifdef XFree86Server xf86Msg(X_WARNING, "fcntl(%d, F_SETOWN): %s\n", fd, strerror(errno)); #else fprintf(stderr,"fcntl(%d, F_SETOWN): %s\n", fd, strerror(errno)); #endif xf86UnblockSIGIO(blocked); return 0; } sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sa.sa_flags = 0; sa.sa_handler = xf86SIGIO; sigaction(SIGIO, &sa, &osa); xf86SigIOFuncs[i].fd = fd; xf86SigIOFuncs[i].closure = closure; xf86SigIOFuncs[i].f = f; if (i >= xf86SigIOMax) xf86SigIOMax = i+1; if (fd >= xf86SigIOMaxFd) xf86SigIOMaxFd = fd + 1; FD_SET (fd, &xf86SigIOMask); xf86UnblockSIGIO(blocked); return 1; } /* Allow overwriting of the closure and callback */ else if (xf86SigIOFuncs[i].fd == fd) { xf86SigIOFuncs[i].closure = closure; xf86SigIOFuncs[i].f = f; return 1; } } return 0; }
int xf86InstallSIGIOHandler(int fd, void (*f) (int, void *), void *closure) { struct sigaction sa; struct sigaction osa; int i; int installed = FALSE; if (!xf86Info.useSIGIO) return 0; for (i = 0; i < MAX_FUNCS; i++) { if (!xf86SigIOFuncs[i].f) { if (xf86IsPipe(fd)) return 0; OsBlockSIGIO(); #ifdef O_ASYNC if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_ASYNC) == -1) { xf86Msg(X_WARNING, "fcntl(%d, O_ASYNC): %s\n", fd, strerror(errno)); } else { if (fcntl(fd, F_SETOWN, getpid()) == -1) { xf86Msg(X_WARNING, "fcntl(%d, F_SETOWN): %s\n", fd, strerror(errno)); } else { installed = TRUE; } } #endif #ifdef I_SETSIG /* System V Streams - used on Solaris for input devices */ if (!installed && isastream(fd)) { if (ioctl(fd, I_SETSIG, S_INPUT | S_ERROR | S_HANGUP) == -1) { xf86Msg(X_WARNING, "fcntl(%d, I_SETSIG): %s\n", fd, strerror(errno)); } else { installed = TRUE; } } #endif if (!installed) { OsReleaseSIGIO(); return 0; } sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sa.sa_flags = 0; sa.sa_handler = xf86SIGIO; sigaction(SIGIO, &sa, &osa); xf86SigIOFuncs[i].fd = fd; xf86SigIOFuncs[i].closure = closure; xf86SigIOFuncs[i].f = f; if (i >= xf86SigIOMax) xf86SigIOMax = i + 1; if (fd >= xf86SigIOMaxFd) xf86SigIOMaxFd = fd + 1; FD_SET(fd, &xf86SigIOMask); OsReleaseSIGIO(); return 1; } /* Allow overwriting of the closure and callback */ else if (xf86SigIOFuncs[i].fd == fd) { xf86SigIOFuncs[i].closure = closure; xf86SigIOFuncs[i].f = f; return 1; } } return 0; }