Re: Add pselect, ppoll system calls.

2005-08-26 Thread Michael Kerrisk
David,

> On Fri, 2005-08-05 at 14:49 +0200, Michael Kerrisk wrote:
> > If I change your program to do something like the above, I also
> > do not see a message from the handler -- i.e., it is not being
> > called, and I'm pretty sure it should be.
> 
> Hm, yes. What happens is we come back out of the select() immediately
> because of the pending signal, but on the way back to userspace we put the
> old signal mask back... so by the time we check for it, there _is_ no
> (unblocked) signal pending. 
> 
> If it's mandatory that we actually call the signal handler, 

I'm just about to go off on holiday, and don't have a chance to pull up 
all the relevant standards details at them moment.  However, I'm fairly 
sure that the signal handler should be called.  (Try running a modified 
version of my program on Solaris 10 or the Unix-03 conversion of AIX 
(5.3?).)

> then we need to
> play tricks like sigsuspend() does to leave the old signal mask on the
> stack frame. That's a bit painful atm because do_signal is different
> between architectures. 

Yes, I'd say the behaviour should in fact be like what sigsuspend() does.

Cheers,

Michael
-
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/


Re: Add pselect, ppoll system calls.

2005-08-26 Thread Michael Kerrisk
David,

 On Fri, 2005-08-05 at 14:49 +0200, Michael Kerrisk wrote:
  If I change your program to do something like the above, I also
  do not see a message from the handler -- i.e., it is not being
  called, and I'm pretty sure it should be.
 
 Hm, yes. What happens is we come back out of the select() immediately
 because of the pending signal, but on the way back to userspace we put the
 old signal mask back... so by the time we check for it, there _is_ no
 (unblocked) signal pending. 
 
 If it's mandatory that we actually call the signal handler, 

I'm just about to go off on holiday, and don't have a chance to pull up 
all the relevant standards details at them moment.  However, I'm fairly 
sure that the signal handler should be called.  (Try running a modified 
version of my program on Solaris 10 or the Unix-03 conversion of AIX 
(5.3?).)

 then we need to
 play tricks like sigsuspend() does to leave the old signal mask on the
 stack frame. That's a bit painful atm because do_signal is different
 between architectures. 

Yes, I'd say the behaviour should in fact be like what sigsuspend() does.

Cheers,

Michael
-
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/


Re: Add pselect, ppoll system calls.

2005-08-24 Thread Ulrich Drepper
David Woodhouse wrote:
> If it's mandatory that we actually call the signal handler, then we need
> to play tricks like sigsuspend() does to leave the old signal mask on
> the stack frame. That's a bit painful atm because do_signal is different
> between architectures. 

It is necessary that the handler is called.  This is the purpose of
these interfaces.  If this means more complexity is needed then this is
how the cookie crumbles.  One use case for pselect would be something
like this:


int got_signal;
void sigint_handler(int sig) {
  got_signal = 1;
}

{
  ...
  while (1) {
if (!got_signal)
  pselect()

if (got_signal) {
  handle signal
  got_signal = 0;
}
  }
  ...
}

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖



signature.asc
Description: OpenPGP digital signature


Re: Add pselect, ppoll system calls.

2005-08-24 Thread Ulrich Drepper
David Woodhouse wrote:
 If it's mandatory that we actually call the signal handler, then we need
 to play tricks like sigsuspend() does to leave the old signal mask on
 the stack frame. That's a bit painful atm because do_signal is different
 between architectures. 

It is necessary that the handler is called.  This is the purpose of
these interfaces.  If this means more complexity is needed then this is
how the cookie crumbles.  One use case for pselect would be something
like this:


int got_signal;
void sigint_handler(int sig) {
  got_signal = 1;
}

{
  ...
  while (1) {
if (!got_signal)
  pselect()

if (got_signal) {
  handle signal
  got_signal = 0;
}
  }
  ...
}

-- 
➧ Ulrich Drepper ➧ Red Hat, Inc. ➧ 444 Castro St ➧ Mountain View, CA ❖



signature.asc
Description: OpenPGP digital signature


Re: Add pselect, ppoll system calls.

2005-08-05 Thread Michael Kerrisk
> 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 
#endif
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#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();
if (sigprocmask(SIG_BLOCK, , NULL) == -1) errExit("sigprocmask");

/* Establish hander for SIGINT */

sa.sa_handler = handler;
sigemptyset(_mask);
sa.sa_flags = 0;
if (sigaction(SIGINT, , NULL) == -1) errExit("sigaction");

/* Timeout is specified in argv[1] */

if (strcmp(argv[1], "-") == 0) {
pto = NULL; /* Infinite timeout */
} else {
pto = 
timeout.tv_sec = atoi(argv[1]);
timeout.tv_nsec = 0;
}

/* Initialize descriptor set */

nfds = 1;
FD_ZERO();
FD_SET(STDIN_FILENO, );

sigemptyset();
/* sigaddset(, 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, , NULL, NULL,
pto, );
#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_sec = atoi(argv[1]);
tv.tv_usec = 0;
}

if (sigprocmask(SIG_SETMASK, , NULL) == -1)
errExit("sigprocmask");

printf("Making syscall(SYS__newselect) call\n");
ready = syscall(SYS__newselect, nfds, , NULL, NULL, ptv);
printf(" Ignore timeout informati

Re: Add pselect, ppoll system calls.

2005-08-05 Thread Michael Kerrisk
 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 = empty;
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