Email List: Xaustin-group-lX
[All Lists]

Stop signals and interruption of system calls on Linux

To: yyyyyyyyyyyyyy@xxxxxxxxxxxxx
Subject: Stop signals and interruption of system calls on Linux
From: "Michael T Kerrisk" <yyyyyyyyy@xxxxxxx>
Date: Fri, 13 Feb 2004 11:44:50 +0100 (MET)
Gidday again,

My second question relates to what I regard as a rather strange 
behavior on Linux with respect to signals.

On Linux, the delivery of a stop signal (SIGTSTP, SIGSTOP, etc) 
plus subsequent SIGCONT can cause a certain blocking system calls 
(e.g., semop()) to return EINTR **even if the program is not 
catching the stop signal**.  

For example, if we run the program below (which uses semop()), 
then on Linux we see the following:

    $ ./a.out
    65538                 # This is just the semaphore ID
    About to semop()
    ^Z                    # Type control-Z to generate SIGTSTP
    [1]+  Stopped        ./a.out
    $ fg
    ./a.out
    semop: Interrupted system call

I’ve seen claims that:

a) This behavior is permitted by the standard.  However, 
   with some assistance from Geoff Clare, I’ve come to the 
   conclusion that the standard does not permit this.  
   In particular, the specification for EINTR says:

        [EINTR]
        Interrupted function call. An asynchronous signal 
        was caught by the process during the execution of an 
        interruptible function. If the signal handler 
        performs a normal return, the interrupted function 
        call may return this condition (see the Base 
        Definitions volume of IEEE Std 1003.1-2001, <signal.h>).

   and at the end of the Signal Concepts section, under the 
   heading Signal Effects on Other Functions (2.4.4), we see
 
        If the action of the signal is to invoke a 
        signal-catching function, the signal-catching function 
        shall be invoked; in this case the original function 
        is said to be ``interrupted'' by the signal."

   In other words, EINTR should only occur in the presence 
   of a signal handler.

b) Other implementations might do the same.  However, I’ve 
   never seen this on another implementation, and recently 
   I’ve tested Tru64 5.1B, FreeBSD 4.8, Solaris 8, 
   HP-UX 11.22, and Irix 6.5.  On all of these 
   implementations, we see the following:

        $ ./a.out
        21               # Whatever ID happens to be generated
        About to semop()
       ^Z
       [1]+  Stopped        ./a.out
       Stopped
       $ fg
       ./a.out

   at this point, the program continues, but remains blocked 
   in the semop() call.


My question is, does anyone know of any other implementation 
that behaves like Linux?

Cheers,

Michael


/* semop_stop.c */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#ifndef NO_SEMUN        /* Not needed on FreeBSD and Irix */
union semun {
    int                 val;
    struct semid_ds *   buf;
    unsigned short *    array;
#if defined(__linux__)
    struct seminfo *    __buf;
#endif
};
#endif

#define errExit(msg)    { perror(msg); exit(EXIT_FAILURE); }

int
main(int argc, char *argv[])
{
    int semid;
    union semun arg;
    struct sembuf sop;

    semid = semget(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR);
    if (semid == -1) errExit("semget");
    printf("%d\n", semid);
    arg.val = 0;
    if (semctl(semid, 0, SETVAL, arg) == -1) errExit("semctl");

    sop.sem_num = 0;
    sop.sem_op = -1;
    sop.sem_flg = 0;
    printf("About to semop()\n");
    if (semop(semid, &sop, 1) == -1) errExit("semop");

    exit(EXIT_SUCCESS);
} /* main */

-- 
Michael Kerrisk
yyyyyyyyy@xxxxxxx

GMX ProMail (250 MB Mailbox, 50 FreeSMS, Virenschutz, 2,99 EUR/Monat...)
jetzt 3 Monate GRATIS + 3x DER SPIEGEL +++ http://www.gmx.net/derspiegel +++

<Prev in Thread] Current Thread [Next in Thread>