1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

* sysdeps/unix/sysv/linux/syscalls.list: Add __pipe2 alias.

* io/pipe2.c: Likewise.
	* sysdeps/unix/sysv/linux/kernel-features.h: Define __ASSUME_PIPE2
	instead of __ASSUME_PACCEPT.
	* include/unistd.h: Declare __have_pipe2.
	* libio/iopopen.c: Implement "e" flag.
	* libio/Makefile (tests): Add tst-popen1.
	* libio/tst-popen1.c: New file.
This commit is contained in:
Ulrich Drepper
2008-07-27 18:26:13 +00:00
parent 11ed3eaed9
commit d6e0c2a67d
8 changed files with 165 additions and 27 deletions

View File

@ -1,5 +1,15 @@
2008-07-27 Ulrich Drepper <drepper@redhat.com> 2008-07-27 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/syscalls.list: Add __pipe2 alias.
* io/pipe2.c: Likewise.
* sysdeps/unix/sysv/linux/kernel-features.h: Define __ASSUME_PIPE2
instead of __ASSUME_PACCEPT.
* include/unistd.h: Declare __have_pipe2.
* libio/iopopen.c: Implement "e" flag.
* libio/Makefile (tests): Add tst-popen1.
* libio/tst-popen1.c: New file.
* sysdeps/unix/sysv/linux/bits/socket.h: Define PF_ISDN and AF_ISDN. * sysdeps/unix/sysv/linux/bits/socket.h: Define PF_ISDN and AF_ISDN.
* sysdeps/unix/sysv/linux/sparc/bits/socket.h: Likewise. * sysdeps/unix/sysv/linux/sparc/bits/socket.h: Likewise.

View File

@ -48,6 +48,7 @@ extern ssize_t __libc_write (int __fd, __const void *__buf, size_t __n);
libc_hidden_proto (__libc_write) libc_hidden_proto (__libc_write)
extern int __pipe (int __pipedes[2]); extern int __pipe (int __pipedes[2]);
libc_hidden_proto (__pipe) libc_hidden_proto (__pipe)
extern int __pipe2 (int __pipedes[2], int __flags);
extern unsigned int __sleep (unsigned int __seconds); extern unsigned int __sleep (unsigned int __seconds);
extern int __chown (__const char *__file, extern int __chown (__const char *__file,
__uid_t __owner, __gid_t __group); __uid_t __owner, __gid_t __group);
@ -165,4 +166,10 @@ extern int __libc_pause (void);
/* Not cancelable variant. */ /* Not cancelable variant. */
extern int __pause_nocancel (void) attribute_hidden; extern int __pause_nocancel (void) attribute_hidden;
extern int __have_sock_cloexec;
/* At lot of other functionality became available at the same time as
SOCK_CLOEXEC. Avoid defining separate variables for all of them
unless it is really necessary. */
#define __have_pipe2 __have_sock_cloexec
#endif #endif

View File

@ -25,7 +25,7 @@
PIPEDES[1] can be read from PIPEDES[0]. Apply FLAGS to the new PIPEDES[1] can be read from PIPEDES[0]. Apply FLAGS to the new
file descriptors. Returns 0 if successful, -1 if not. */ file descriptors. Returns 0 if successful, -1 if not. */
int int
pipe2 (pipedes, flags) __pipe2 (pipedes, flags)
int pipedes[2]; int pipedes[2];
int flags; int flags;
{ {
@ -38,6 +38,7 @@ pipe2 (pipedes, flags)
__set_errno (ENOSYS); __set_errno (ENOSYS);
return -1; return -1;
} }
weak_alias (__pipe2, pipe2)
stub_warning (pipe2) stub_warning (pipe2)
#include <stub-tag.h> #include <stub-tag.h>

View File

@ -1,4 +1,4 @@
# Copyright (C) 1995-2002,2003,2004,2006,2007 Free Software Foundation, Inc. # Copyright (C) 1995-2004,2006,2007,2008 Free Software Foundation, Inc.
# This file is part of the GNU C Library. # This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or # The GNU C Library is free software; you can redistribute it and/or
@ -58,7 +58,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
tst-memstream1 tst-memstream2 \ tst-memstream1 tst-memstream2 \
tst-wmemstream1 tst-wmemstream2 \ tst-wmemstream1 tst-wmemstream2 \
bug-memstream1 bug-wmemstream1 \ bug-memstream1 bug-wmemstream1 \
tst-setvbuf1 tst-setvbuf1 tst-popen1
test-srcs = test-freopen test-srcs = test-freopen
all: # Make this the default target; it will be defined in Rules. all: # Make this the default target; it will be defined in Rules.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1993, 1997-2002, 2003, 2004, 2007 /* Copyright (C) 1993, 1997-2002, 2003, 2004, 2007, 2008
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Written by Per Bothner <bothner@cygnus.com>. Written by Per Bothner <bothner@cygnus.com>.
@ -56,15 +56,6 @@ extern _IO_pid_t _IO_fork (void) __THROW;
#endif /* _IO_HAVE_SYS_WAIT */ #endif /* _IO_HAVE_SYS_WAIT */
#ifndef _IO_pipe
#ifdef _LIBC
#define _IO_pipe __pipe
#else
#define _IO_pipe pipe
#endif
extern int _IO_pipe (int des[2]) __THROW;
#endif
#ifndef _IO_dup2 #ifndef _IO_dup2
#ifdef _LIBC #ifdef _LIBC
#define _IO_dup2 __dup2 #define _IO_dup2 __dup2
@ -131,41 +122,99 @@ _IO_new_proc_open (fp, command, mode)
volatile int parent_end, child_end; volatile int parent_end, child_end;
int pipe_fds[2]; int pipe_fds[2];
_IO_pid_t child_pid; _IO_pid_t child_pid;
int do_read = 0;
int do_write = 0;
int do_cloexec = 0;
while (*mode != '\0')
switch (*mode++)
{
case 'r':
do_read = 1;
break;
case 'w':
do_write = 1;
break;
case 'e':
do_cloexec = 1;
break;
default:
errout:
__set_errno (EINVAL);
return NULL;
}
if ((do_read ^ do_write) == 0)
goto errout;
if (_IO_file_is_open (fp)) if (_IO_file_is_open (fp))
return NULL; return NULL;
if (_IO_pipe (pipe_fds) < 0)
#ifdef O_CLOEXEC
# ifndef __ASSUME_PIPE2
if (__have_pipe2 >= 0)
# endif
{
int r = __pipe2 (pipe_fds, O_CLOEXEC);
# ifndef __ASSUME_PIPE2
if (__have_pipe2 == 0)
__have_pipe2 = r != -1 || errno != ENOSYS ? 1 : -1;
if (__have_pipe2 > 0)
# endif
if (r < 0)
return NULL; return NULL;
if (mode[0] == 'r' && mode[1] == '\0') }
#endif
#ifndef __ASSUME_PIPE2
# ifdef O_CLOEXEC
if (__have_pipe2 < 0)
# endif
if (__pipe (pipe_fds) < 0)
return NULL;
#endif
if (do_read)
{ {
parent_end = pipe_fds[0]; parent_end = pipe_fds[0];
child_end = pipe_fds[1]; child_end = pipe_fds[1];
read_or_write = _IO_NO_WRITES; read_or_write = _IO_NO_WRITES;
} }
else if (mode[0] == 'w' && mode[1] == '\0') else
{ {
parent_end = pipe_fds[1]; parent_end = pipe_fds[1];
child_end = pipe_fds[0]; child_end = pipe_fds[0];
read_or_write = _IO_NO_READS; read_or_write = _IO_NO_READS;
} }
else
{
_IO_close (pipe_fds[0]);
_IO_close (pipe_fds[1]);
__set_errno (EINVAL);
return NULL;
}
((_IO_proc_file *) fp)->pid = child_pid = _IO_fork (); ((_IO_proc_file *) fp)->pid = child_pid = _IO_fork ();
if (child_pid == 0) if (child_pid == 0)
{ {
int child_std_end = mode[0] == 'r' ? 1 : 0; int child_std_end = do_read ? 1 : 0;
struct _IO_proc_file *p; struct _IO_proc_file *p;
#ifndef __ASSUME_PIPE2
/* If we have pipe2 the descriptor is marked for close-on-exec. */
_IO_close (parent_end); _IO_close (parent_end);
#endif
if (child_end != child_std_end) if (child_end != child_std_end)
{ {
_IO_dup2 (child_end, child_std_end); _IO_dup2 (child_end, child_std_end);
#ifndef __ASSUME_PIPE2
_IO_close (child_end); _IO_close (child_end);
#endif
} }
#ifdef O_CLOEXEC
else
{
/* The descriptor is already the one we will use. But it must
not be marked close-on-exec. Undo the effects. */
# ifndef __ASSUME_PIPE2
if (__have_pipe2 > 0)
# endif
__fcntl (child_end, F_SETFD, 0);
}
#endif
/* POSIX.2: "popen() shall ensure that any streams from previous /* POSIX.2: "popen() shall ensure that any streams from previous
popen() calls that remain open in the parent process are closed popen() calls that remain open in the parent process are closed
in the new child process." */ in the new child process." */
@ -189,6 +238,28 @@ _IO_new_proc_open (fp, command, mode)
_IO_close (parent_end); _IO_close (parent_end);
return NULL; return NULL;
} }
if (do_cloexec)
{
#ifndef __ASSUME_PIPE2
# ifdef O_CLOEXEC
if (__have_pipe2 < 0)
# endif
__fcntl (parent_end, F_SETFD, FD_CLOEXEC);
#endif
}
else
{
#ifdef O_CLOEXEC
/* Undo the effects of the pipe2 call which set the
close-on-exec flag. */
# ifndef __ASSUME_PIPE2
if (__have_pipe2 > 0)
# endif
__fcntl (parent_end, F_SETFD, 0);
#endif
}
_IO_fileno (fp) = parent_end; _IO_fileno (fp) = parent_end;
/* Link into proc_file_chain. */ /* Link into proc_file_chain. */

49
libio/tst-popen1.c Normal file
View File

@ -0,0 +1,49 @@
#include <fcntl.h>
#include <stdio.h>
static int
do_test (void)
{
int res = 0;
FILE *fp = popen ("echo hello", "r");
if (fp == NULL)
{
puts ("first popen failed");
res = 1;
}
else
{
int fd = fileno (fp);
if (fcntl (fd, F_GETFD) == FD_CLOEXEC)
{
puts ("first popen(\"r\") set FD_CLOEXEC");
res = 1;
}
fclose (fp);
}
fp = popen ("echo hello", "re");
if (fp == NULL)
{
puts ("second popen failed");
res = 1;
}
else
{
int fd = fileno (fp);
if (fcntl (fd, F_GETFD) != FD_CLOEXEC)
{
puts ("second popen(\"r\") did not set FD_CLOEXEC");
res = 1;
}
fclose (fp);
}
return res;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -505,5 +505,5 @@
|| defined __ia64__ || defined __sparc__) || defined __ia64__ || defined __sparc__)
# define __ASSUME_SOCK_CLOEXEC 1 # define __ASSUME_SOCK_CLOEXEC 1
# define __ASSUME_IN_NONBLOCK 1 # define __ASSUME_IN_NONBLOCK 1
# define __ASSUME_PACCEPT 1 # define __ASSUME_PIPE2 1
#endif #endif

View File

@ -47,7 +47,7 @@ nfsservctl EXTRA nfsservctl i:ipp nfsservctl
pause - pause Ci: __libc_pause pause pause - pause Ci: __libc_pause pause
personality EXTRA personality i:i __personality personality personality EXTRA personality i:i __personality personality
pipe - pipe i:f __pipe pipe pipe - pipe i:f __pipe pipe
pipe2 - pipe2 i:fi pipe2 pipe2 - pipe2 i:fi __pipe2 pipe2
pivot_root EXTRA pivot_root i:ss pivot_root pivot_root EXTRA pivot_root i:ss pivot_root
prctl EXTRA prctl i:iiiii __prctl prctl prctl EXTRA prctl i:iiiii __prctl prctl
putpmsg - putpmsg i:ippii putpmsg putpmsg - putpmsg i:ippii putpmsg