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 +++
|