> From: David Woodhouse <[EMAIL PROTECTED]> > Subject: Re: Add pselect, ppoll system calls. > Date: Wed, 15 Jun 2005 12:36:54 +0100 > > On Mon, 2005-06-13 at 08:38 -0700, Ulrich Drepper wrote: > > > Eep -- I hadn't noticed that difference. Will update patch > > accordingly. > > > > And change [the poll timeout] to expect a 64bit value I hope... > > I believe that 64-bit int types in syscalls are a pain on some > architectures because of restrictions on precisely which register pairs > may be used. I think I'd rather just use a struct timespec, which also > makes it consistent with pselect(). > > > > The other documented difference (other than the signal mask bit) is > > > that > > > pselect() is documented not to modify the timeout parameter. I'm not > > > sure whether I should preserve that difference, or not. > > > > As long as there is a configuration where the timeout value is not > > modified, it doesn't matter. That is the case for select() using a > > personality switch. > > I've made pselect() consistent with select() by using the same > personality switch to control its behaviour. > > I've also fixed select() so that timeouts of greater than LONG_MAX > jiffies are implemented accurately, instead of being infinite.
Hi David, I applied the 15 Jun version of your patch agains 2.6.12 and tried a test program. I see some behaviour that puzzles me. When I run the program below, and type control-C, the program tells me that the SIGINT hander was *not* called: ./t_pselect - Making syscall(SYS_pselect6) call [Type ^C] pselect: Unknown error 514 <-- ERESTNOHAND ready = -1 stdin IS NOT readable signal handler WAS NOT called I'm not sure whether this is possibly a mistake in the way I've constructed my test program (I don't think so, but I'm not !00% confident), or some bug in the implementation (I did try making a syscall(SYS__newselect), and that *did* show the signal handler being called. Also, I now have a test result on Solaris 10 for pselect(), and it shows the signal handler is called in this case.) Cheers, Michael /* t_pselect.c Michael Kerrisk, Aug 2005 */ #if defined(__linux__) && !defined(NO_SYSCALL) #define USE_PSELECT_SYSCALL 1 #endif #ifdef USE_PSELECT_SYSCALL #define _GNU_SOURCE #include <syscall.h> #endif #include <sys/time.h> #include <sys/select.h> #include <signal.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #define errMsg(msg) do { perror(msg); } while (0) #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ } while (0) #ifdef USE_PSELECT_SYSCALL /* Following are for x86 */ #define SYS_pselect6 289 #define SYS_ppoll 290 #endif sig_atomic_t gotsig = 0; static void handler(int sig) { gotsig = 1; printf("Caught signal %d\n", sig); /* UNSAFE (see Section $$$) */ } /* handler */ int main(int argc, char *argv[]) { fd_set readfds; int ready, nfds; struct timespec timeout; struct timespec *pto; struct sigaction sa; #ifdef USE_PSELECT_SYSCALL struct { sigset_t *sp; size_t size; } pselarg6; #endif sigset_t empty, all; if (argc != 2) { fprintf(stderr, "Usage: %s {nsecs|-}\n", argv[1]); exit(EXIT_FAILURE); } setbuf(stdout, NULL); /* Block all sigs */ sigfillset(&all); if (sigprocmask(SIG_BLOCK, &all, NULL) == -1) errExit("sigprocmask"); /* Establish hander for SIGINT */ sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGINT, &sa, NULL) == -1) errExit("sigaction"); /* Timeout is specified in argv[1] */ if (strcmp(argv[1], "-") == 0) { pto = NULL; /* Infinite timeout */ } else { pto = &timeout; timeout.tv_sec = atoi(argv[1]); timeout.tv_nsec = 0; } /* Initialize descriptor set */ nfds = 1; FD_ZERO(&readfds); FD_SET(STDIN_FILENO, &readfds); sigemptyset(&empty); /* sigaddset(&empty, SIGINT); */ /* Make the call */ #ifdef USE_PSELECT_SYSCALL #if 1 printf("Making syscall(SYS_pselect6) call\n"); pselarg6.sp = ∅ pselarg6.size = 8; /* sizeof(sigset_t) */ ready = syscall(SYS_pselect6, nfds, &readfds, NULL, NULL, pto, &pselarg6); #else /* The following is just some testing cruft */ { struct timeval tv; struct timeval *ptv; if (strcmp(argv[1], "-") == 0) { ptv = NULL; /* Infinite timeout */ } else { ptv = &tv; tv.tv_sec = atoi(argv[1]); tv.tv_usec = 0; } if (sigprocmask(SIG_SETMASK, &empty, NULL) == -1) errExit("sigprocmask"); printf("Making syscall(SYS__newselect) call\n"); ready = syscall(SYS__newselect, nfds, &readfds, NULL, NULL, ptv); printf("!!!! Ignore timeout information printed below !!!!\n"); } #endif #else /* This is how a "proper" pselect() call looks on other implementations, or when calling the non-atomic glibc version */ printf("Making simple pselect() call\n"); ready = pselect(nfds, &readfds, NULL, NULL, pto, &empty); #endif /* Now see what happened */ if (ready == -1) errMsg("pselect"); printf("ready = %d\n", ready); printf("stdin %s readable\n", ready > 0 && FD_ISSET(STDIN_FILENO, &readfds) ? "IS" : "IS NOT"); printf("Signal handler %s called\n", gotsig ? "WAS" : "WAS NOT"); if (pto != NULL) printf("timeout after select(): %ld.%03ld\n", (long) timeout.tv_sec, (long) timeout.tv_nsec / 10000000); exit(EXIT_SUCCESS); } /* main */ -- 5 GB Mailbox, 50 FreeSMS http://www.gmx.net/de/go/promail +++ GMX - die erste Adresse für Mail, Message, More +++ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/