This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[Various] libc/1828: signal handler chages errno while doing fdopen(3) to pipe.
- To: libc-alpha Mailinglist <libc-alpha at sourceware dot cygnus dot com>
- Subject: [Various] libc/1828: signal handler chages errno while doing fdopen(3) to pipe.
- From: Andreas Jaeger <aj at suse dot de>
- Date: 25 Jul 2000 09:14:07 +0200
- Cc: Junjiro Okajima <j-okajim at nskli014 dot nsk dot nis dot nec dot co dot jp>
We've received the appended bug report which I've answered directly
with a reference to ISO C99.
Looking again into it, I noticed that Unix98 and Posix allow to call
certain asynch-signal safe functions - which might set errno as a side
effect. What can we do? Can we do anything at all?
Andreas
Subject: Topics
Topics:
libc/1828: signal handler chages errno while doing fdopen(3) to pipe.
Re: libc/1828: signal handler chages errno while doing fdopen(3) to pipe.
- To: bugs at gnu dot org
- Subject: libc/1828: signal handler chages errno while doing fdopen(3) to pipe.
- From: Junjiro Okajima <j-okajim at nskli014 dot nsk dot nis dot nec dot co dot jp>
- Date: Mon, 24 Jul 2000 18:13:17 +0900
>Number: 1828
>Category: libc
>Synopsis: fdopen(3) to pipe fails
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: libc-gnats
>State: open
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Mon Jul 24 05:20:01 EDT 2000
>Last-Modified:
>Originator: Junjiro Okajima
>Organization:
NEC Informatec Systems Ltd
>Release: libc-2.1.1 to 2.1.3
>Environment:
inter celeron, PenII, PenIII, etc.
linux-2.2.10 to 2.2.16
Host type: i386-pc-linux-gnu
System: Linux nskli014 2.2.16 #2 SMP Fri Jul 14 20:49:35 JST 2000 i686 unknown
Architecture: i686
Addons: crypt linuxthreads localedata
Build CFLAGS: -O2
Build CC: gcc -B$(common-objpfx)
Build shared: yes
Build profile: yes
Build omitfp: no
Stdio: libio
>Description:
When an application has an event handler which calls some
systemalls, fdopen(3) to pipe fails somtimes.
fdopen(3) calls llseek(2) and check the return value and
errno(global var.) with an internal function file_attach(). If
the signal handler is called at just after the lseek(), just
before checking errno, and the signal handler change errno
other than ESPIPE, fdopen() fails and returns NULL in case of
lseek() succeeded.
>How-To-Repeat:
/* please adjust a timing parameter to suit your machine */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include <time.h>
#include <fcntl.h>
#define MAGIC 123456789
void
handler(int arg) {
// if an error happend in systemcall called by me,
// errno will be updated.
errno = MAGIC;
}
int
main(int argc, char *argv[])
{
int ret, fds[2];
pid_t pid;
signal(SIGUSR1, handler);
pid = getpid();
// send a signal simultaneously
if (!fork()) {
struct timespec req;
unsigned long n = 1;
req.tv_sec = 0;
req.tv_nsec = 0;
ret = 0;
while (!ret) {
req.tv_nsec = n++%999; // adjust here
nanosleep(&req, NULL);
ret = kill(pid, SIGUSR1);
}
exit(errno);
}
ret = pipe(fds);
if (ret) {
perror("before test begins");
exit(errno);
}
close(fds[1]);
{
struct timespec req;
unsigned long n = 1;
req.tv_sec = 0;
req.tv_nsec = 0;
while (1) {
int fd = dup(fds[0]);
FILE *fp = fdopen(fd, "r");
if (!fp) {
perror("Why fdopen");
signal(SIGUSR1, SIG_DFL);
kill(-pid, SIGKILL);
break; // while
}
fclose(fp);
req.tv_nsec = n++%3; // adjust here
//nanosleep(&req, NULL);
}
}
kill(-pid, SIGKILL);
waitpid(-1, NULL, 0);
return 0;
}
/* end of the code */
>Fix:
I think it is difficult to fix this bug. This is a matter of
global variables, and application can check/set errno at
anytime, but glibc cannot check or depend on errno.
>Audit-Trail:
>Unformatted:
- To: libc-gnats at gnu dot org
- Subject: Re: libc/1828: signal handler chages errno while doing fdopen(3) to pipe.
- From: Andreas Jaeger <aj at suse dot de>
- Date: Mon, 24 Jul 2000 09:30:01 -0400
- Cc: gnats-admin at gnu dot org
The following reply was made to PR libc/1828; it has been noted by GNATS.
From: Andreas Jaeger <aj@suse.de>
To: Junjiro Okajima <j-okajim@nskli014.nsk.nis.nec.co.jp>
Cc: bugs@gnu.org
Subject: Re: libc/1828: signal handler chages errno while doing fdopen(3) to pipe.
Date: 24 Jul 2000 14:06:55 +0200
>>>>> Junjiro Okajima writes:
>> Number: 1828
>> Category: libc
>> Synopsis: fdopen(3) to pipe fails
>> Confidential: no
>> Severity: serious
>> Priority: high
>> Responsible: libc-gnats
>> State: open
>> Class: sw-bug
>> Submitter-Id: unknown
>> Arrival-Date: Mon Jul 24 05:20:01 EDT 2000
>> Last-Modified:
>> Originator: Junjiro Okajima
>> Organization:
> NEC Informatec Systems Ltd
>> Release: libc-2.1.1 to 2.1.3
>> Environment:
> inter celeron, PenII, PenIII, etc.
> linux-2.2.10 to 2.2.16
> Host type: i386-pc-linux-gnu
> System: Linux nskli014 2.2.16 #2 SMP Fri Jul 14 20:49:35 JST 2000 i686 unknown
> Architecture: i686
> Addons: crypt linuxthreads localedata
> Build CFLAGS: -O2
> Build CC: gcc -B$(common-objpfx)
> Build shared: yes
> Build profile: yes
> Build omitfp: no
> Stdio: libio
>> Description:
> When an application has an event handler which calls some
> systemalls, fdopen(3) to pipe fails somtimes.
> fdopen(3) calls llseek(2) and check the return value and
> errno(global var.) with an internal function file_attach(). If
> the signal handler is called at just after the lseek(), just
> before checking errno, and the signal handler change errno
> other than ESPIPE, fdopen() fails and returns NULL in case of
> lseek() succeeded.
[...]
>> Fix:
> I think it is difficult to fix this bug. This is a matter of
> global variables, and application can check/set errno at
> anytime, but glibc cannot check or depend on errno.
The ISO C standard specifies:
[#5] If the signal occurs other than as the result of
calling the abort or raise function, the behavior is
undefined if the signal handler refers to any object with
static storage duration other than by assigning a value to
an object declared as volatile sig_atomic_t, or the signal
handler calls any function in the standard library other
than the abort function, the _Exit function, or the signal
function with the first argument equal to the signal number
corresponding to the signal that caused the invocation of
the handler. Furthermore, if such a call to the signal
function results in a SIG_ERR return, the value of errno is
indeterminate.211)
Therefore your signal handler is not allowed to mess around with errno
and call any other functions that might change errno.
Please fix your program.
Andreas
--
Andreas Jaeger
SuSE Labs aj@suse.de
private aj@arthur.inka.de
--
Andreas Jaeger
SuSE Labs aj@suse.de
private aj@arthur.inka.de