105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Create a pipe, with specific opening flags. 205436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 2009-2012 Free Software Foundation, Inc. 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 405436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software; you can redistribute it and/or modify 505436638acc7c010349a69c3395f1a57c642dc62Ying Wang it under the terms of the GNU General Public License as published by 605436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation; either version 3, or (at your option) 705436638acc7c010349a69c3395f1a57c642dc62Ying Wang any later version. 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 905436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is distributed in the hope that it will be useful, 1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang but WITHOUT ANY WARRANTY; without even the implied warranty of 1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang GNU General Public License for more details. 1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang You should have received a copy of the GNU General Public License along 1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang with this program; if not, see <http://www.gnu.org/licenses/>. */ 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <config.h> 1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Specification. */ 2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <unistd.h> 2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <errno.h> 2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <fcntl.h> 2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "binary-io.h" 2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "verify.h" 2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if GNULIB_defined_O_NONBLOCK 2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include "nonblocking.h" 3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Native Windows API. */ 3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <io.h> 3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3905436638acc7c010349a69c3395f1a57c642dc62Ying Wangint 4005436638acc7c010349a69c3395f1a57c642dc62Ying Wangpipe2 (int fd[2], int flags) 4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Mingw _pipe() corrupts fd on failure; also, if we succeed at 4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang creating the pipe but later fail at changing fcntl, we want 4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang to leave fd unchanged: http://austingroupbugs.net/view.php?id=467 */ 4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang int tmp[2]; 4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang tmp[0] = fd[0]; 4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang tmp[1] = fd[1]; 4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if HAVE_PIPE2 5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# undef pipe2 5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Try the system call first, if it exists. (We may be running with a glibc 5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang that has the function but with an older kernel that lacks it.) */ 5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Cache the information whether the system call really exists. */ 5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang static int have_pipe2_really; /* 0 = unknown, 1 = yes, -1 = no */ 5605436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (have_pipe2_really >= 0) 5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang int result = pipe2 (fd, flags); 5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!(result < 0 && errno == ENOSYS)) 6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang have_pipe2_really = 1; 6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang return result; 6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang have_pipe2_really = -1; 6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Check the supported flags. */ 7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if ((flags & ~(O_CLOEXEC | O_NONBLOCK | O_BINARY | O_TEXT)) != 0) 7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang errno = EINVAL; 7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang return -1; 7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Native Windows API. */ 7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (_pipe (fd, 4096, flags & ~O_NONBLOCK) < 0) 8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang fd[0] = tmp[0]; 8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang fd[1] = tmp[1]; 8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang return -1; 8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 8505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* O_NONBLOCK handling. 8705436638acc7c010349a69c3395f1a57c642dc62Ying Wang On native Windows platforms, O_NONBLOCK is defined by gnulib. Use the 8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang functions defined by the gnulib module 'nonblocking'. */ 8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if GNULIB_defined_O_NONBLOCK 9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (flags & O_NONBLOCK) 9105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 9205436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (set_nonblocking_flag (fd[0], true) != 0 9305436638acc7c010349a69c3395f1a57c642dc62Ying Wang || set_nonblocking_flag (fd[1], true) != 0) 9405436638acc7c010349a69c3395f1a57c642dc62Ying Wang goto fail; 9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else 9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang verify (O_NONBLOCK == 0); 9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 10105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#else 10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Unix API. */ 10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (pipe (fd) < 0) 10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang return -1; 10905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 11005436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* POSIX <http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html> 11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang says that initially, the O_NONBLOCK and FD_CLOEXEC flags are cleared on 11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang both fd[0] and fd[1]. */ 11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* O_NONBLOCK handling. 11505436638acc7c010349a69c3395f1a57c642dc62Ying Wang On Unix platforms, O_NONBLOCK is defined by the system. Use fcntl(). */ 11605436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (flags & O_NONBLOCK) 11705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 11805436638acc7c010349a69c3395f1a57c642dc62Ying Wang int fcntl_flags; 11905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 12005436638acc7c010349a69c3395f1a57c642dc62Ying Wang if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0 12105436638acc7c010349a69c3395f1a57c642dc62Ying Wang || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) == -1 12205436638acc7c010349a69c3395f1a57c642dc62Ying Wang || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0 12305436638acc7c010349a69c3395f1a57c642dc62Ying Wang || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1) 12405436638acc7c010349a69c3395f1a57c642dc62Ying Wang goto fail; 12505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 12605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 12705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (flags & O_CLOEXEC) 12805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 12905436638acc7c010349a69c3395f1a57c642dc62Ying Wang int fcntl_flags; 13005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 13105436638acc7c010349a69c3395f1a57c642dc62Ying Wang if ((fcntl_flags = fcntl (fd[1], F_GETFD, 0)) < 0 13205436638acc7c010349a69c3395f1a57c642dc62Ying Wang || fcntl (fd[1], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1 13305436638acc7c010349a69c3395f1a57c642dc62Ying Wang || (fcntl_flags = fcntl (fd[0], F_GETFD, 0)) < 0 13405436638acc7c010349a69c3395f1a57c642dc62Ying Wang || fcntl (fd[0], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1) 13505436638acc7c010349a69c3395f1a57c642dc62Ying Wang goto fail; 13605436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 13705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 13805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if O_BINARY 13905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (flags & O_BINARY) 14005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 14105436638acc7c010349a69c3395f1a57c642dc62Ying Wang setmode (fd[1], O_BINARY); 14205436638acc7c010349a69c3395f1a57c642dc62Ying Wang setmode (fd[0], O_BINARY); 14305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 14405436638acc7c010349a69c3395f1a57c642dc62Ying Wang else if (flags & O_TEXT) 14505436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 14605436638acc7c010349a69c3395f1a57c642dc62Ying Wang setmode (fd[1], O_TEXT); 14705436638acc7c010349a69c3395f1a57c642dc62Ying Wang setmode (fd[0], O_TEXT); 14805436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 14905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif 15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang return 0; 15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if GNULIB_defined_O_NONBLOCK || \ 15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) 15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang fail: 15805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 15905436638acc7c010349a69c3395f1a57c642dc62Ying Wang int saved_errno = errno; 16005436638acc7c010349a69c3395f1a57c642dc62Ying Wang close (fd[0]); 16105436638acc7c010349a69c3395f1a57c642dc62Ying Wang close (fd[1]); 16205436638acc7c010349a69c3395f1a57c642dc62Ying Wang fd[0] = tmp[0]; 16305436638acc7c010349a69c3395f1a57c642dc62Ying Wang fd[1] = tmp[1]; 16405436638acc7c010349a69c3395f1a57c642dc62Ying Wang errno = saved_errno; 16505436638acc7c010349a69c3395f1a57c642dc62Ying Wang return -1; 16605436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 16705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 16805436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 169