> 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/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
|
|