mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-28 00:21:52 +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:
10
ChangeLog
10
ChangeLog
@ -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.
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -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.
|
||||||
|
115
libio/iopopen.c
115
libio/iopopen.c
@ -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)
|
|
||||||
return NULL;
|
#ifdef O_CLOEXEC
|
||||||
if (mode[0] == 'r' && mode[1] == '\0')
|
# 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;
|
||||||
|
}
|
||||||
|
#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
49
libio/tst-popen1.c
Normal 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"
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user