- Subject: libc/1708:
- From: pelliott at nowdocs dot com
- Date: Thu Apr 27 05:54:41 2000
Topics:
libc/1708: [pthreads stop working on call to "system" if linked -static]
----------------------------------------------------------------------
Date: Tue, 25 Apr 2000 16:29:52 -0500
From: pelliott@nowdocs.com
To: bugs@gnu.org
Subject: libc/1708: [pthreads stop working on call to "system" if linked -static]
Message-Id: <200004252129.QAA01232@vortex.nowdocs.com>
>Number: 1708
>Category: libc
>Synopsis: pthreads stop working children defunct on call to "system" if linked -static
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: libc-gnats
>State: open
>Class: doc-bug
>Submitter-Id: unknown
>Arrival-Date: Tue Apr 25 17:40:06 EDT 2000
>Last-Modified:
>Originator:
>Organization:
NowDocs.com
>Release: libc-2.1.2
>Environment:
pc, linux, linux, glibc
Host type: i386-redhat-linux-gnu
System: Linux vortex.nowdocs.com 2.2.14 #5 SMP Wed Mar 8 14:28:07 CST 2000 i686 unknown
Architecture: i686
Addons: crypt glibc-compat linuxthreads
Build CFLAGS: -O3 -Wall -Winline -Wstrict-prototypes -Wwrite-strings -g
Build CC: egcs
Compiler version: egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
Kernel headers: 2.2.14
Symbol versioning: yes
Build static: yes
Build shared: yes
Build pic-default: no
Build profile: yes
Build omitfp: no
Build bounded: no
Build static-nss: no
Stdio: libio
>Description:
/* if linked -static program calls "system" manager thread exits, parent thread stops
* all children programs become defunct.
*/
>How-To-Repeat:
/* link the following code -static, then run. */
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
void putmsg(const char* fmt, ...) {
char buf[256], *end;
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
write(1, buf, strlen(buf));
}
void* threadfun(void* arg) {
const char* msg = (const char*) arg;
for(;;) {
putmsg("pid=%d, tid=%d, name=%s, ppid=%d\n",
getpid(), pthread_self(), msg, getppid() );
sleep(1);
}
}
void spawn(const char* name) {
pthread_t tid;
int e = pthread_create(&tid, NULL, threadfun, (void*)name);
if (e != 0) {
putmsg("pthread_create(%s) = %d\n", name, e);
}
}
int main() {
printf("main pid=%d\n",getpid() );
spawn("one");
spawn("two");
spawn("three");
sleep(5);
putmsg("calling system\n");
system("echo \"Your momma!\"");
pause();
sleep(60);
return 0;
}
>Fix:
workaround:
/* grab the following code from glibc-2.1/sysdeps/posix
* rename __libc_system to my_libc_system
* change __set_errno to errno =
* so that it will compile
* call my_libc_system instead of "system"
*/
/* Copyright (C) 1991, 92, 94, 95, 96, 97 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/types.h>
#include <errno.h>
#ifndef HAVE_GNU_LD
#define __environ environ
#endif
#define SHELL_PATH "/bin/sh" /* Path of the shell. */
#define SHELL_NAME "sh" /* Name to give it. */
/* Execute LINE as a shell command, returning its status. */
int
my_libc_system (const char *line)
{
int status, save;
pid_t pid;
struct sigaction sa, intr, quit;
#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD
sigset_t block, omask;
#endif
if (line == NULL)
/* This signals that we have a command processor available. */
return 1;
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
__sigemptyset (&sa.sa_mask);
if (__sigaction (SIGINT, &sa, &intr) < 0)
return -1;
if (__sigaction (SIGQUIT, &sa, &quit) < 0)
{
save = errno;
(void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
errno = save;
return -1;
}
#ifndef WAITPID_CANNOT_BLOCK_SIGCHLD
/* SCO 3.2v4 has a bug where `waitpid' will never return if SIGCHLD is
blocked. This makes it impossible for `system' to be implemented in
compliance with POSIX.2-1992. They have acknowledged that this is a bug
but I have not seen nor heard of any forthcoming fix. */
__sigemptyset (&block);
__sigaddset (&block, SIGCHLD);
save = errno;
if (__sigprocmask (SIG_BLOCK, &block, &omask) < 0)
{
if (errno == ENOSYS)
errno = save;
else
{
save = errno;
(void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
(void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
errno = save;
return -1;
}
}
#define UNBLOCK __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL)
#else
#define UNBLOCK 0
#endif
pid = __vfork ();
if (pid == (pid_t) 0)
{
/* Child side. */
const char *new_argv[4];
new_argv[0] = SHELL_NAME;
new_argv[1] = "-c";
new_argv[2] = line;
new_argv[3] = NULL;
/* Restore the signals. */
(void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL);
(void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL);
(void) UNBLOCK;
/* Exec the shell. */
(void) __execve (SHELL_PATH, (char *const *) new_argv, __environ);
_exit (127);
}
else if (pid < (pid_t) 0)
/* The fork failed. */
status = -1;
else
/* Parent side. */
#ifdef NO_WAITPID
{
pid_t child;
do
{
child = __wait (&status);
if (child <= -1)
{
status = -1;
break;
}
} while (child != pid);
}
#else
if (__waitpid (pid, &status, 0) != pid)
status = -1;
#endif
save = errno;
if ((__sigaction (SIGINT, &intr, (struct sigaction *) NULL) |
__sigaction (SIGQUIT, &quit, (struct sigaction *) NULL) |
UNBLOCK) != 0)
{
if (errno == ENOSYS)
errno = save;
else
return -1;
}
return status;
}
>Audit-Trail:
>Unformatted:
------------------------------
End of forwardHdDFqT Digest
***************************