Ejemplo n.º 1
0
	ShellWrapper()
	{
		int iReturn;
		iReturn = _pipe(iPipeIn_, 512, _O_TEXT | O_NOINHERIT);
		assert(iReturn != -1);
		iReturn = _pipe(iPipeOut_, 512, _O_TEXT | O_NOINHERIT);
		assert(iReturn != -1);

		//save old handle
		int iStdin = _dup(_fileno(stdin));
		int iStdout = _dup(_fileno(stdout));
		int iStderr = _dup(_fileno(stderr));

		iReturn = _dup2(iPipeOut_[0], _fileno(stdin));
		assert(iReturn == 0);
		iReturn = _dup2(iPipeIn_[1], _fileno(stdout));
		assert(iReturn == 0);
		iReturn = _dup2(iPipeIn_[1], _fileno(stderr));
		assert(iReturn == 0);

		char *arg[] = {"cmd.exe", "/Q", "/A", NULL};
		iSubProcess_ = spawnvp(P_NOWAIT, arg[0], arg);

		//restore old handle
		iReturn = _dup2(iStdin, _fileno(stdin));
		iReturn = _dup2(iStdout, _fileno(stdout));
		iReturn = _dup2(iStderr, _fileno(stderr));
	}
Ejemplo n.º 2
0
/* This function does file handle black magic.  Here, we create pipes,
   duplicate the ones we're going to pass on to the child process, and
   set the current process's stdin and stdout to be those pipes.  (###
   I'm not sure duplicating them is necessary, but it doesn't hurt...)

   inpipes, outpipes, and old_handles are 2 element arrays.  */
static void pipe_setup (STARTUPINFO *siStartInfo, int inpipes[], 
			int outpipes[], HANDLE old_handles[])
{
  const int pipe_size = 2000;
  HANDLE new_stdin, new_stdout;
  HANDLE parent = GetCurrentProcess();

  /* Create new file handles--in binary mode.
     _pipe sticks the read then the write handle in {in,out}pipes, and
     returns 0 on success and -1 on failure */
  if (_pipe(inpipes, pipe_size, O_BINARY) != 0
      || _pipe(outpipes, pipe_size, O_BINARY) != 0

      /* Duplicate the stdin and stdout handles.  False on failure. */
      || !DuplicateHandle(parent, /* source process */
			  /* next, handle to dup */
			  (HANDLE) _get_osfhandle(inpipes[0]),
			  parent,  /* Proc to give new handles to */
			  &new_stdin, /* Where new handle is stored */
			  0,  /* Parameter ignored */
			  TRUE, /* Make new handle inheritable */
			  DUPLICATE_SAME_ACCESS)
      || !DuplicateHandle(parent,  /* source process */
			  /* next, handle to dup */
			  (HANDLE)_get_osfhandle(outpipes[1]),
			  parent,   /* Proc to give new handles to */
			  &new_stdout,  /* Where new handle is stored */
			  0,  /* Parameter ignored */
			  TRUE, /* Make new handle inheritable */
			  DUPLICATE_SAME_ACCESS)) {
    fprintf(stderr, "Failed while doing pipe stuff for fd_exec");
    exit(1);
  }

  /* Save the old stdin and stdout handles to some place we can remember */
  old_handles[0] = GetStdHandle(STD_INPUT_HANDLE);
  old_handles[1] = GetStdHandle(STD_OUTPUT_HANDLE);

  /* Set stdin and stdout to the new handles */
  if (!SetStdHandle(STD_INPUT_HANDLE, new_stdin)
      || !SetStdHandle(STD_OUTPUT_HANDLE, new_stdout)) {
    fprintf(stderr, "Failed while doing pipe stuff for fd_exec");
    exit(1);
  }

  /* Now tell the StartInfo to use the handles we just created.  By
     default, child processes don't inherit the stdin and stdout of
     their parents. */
  siStartInfo->dwFlags = STARTF_USESTDHANDLES;
  siStartInfo->hStdInput = new_stdin;
  siStartInfo->hStdOutput = new_stdout;

  /* nothing funny with stderr, but we still have to initialize 
     the field anyway */
  siStartInfo->hStdError = GetStdHandle(STD_ERROR_HANDLE);
}
Ejemplo n.º 3
0
int start_child(char *cmd, FILE **readpipe, FILE **writepipe)
{

   /* FIXME: Doesn't seem to work for Windows */
   
#if !defined(_MSC_VER) && !defined (__MNO_CYGWIN)

   int childpid, pipe1[2], pipe2[2];

#if !defined(_MSC_VER) && !defined (__MNO_CYGWIN)
   if ((pipe(pipe1) < 0) || (pipe(pipe2) < 0)){
      perror("pipe");
      exit(-1);
   }
#else
   if ((_pipe(pipe1,256,O_BINARY) < 0) || (_pipe(pipe2,256,O_BINARY) < 0)){
      perror("pipe");
      exit(-1);
   }
#endif

   if ((childpid = vfork()) < 0){
      perror("fork");
      exit(-1);
   }else if (childpid > 0){    /* parent */
      close(pipe1[0]);
      close(pipe2[1]);
      /* write to child is pipe1[1], read from child is pipe2[0] */
      *readpipe = fdopen(pipe2[0], "r");
      /* this sets the pipe to be a Non-Blocking IO one, so fgets won't wait
       * until it receives a line. */
      fcntl(pipe2[0], F_SETFL, O_NONBLOCK);
      *writepipe = fdopen(pipe1[1], "w");
      setlinebuf(*writepipe);
      return(childpid);
   }else{      /* child */
      close(pipe1[1]);
      close(pipe2[0]);
      /* read from parent is pipe1[0], write to parent is pipe2[1] */
      dup2(pipe1[0], 0);
      dup2(pipe2[1], 1);
      close(pipe1[0]);
      close(pipe2[1]);
      if (execlp(cmd, cmd, NULL) < 0)
	 perror("execlp");

      /* never returns */
   }

#endif

   return(0);
}
Ejemplo n.º 4
0
int
ShCreatePipe (
    int Descriptors[2]
    )

/*++

Routine Description:

    This routine creates an anonymous pipe.

Arguments:

    Descriptors - Supplies the array where the pipe's read and write ends will
        be returned.

Return Value:

    1 on success.

    0 on failure.

--*/

{

    int Result;

    Result = _pipe(Descriptors, SHELL_NT_PIPE_SIZE, _O_BINARY);
    if (Result == 0) {
        return 1;
    }

    return 0;
}
Ejemplo n.º 5
0
static void
create_pipe (estream_t *r_in, estream_t *r_out)
{
  gpg_error_t err;
  int filedes[2];

#ifdef _WIN32
  if (_pipe (filedes, 512, 0) == -1)
#else
  if (pipe (filedes) == -1)
#endif
    {
      err = gpg_error_from_syserror ();
      die ("error creating a pipe: %s\n", gpg_strerror (err));
    }

  show ("created pipe [%d, %d]\n", filedes[0], filedes[1]);

  *r_in = es_fdopen (filedes[0], "r");
  if (!*r_in)
    {
      err = gpg_error_from_syserror ();
      die ("error creating a stream for a pipe: %s\n", gpg_strerror (err));
    }

  *r_out = es_fdopen (filedes[1], "w");
  if (!*r_out)
    {
      err = gpg_error_from_syserror ();
      die ("error creating a stream for a pipe: %s\n", gpg_strerror (err));
    }
}
Ejemplo n.º 6
0
void create_pipe()
{
    if( _pipe( (int *)&handles, 2048, _O_BINARY ) == -1 ) {
        perror( "create_pipe" );
        exit( EXIT_FAILURE );
    }
}
Ejemplo n.º 7
0
OcaOctaveController::OcaOctaveController()
:
  m_state( e_StateStopped ),
  m_lastError( 0 ),
  m_historyFileName( ".octaudio_history" ),
  m_historyBackupFileName( ".octaudio_history_old" ),
  m_host( NULL )
{
  int fds[2] = { -1, -1 };
#ifndef Q_OS_WIN32
  pipe( fds );
  dup2( fds[1], fileno(stdout) );
  setvbuf( stdout, NULL, _IOLBF, 0 );
  close( fds[1] );
  m_pipeFd = fds[0];
  int result = fcntl( m_pipeFd,  F_SETFL, O_NONBLOCK );
  Q_ASSERT( 0 == result );
  (void) result;
  QSocketNotifier* pNotifier = new QSocketNotifier( m_pipeFd,
                                                    QSocketNotifier::Read, this );
  connect( pNotifier, SIGNAL(activated(int)), SLOT(readStdout()) );
#else
  _pipe( fds, 4096, O_BINARY );
  _dup2( fds[1], fileno(stdout) );
  setvbuf( stdout, NULL, _IOLBF, 0 );
  close( fds[1] );
  m_pipeFd = fds[0];

  m_stdoutThread = new OcaStdoutThread( this );
  m_stdoutThread->start();
#endif
}
Ejemplo n.º 8
0
CGlobal::CGlobal()
{
    debugger_.reset(new Debugger());

    // redirect 'stdout' to the pipe

    char path[MAX_PATH];
    ::GetTempPath(MAX_PATH, path);
    char temp[MAX_PATH];
    ::GetTempFileName(path, "lu-", ::GetTickCount(), temp);

    // open stdout first, or else dup2 won't work
    if (freopen(temp, "w", stdout) == 0)
        throw std::exception("error redirecting stdout to temp file");

    if (_pipe(stdout_fds_, 0, _O_BINARY) != 0 || _dup2(stdout_fds_[1], _fileno(stdout)) != 0)
        throw std::exception("error redirecting stdout to the pipe");

    // no buffering for stdout, to make output window refresh instant
    setvbuf(stdout, NULL, _IONBF, 0);

    //TODO: delete temp
    ::DeleteFile(temp);

    output_position_ = 0;
    output_.reserve(200);

    thread_ = ::AfxBeginThread(ReadStdoutText, this, 0, 0, CREATE_SUSPENDED);
    if (thread_ == 0)
        throw std::exception("cannot create worker thread");
    thread_->m_bAutoDelete = false;
    thread_->ResumeThread();
}
Ejemplo n.º 9
0
int cloexec_pipe(int fds[2])
{
#ifdef __linux__
    return pipe2(fds, O_CLOEXEC);
#else
    int ret = -1;
#ifndef _MSC_VER
    pthread_mutex_lock(&cloexec_mutex);
	if (pipe(fds))
#else
	uv_mutex_lock(&cloexec_mutex);
	if (_pipe(fds, 4096, O_BINARY) != 0)
#endif
        goto Exit;
    if (set_cloexec(fds[0]) != 0 || set_cloexec(fds[1]) != 0)
        goto Exit;
    ret = 0;

Exit:
#ifndef _MSC_VER
    pthread_mutex_unlock(&cloexec_mutex);
#else
	uv_mutex_unlock(&cloexec_mutex);
#endif
    return ret;
#endif
}
Ejemplo n.º 10
0
int
pipe_cloexec_nonblock(int fd[2])
{
#ifdef WIN32
    return _pipe(fd, 512, _O_BINARY);
#else
    int ret;

#ifdef HAVE_PIPE2
    ret = pipe2(fd, O_CLOEXEC|O_NONBLOCK);
    if (ret >= 0 || errno != ENOSYS)
        return ret;
#endif

    ret = pipe(fd);
    if (ret >= 0) {
        fd_set_cloexec(fd[0], true);
        fd_set_cloexec(fd[1], true);

        fd_set_nonblock(fd[0]);
        fd_set_nonblock(fd[1]);
    }

    return ret;
#endif
}
Ejemplo n.º 11
0
 StdoutThread::StdoutThread(QLuaConsole::Private *d)
   : d(d), 
     fout(0), 
     sync("\027SYNC\007"),
     tCount(0),
     tActive(false)
 {
   fds[0] = fds[1] = -1;
   if (_pipe(fds,1024,_O_BINARY|_O_NOINHERIT) < 0)
     qFatal("Cannot create stdout pipe");
 }
Ejemplo n.º 12
0
pid_t
background_and_capture(char cmd[], int user_sh, FILE **out, FILE **err)
{
	int out_fd, out_pipe[2];
	int err_fd, err_pipe[2];
	pid_t pid;

	if(_pipe(out_pipe, 512, O_NOINHERIT) != 0)
	{
		show_error_msg("File pipe error", "Error creating pipe");
		return (pid_t)-1;
	}

	if(_pipe(err_pipe, 512, O_NOINHERIT) != 0)
	{
		show_error_msg("File pipe error", "Error creating pipe");
		close(out_pipe[0]);
		close(out_pipe[1]);
		return (pid_t)-1;
	}

	out_fd = dup(_fileno(stdout));
	err_fd = dup(_fileno(stderr));

	pid = background_and_capture_internal(cmd, user_sh, out, err, out_pipe,
			err_pipe);

	_close(out_pipe[1]);
	_close(err_pipe[1]);

	_dup2(out_fd, _fileno(stdout));
	_dup2(err_fd, _fileno(stderr));

	if(pid == (pid_t)-1)
	{
		_close(out_pipe[0]);
		_close(err_pipe[0]);
	}

	return pid;
}
Ejemplo n.º 13
0
static Int
open_pipe_stream (USES_REGS1)
{
  Term t1, t2;
  StreamDesc *st;
  int sno;
  int filedes[2];

  if (
#if   _MSC_VER || defined(__MINGW32__)
      // assume for now only text streams...
      _pipe(filedes, 1024, O_TEXT)
#else
      pipe(filedes)
#endif      
      != 0)
    {
      return (PlIOError (SYSTEM_ERROR_INTERNAL,TermNil, "error %s",  strerror(errno)) );
    }
  sno = GetFreeStreamD();
  if (sno < 0)
    return (PlIOError (RESOURCE_ERROR_MAX_STREAMS,TermNil, "new stream not available for open_pipe_stream/2"));
  t1 = Yap_MkStream (sno);
  st = &GLOBAL_Stream[sno];
  st->status = Input_Stream_f | Pipe_Stream_f;
  st->linepos = 0;
  st->charcount = 0;
  st->linecount = 1;
  st->stream_putc = PipePutc;
  st->stream_getc = PipeGetc;
  Yap_DefaultStreamOps( st );
  st->u.pipe.fd = filedes[0];
  st->file = fdopen( filedes[0], "r");
  UNLOCK(st->streamlock);
  sno = GetFreeStreamD();
  if (sno < 0)
    return (PlIOError (RESOURCE_ERROR_MAX_STREAMS,TermNil, "new stream not available for open_pipe_stream/2"));
  st = &GLOBAL_Stream[sno];
  st->status = Output_Stream_f | Pipe_Stream_f;
  st->linepos = 0;
  st->charcount = 0;
  st->linecount = 1;
  st->stream_putc = PipePutc;
  st->stream_getc = PipeGetc;
  Yap_DefaultStreamOps( st );
  st->u.pipe.fd = filedes[1];
  st->file = fdopen( filedes[1], "w");
  UNLOCK(st->streamlock);
  t2 = Yap_MkStream (sno);
  return
    Yap_unify (ARG1, t1) &&
    Yap_unify (ARG2, t2);
}
Ejemplo n.º 14
0
/* Returns the pipe handle, or 0 if error						 			  */
pipe_handle_t thread_pipe_create( unsigned long buffersize )
{
	pipe_handle_t ph = 0;
	tl_pipedata_t *pipedata;

	pipedata = malloc( sizeof(tl_pipedata_t) );
	memset( pipedata, 0, sizeof( tl_pipedata_t ) );
	pipedata->mutex = thread_mutex_create();

	/* Linux has a maximum pipe size of 4K - use write buffers in both environments */
	pipedata->buffer_limit = buffersize;
	pipedata->pipe_size = min( buffersize, 4096 );
	pipedata->limit_pipesize = 1;

#ifdef WIN32
	/* Windows pipes are blocking even when there is enough room for more data */
	/* Setting the pipe size to more than double what we need seems to solve the problem */
	/* At the moment I am suuming it is a bug in the Windows pipe implementation */
	if( _pipe( pipedata->phandles, 10240, O_BINARY | O_NOINHERIT ) ) {
//	if( _pipe( pipedata->phandles, pipedata->pipe_size, O_BINARY | O_NOINHERIT ) ) {
#else
	if( pipe( pipedata->phandles ) ) {
#endif
		/* Error */
		free( pipedata );
	} else {
		ph = (pipe_handle_t) pipedata;
	}

	return( ph );
}

/* Create a read only FIFO pipe, from a file								  */
/* Returns the pipe handle, or 0 if error						 			  */
pipe_handle_t thread_pipe_create_from_file( const char *filename )
{
	pipe_handle_t ph = 0;
	tl_pipedata_t *pipedata;

	pipedata = malloc( sizeof(tl_pipedata_t) );
	memset( pipedata, 0, sizeof(tl_pipedata_t) );
	pipedata->mutex = thread_mutex_create();

	pipedata->phandles[0] = open(filename, OPEN_READONLY_FLAGS );
	if( pipedata->phandles[0] == -1 ) {
		/* Error */
		free( pipedata );
	} else {
		ph = (pipe_handle_t) pipedata;
	}

	return( ph );
}
Ejemplo n.º 15
0
// --------------------------------------------------------------------------
void ctkFDHandler::setupPipe()
{
#ifdef Q_OS_WIN32
  int status = _pipe(this->Pipe, 65536, _O_TEXT);
#else
  int status = pipe(this->Pipe);
#endif
  if (status != 0)
    {
    qCritical().nospace() << "ctkFDHandler - Failed to create pipe !";
    return;
    }
}
Ejemplo n.º 16
0
static FILE* fopenZIPped(const char* filename, const char* mode)
{
    // check mode
    if (mode[0] == 'r')
    {
        // create the pipe
        int hPipe[2];
        if (_pipe(hPipe, 2048, ((mode[1] =='b') ? _O_BINARY : _O_TEXT) | _O_NOINHERIT) == -1)
        {
            fprintf(stderr, "could not create pipe\n");
            return NULL;
        }

        // duplicate stdin/stdout handle so we can restore them later
        int hStdOut = _dup(_fileno(stdout));

        // make the write end of pipe go to stdout
        if (_dup2(hPipe[WRITE_HANDLE], _fileno(stdout)) != 0)
        {
            fprintf(stderr, "could not set pipe output\n");
            return NULL;
        }

        // redirect read end of pipe to input file
        if (_dup2(hPipe[READ_HANDLE], _fileno(stdin)) != 0)
        {
            fprintf(stderr, "could not redirect input file\n");
            return NULL;
        }

        // close original write end of pipe
        close(hPipe[WRITE_HANDLE]);

        // Spawn process
        HANDLE hProcess = (HANDLE) spawnlp(P_NOWAIT, "unzip", "unzip", "-p", filename, NULL);

        // redirect stdout back into stdout
        if (_dup2(hStdOut, _fileno(stdout)) != 0)
        {
            fprintf(stderr, "could not reconstruct stdout\n");
            return NULL;
        }

        // return redirected stdin
        return stdin;
    }
    else
    {
        return NULL;
    }
}
Ejemplo n.º 17
0
OutputLogger::OutputLogger(FILE *file, const std::string &filename) :
	fd(-1), fileOld(NULL), filenameLog(filename), fileLog(NULL), 	
	fdPipeRead(-1), pThread(NULL)
{
	// Get the underlying file descriptor for the FILE stream
	fd = _fileno(file);

	// Probably on windows and there is no stdout/stderr in Subsystem Windows
	if (fd < 0) {
		fileLog = freopen(filenameLog.c_str(),"w",file);
#ifdef WIN32
		DWORD stdhandle = 0;
		if (fileLog == stdout) 
			stdhandle = STD_OUTPUT_HANDLE;
		else if (fileLog == stderr) 
			stdhandle = STD_ERROR_HANDLE;
		if (stdhandle) 
			SetStdHandle(stdhandle,(HANDLE)_get_osfhandle(_fileno(fileLog)));
#endif
		return;
	}

	// Create the pipe
	int fdsPipe[2];
	if (_pipe(fdsPipe,256,_O_BINARY) != 0) {
		return;
	}
	fdPipeRead = fdsPipe[0];
	int fdPipeWrite = fdsPipe[1];

	// Make sure that buffering is turned off on the incoming file
	std::setvbuf(file,NULL,_IONBF,0);

	// Duplicate the fd and create new filestream for it
	fileOld = _fdopen(_dup(fd),"w");
	// If the file was stderr, make sure the new file doesn't have buffering
	if (fileOld && file == stderr) std::setvbuf(fileOld,NULL,_IONBF,0);

	// Create the output log file
	fileLog =  std::fopen(filenameLog.c_str(),"w");

	// Duplicate pipe write file descriptor and replace original
	_dup2(fdPipeWrite,fd);
	
	// Close the fd for the write end of the pipe
	_close(fdPipeWrite);
	fdPipeWrite = -1;

	// Create the thread
	pThread = SDL_CreateThread( (int (SDLCALL*)(void*)) &OutputLogger::sThreadMain,this);
}
Ejemplo n.º 18
0
int
pipe (int fd[2])
{
  /* Mingw changes fd to {-1,-1} on failure, but this violates
     http://austingroupbugs.net/view.php?id=467 */
  int tmp[2];
  int result = _pipe (tmp, 4096, _O_BINARY);
  if (!result)
    {
      fd[0] = tmp[0];
      fd[1] = tmp[1];
    }
  return result;
}
Ejemplo n.º 19
0
FILE *
PostScript::ConvertToEPS (/*[in]*/ const char * lpszFileName)
{
  int handles[2];
  if (_pipe(handles, 4096, _O_BINARY) != 0)
  {
    FATAL_CRT_ERROR ("pipe", 0);
  }
  FILE * pFilePipeRead = fdopen(handles[0], "rb");
  if (pFilePipeRead == 0)
  {
    _close (handles[0]);
    _close (handles[1]);
    FATAL_CRT_ERROR ("fdopen", 0);
  }
  FILE * pFilePipeWrite = fdopen(handles[1], "wb");
  if (pFilePipeWrite == 0)
  {
    fclose (pFilePipeRead);
    _close (handles[1]);
    FATAL_CRT_ERROR ("fdopen", 0);
  }
  FILE * pFileIn;
  try
  {
    pFileIn = File::Open(lpszFileName, FileMode::Open, FileAccess::Read, false);
  }
  catch (const exception &)
  {
    fclose (pFilePipeRead);
    fclose (pFilePipeWrite);
    throw;
  }
  ThreadArg * pthreadarg = new ThreadArg (pFileIn, pFilePipeWrite, lpszFileName);
  pFileIn = 0;
  pFilePipeWrite = 0;
  auto_ptr<Thread> pConverterThread;
  try
  {
    pConverterThread.reset (Thread::Start(ConvertToEPSThread, pthreadarg));;
  }
  catch (const exception &)
  {
    fclose (pFilePipeRead);
    delete pthreadarg;
    throw;
  }
  return (pFilePipeRead);
}
Ejemplo n.º 20
0
void MakePipe(int out_pipefds[2]) {
#if THRILL_HAVE_PIPE2
    if (pipe2(out_pipefds, O_CLOEXEC) != 0)
        throw ErrnoException("Error creating pipe");
#elif defined(_MSC_VER)
    if (_pipe(out_pipefds, 256, O_BINARY) != 0)
        throw ErrnoException("Error creating pipe");
#else
    if (pipe(out_pipefds) != 0)
        throw ErrnoException("Error creating pipe");

    PortSetCloseOnExec(out_pipefds[0]);
    PortSetCloseOnExec(out_pipefds[1]);
#endif
}
Ejemplo n.º 21
0
VALUE
rbffi_thread_blocking_region(VALUE (*func)(void *), void *data1, void (*ubf)(void *), void *data2)
{
    struct BlockingThread* thr;
    int fd[2];
    VALUE exc;
    DWORD state;
    DWORD res;

    if (_pipe(fd, 1024, O_BINARY) == -1) {
        rb_raise(rb_eSystemCallError, "_pipe() failed");
        return Qnil;
    }

    thr = ALLOC_N(struct BlockingThread, 1);
    thr->rdfd = fd[0];
    thr->wrfd = fd[1];
    thr->fn = func;
    thr->data = data1;
    thr->ubf = ubf;
    thr->data2 = data2;
    thr->retval = Qnil;

    thr->tid = CreateThread(NULL, 0, rbffi_blocking_thread, thr, 0, NULL);
    if (!thr->tid) {
        close(fd[0]);
        close(fd[1]);
        xfree(thr);
        rb_raise(rb_eSystemCallError, "CreateThread() failed");
        return Qnil;
    }

    exc = rb_rescue2(wait_for_thread, (VALUE) thr, cleanup_blocking_thread, (VALUE) thr,
        rb_eException);

    /* The thread should be finished, already. */
    WaitForSingleObject(thr->tid, INFINITE);
    CloseHandle(thr->tid);
    close(fd[1]);
    close(fd[0]);
    xfree(thr);

    if (exc != Qnil) {
        rb_exc_raise(exc);
    }

    return thr->retval;
}
// --------------------------------------------------------------------------
void ctkFDHandler::init()
{
#ifdef Q_OS_WIN32
  int status = _pipe(this->Pipe, 65536, _O_TEXT);
#else
  int status = pipe(this->Pipe);
#endif
  if (status != 0)
    {
    qCritical().nospace() << "ctkFDHandler - Failed to create pipe !";
    return;
    }
  this->RedirectionFile.open(this->Pipe[0], QIODevice::ReadOnly);
  this->RedirectionStream = new QTextStream(&this->RedirectionFile);
  this->Initialized = true;
}
Ejemplo n.º 23
0
void
Pipe (/*[out]*/ int	filedes[2],
                /*[in]*/ size_t	pipeSize)
{
    int p;
#if defined(_MSC_VER)
    p = _pipe(filedes, static_cast<unsigned>(pipeSize), _O_BINARY);
#else
    UNUSED_ALWAYS (pipeSize);
    p = pipe(filedes);
#endif
    if (p != 0)
    {
        FATAL_CRT_ERROR ("pipe", 0);
    }
}
Ejemplo n.º 24
0
void FileKindTestCase::Pipe()
{
    int afd[2];
#ifdef __UNIX__
    pipe(afd);
#else
    _pipe(afd, 256, O_BINARY);
#endif

    wxFile file0(afd[0]);
    wxFile file1(afd[1]);
    TestFd(file0, false);
    file0.Detach();

    wxFFile ffile(fdopen(afd[0], "r"));
    TestFILE(ffile, false);
}
Ejemplo n.º 25
0
void FileKindTestCase::Pipe()
{
    int afd[2];
    int rc;
#ifdef __UNIX__
    rc = pipe(afd);
#else
    rc = _pipe(afd, 256, O_BINARY);
#endif
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to create pipe", 0, rc);

    wxFile file0(afd[0]);
    wxFile file1(afd[1]);
    TestFd(file0, false);
    file0.Detach();

    wxFFile ffile(fdopen(afd[0], "r"));
    TestFILE(ffile, false);
}
Ejemplo n.º 26
0
JError
JCreatePipe
	(
	int fd[2]
	)
{
	jclear_errno();
	if (_pipe(fd, 4096, _O_BINARY) == 0)
		{
		return JNoError();
		}

	const int err = jerrno();
	if (err == EMFILE || err == ENFILE)
		{
		return JTooManyDescriptorsOpen();
		}
	else
		{
		return JUnexpectedError(err);
		}
}
Ejemplo n.º 27
0
int tryExec(char *input, bool piping) 
{
  char ** head_tail;
  char ** args;
  int pid = -1, status;
  bool _hasPipe = FALSE;
  
  if(!piping)
    pid = fork();

  if(!piping && pid) {// parent process
    pid = waitpid(pid, &status, 0); // waits for child process to complete
    //printf("\033[1;33mChild [pid:%d] died with code %04x.\n\033[0m", pid, status);
  }
  else { // Child Process
    //printf("\033[1;36mcjp_sh [pid:%d] forks child [pid:%d].\n\033[0m", getppid(), getpid());
    //printf("[pid:%d] given input: %s\n", getpid(), input);

    args = breakup(input, " "); // Break up head_tail into individual arguments
    while(*args) {
      if(strcmp(*args, "|") == 0) {// HAS PIPE
	_hasPipe = TRUE;
	break;
      }
      *args++;
    }

    if(_hasPipe) {
      head_tail = split (input, '|');
      //printf("HAS PIPE:\n");
      //printf("-->Head: %s\n-->Tail: %s\n", head_tail[0], head_tail[1]);
      _pipe(head_tail);
    }
    else { 
      //printf("NO PIPE\nHead: %s\n", input); 
      _execAt(input);
    } 
  }
}
Ejemplo n.º 28
0
Archivo: myfork.c Proyecto: 0x7678/zzuf
/*
 * Create a pipe, a unidirectional channel for interprocess communication.
 */
static int mypipe(int pipefd[2])
{
#if defined HAVE_PIPE
    /* Unix, Linux, and nice systems: just use pipe() */
    return pipe(pipefd);

#elif defined HAVE__PIPE && !defined _WIN32
    /* Systems with _pipe() but not pipe(). They probably don't even
     * exist, apart from Win32 which we handle a different way.
     * The pipe is created with NOINHERIT otherwise both parts are
     * inherited. We then duplicate the part we want. */
    int ret = _pipe(pipefd, 512, _O_BINARY | O_NOINHERIT);
    int tmp = _dup(pipefd[1]);
    close(pipefd[1]);
    pipefd[1] = tmp;
    return ret;

#elif defined _WIN32
    /* Windows: create a unique name for the pipe and use the Win32 API
     * to create it. Inspired by
     * http://www.daniweb.com/software-development/cpp/threads/295780/using-named-pipes-with-asynchronous-io-redirection-to-winapi */
    static int pipe_cnt = 0;
    char pipe_name[BUFSIZ];
    _snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\Pipe\\zzuf.%08x.%d",
              GetCurrentProcessId(), pipe_cnt++);

    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    /* At this time, the HANDLE is inheritable and can both read/write */
    HANDLE rpipe = CreateNamedPipeA(pipe_name,
                           PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
                           PIPE_TYPE_BYTE | PIPE_WAIT,
                           1, BUFSIZ, BUFSIZ, 0, &sa);

    /* Create a new handle for write access only; it must be inheritable */
    HANDLE wpipe = CreateFileA(pipe_name, GENERIC_WRITE, 0, &sa,
                               OPEN_EXISTING,
                               FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                               NULL);

    if (rpipe == INVALID_HANDLE_VALUE || wpipe == INVALID_HANDLE_VALUE)
        return -1;

    /* Create a new handle for the listener; not inheritable */
    HANDLE new_rpipe;
    if (!DuplicateHandle(GetCurrentProcess(), rpipe,
                         GetCurrentProcess(), &new_rpipe,
                         0, FALSE, DUPLICATE_SAME_ACCESS))
        return -1;

    /* Finally we can safetly close the pipe handle */
    CloseHandle(rpipe);

    /* Now we convert handle to fd */
    pipefd[0] = _open_osfhandle((intptr_t)new_rpipe, 0x0);
    pipefd[1] = _open_osfhandle((intptr_t)wpipe, 0x0);

    return 0;
#endif
}
Ejemplo n.º 29
0
static unsigned int __stdcall
ipc_thread_1(void *in_params)
{
    int t1, t2, t3, retval = -1;
    int p2c[2] =
    {-1, -1};
    int c2p[2] =
    {-1, -1};
    HANDLE hProcess = NULL, thread = NULL;
    pid_t pid = -1;
    struct thread_params thread_params;
    int x, tmp_s, fd = -1;
    char *str;
#if HAVE_PUTENV
    char *env_str = NULL;
#endif
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    long F;
    int prfd_ipc = -1, pwfd_ipc = -1, crfd_ipc = -1, cwfd_ipc = -1;
    char *prog = NULL, *buf1 = NULL;
    struct sockaddr_in CS_ipc, PS_ipc;

    struct ipc_params *params = (struct ipc_params *) in_params;
    int type = params->type;
    int crfd = params->crfd;
    int cwfd = params->cwfd;
    char **args = params->args;
    struct sockaddr_in PS = params->PS;


    buf1 = xcalloc(1, 8192);
    strcpy(buf1, params->prog);
    prog = strtok(buf1, w_space);

    if ((str = strrchr(prog, '/')))
	prog = ++str;
    if ((str = strrchr(prog, '\\')))
	prog = ++str;

    prog = xstrdup(prog);

    if (type == IPC_TCP_SOCKET) {
	debug(54, 3) ("ipcCreate: calling accept on FD %d\n", crfd);
	if ((fd = accept(crfd, NULL, NULL)) < 0) {
	    debug(54, 0) ("ipcCreate: FD %d accept: %s\n", crfd, xstrerror());
	    goto cleanup;
	}
	debug(54, 3) ("ipcCreate: CHILD accepted new FD %d\n", fd);
	comm_close(crfd);
	snprintf(buf1, 8191, "%s CHILD socket", prog);
	fd_open(fd, FD_SOCKET, buf1);
	fd_table[fd].flags.ipc = 1;
	cwfd = crfd = fd;
    } else if (type == IPC_UDP_SOCKET) {
	if (comm_connect_addr(crfd, &PS) == COMM_ERROR)
	    goto cleanup;
    }
    x = send(cwfd, hello_string, strlen(hello_string) + 1, 0);

    if (x < 0) {
	debug(54, 0) ("sendto FD %d: %s\n", cwfd, xstrerror());
	debug(54, 0) ("ipcCreate: CHILD: hello write test failed\n");
	goto cleanup;
    }
#if HAVE_PUTENV
    env_str = xcalloc((tmp_s = strlen(Config.debugOptions) + 32), 1);
    snprintf(env_str, tmp_s, "SQUID_DEBUG=%s", Config.debugOptions);
    putenv(env_str);
#endif
    memset(buf1, '\0', sizeof(buf1));
    x = recv(crfd, buf1, 8191, 0);

    if (x < 0) {
	debug(54, 0) ("ipcCreate: CHILD: OK read test failed\n");
	debug(54, 0) ("--> read: %s\n", xstrerror());
	goto cleanup;
    } else if (strcmp(buf1, ok_string)) {
	debug(54, 0) ("ipcCreate: CHILD: OK read test failed\n");
	debug(54, 0) ("--> read returned %d\n", x);
	debug(54, 0) ("--> got '%s'\n", rfc1738_escape(hello_buf));
	goto cleanup;
    }
    /* assign file descriptors to child process */
    if (_pipe(p2c, 1024, _O_BINARY | _O_NOINHERIT) < 0) {
	debug(54, 0) ("ipcCreate: CHILD: pipe: %s\n", xstrerror());
	ipcSend(cwfd, err_string, strlen(err_string));
	goto cleanup;
    }
    if (_pipe(c2p, 1024, _O_BINARY | _O_NOINHERIT) < 0) {
	debug(54, 0) ("ipcCreate: CHILD: pipe: %s\n", xstrerror());
	ipcSend(cwfd, err_string, strlen(err_string));
	goto cleanup;
    }
    if (type == IPC_UDP_SOCKET) {
	snprintf(buf1, 8192, "%s(%ld) <-> ipc CHILD socket", prog, -1L);
	crfd_ipc = cwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1);

	if (crfd_ipc < 0) {
	    debug(54, 0) ("ipcCreate: CHILD: Failed to create child FD for %s.\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	snprintf(buf1, 8192, "%s(%ld) <-> ipc PARENT socket", prog, -1L);
	prfd_ipc = pwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1);
	if (pwfd_ipc < 0) {
	    debug(54, 0) ("ipcCreate: CHILD: Failed to create server FD for %s.\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	tmp_s = sizeof(PS_ipc);
	memset(&PS_ipc, '\0', tmp_s);
	if (getsockname(pwfd_ipc, (struct sockaddr *) &PS_ipc, &tmp_s) < 0) {
	    debug(54, 0) ("ipcCreate: getsockname: %s\n", xstrerror());
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n",
	    pwfd_ipc, inet_ntoa(PS_ipc.sin_addr), ntohs(PS_ipc.sin_port));
	tmp_s = sizeof(CS_ipc);
	memset(&CS_ipc, '\0', tmp_s);
	if (getsockname(crfd_ipc, (struct sockaddr *) &CS_ipc, &tmp_s) < 0) {
	    debug(54, 0) ("ipcCreate: getsockname: %s\n", xstrerror());
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n",
	    crfd_ipc, inet_ntoa(CS_ipc.sin_addr), ntohs(CS_ipc.sin_port));

	if (comm_connect_addr(pwfd_ipc, &CS_ipc) == COMM_ERROR) {
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	fd = crfd;

	if (comm_connect_addr(crfd_ipc, &PS_ipc) == COMM_ERROR) {
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
    }				/* IPC_UDP_SOCKET */
    t1 = dup(0);
    t2 = dup(1);
    t3 = dup(2);
    dup2(c2p[0], 0);
    dup2(p2c[1], 1);
    dup2(fileno(debug_log), 2);
    close(c2p[0]);
    close(p2c[1]);

    commUnsetNonBlocking(fd);

    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.hStdInput = (HANDLE) _get_osfhandle(0);
    si.hStdOutput = (HANDLE) _get_osfhandle(1);
    si.hStdError = (HANDLE) _get_osfhandle(2);
    si.dwFlags = STARTF_USESTDHANDLES;

    /* Make sure all other valid handles are not inerithable */
    for (x = 3; x < Squid_MaxFD; x++) {
	if ((F = _get_osfhandle(x)) == -1)
	    continue;
	SetHandleInformation((HANDLE) F, HANDLE_FLAG_INHERIT, 0);
    }

    *buf1 = '\0';
    strcpy(buf1 + 4096, params->prog);
    str = strtok(buf1 + 4096, w_space);

    do {
	strcat(buf1, str);
	strcat(buf1, " ");
    } while ((str = strtok(NULL, w_space)));

    x = 1;

    while (args[x]) {
	strcat(buf1, args[x++]);
	strcat(buf1, " ");
    }

    if (CreateProcess(buf1 + 4096, buf1, NULL, NULL, TRUE, CREATE_NO_WINDOW,
	    NULL, NULL, &si, &pi)) {
	pid = pi.dwProcessId;
	hProcess = pi.hProcess;
    } else {
	pid = -1;
	WIN32_maperror(GetLastError());
	x = errno;
    }

    dup2(t1, 0);
    dup2(t2, 1);
    dup2(t3, 2);
    close(t1);
    close(t2);
    close(t3);

    if (pid == -1) {
	errno = x;
	debug(54, 0) ("ipcCreate: CHILD: %s: %s\n", params->prog, xstrerror());
	ipcSend(cwfd, err_string, strlen(err_string));
	goto cleanup;
    }
    if (type == IPC_UDP_SOCKET) {
	WSAPROTOCOL_INFO wpi;

	memset(&wpi, 0, sizeof(wpi));
	if (SOCKET_ERROR == WSADuplicateSocket(crfd_ipc, pid, &wpi)) {
	    debug(54, 0) ("ipcCreate: CHILD: WSADuplicateSocket: %s\n",
		xstrerror());
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = write(c2p[1], (const char *) &wpi, sizeof(wpi));
	if (x < sizeof(wpi)) {
	    debug(54, 0) ("ipcCreate: CHILD: write FD %d: %s\n", c2p[1],
		xstrerror());
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = read(p2c[0], buf1, 8192);
	if (x < 0) {
	    debug(54, 0) ("ipcCreate: CHILD: read FD %d: %s\n", p2c[0],
		xstrerror());
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	} else if (strncmp(buf1, ok_string, strlen(ok_string))) {
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    debug(54, 0) ("--> read returned %d\n", x);
	    buf1[x] = '\0';
	    debug(54, 0) ("--> got '%s'\n", rfc1738_escape(buf1));
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = write(c2p[1], (const char *) &PS_ipc, sizeof(PS_ipc));
	if (x < sizeof(PS_ipc)) {
	    debug(54, 0) ("ipcCreate: CHILD: write FD %d: %s\n", c2p[1],
		xstrerror());
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = read(p2c[0], buf1, 8192);
	if (x < 0) {
	    debug(54, 0) ("ipcCreate: CHILD: read FD %d: %s\n", p2c[0],
		xstrerror());
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	} else if (strncmp(buf1, ok_string, strlen(ok_string))) {
	    debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n",
		prog);
	    debug(54, 0) ("--> read returned %d\n", x);
	    buf1[x] = '\0';
	    debug(54, 0) ("--> got '%s'\n", rfc1738_escape(buf1));
	    ipcSend(cwfd, err_string, strlen(err_string));
	    goto cleanup;
	}
	x = send(pwfd_ipc, ok_string, strlen(ok_string), 0);
	x = recv(prfd_ipc, buf1 + 200, 8191 - 200, 0);
	assert((size_t) x == strlen(ok_string)
	    && !strncmp(ok_string, buf1 + 200, strlen(ok_string)));
    }				/* IPC_UDP_SOCKET */
    snprintf(buf1, 8191, "%s(%ld) CHILD socket", prog, (long int) pid);
    fd_note(fd, buf1);

    if (prfd_ipc != -1) {
	snprintf(buf1, 8191, "%s(%ld) <-> ipc CHILD socket", prog, (long int) pid);
	fd_note(crfd_ipc, buf1);
	snprintf(buf1, 8191, "%s(%ld) <-> ipc PARENT socket", prog, (long int) pid);
	fd_note(prfd_ipc, buf1);
    }
    /* else {                       IPC_TCP_SOCKET */
    /*     commSetNoLinger(fd); */
    /*  } */
    thread_params.prog = prog;
    thread_params.send_fd = cwfd;
    thread_params.pid = pid;

    if ((thread_params.type = type) == IPC_TCP_SOCKET)
	thread_params.rfd = p2c[0];
    else
	thread_params.rfd = prfd_ipc;

    thread =
	(HANDLE) _beginthreadex(NULL, 0, ipc_thread_2, &thread_params, 0, NULL);

    if (!thread) {
	debug(54, 0) ("ipcCreate: CHILD: _beginthreadex: %s\n", xstrerror());
	ipcSend(cwfd, err_string, strlen(err_string));
	goto cleanup;
    }
    snprintf(buf1, 8191, "%ld\n", (long int) pid);

    if (-1 == ipcSend(cwfd, buf1, strlen(buf1)))
	goto cleanup;

    debug(54, 2) ("ipc(%s,%ld): started successfully\n", prog, (long int) pid);

    /* cycle */
    for (;;) {
	x = recv(crfd, buf1, 8192, 0);
	if (x <= 0) {
	    debug(54, 3) ("ipc(%s,%d): %d bytes received from parent. Exiting...\n",
		prog, pid, x);
	    break;
	}
	buf1[x] = '\0';
	if (type == IPC_UDP_SOCKET && !strcmp(buf1, shutdown_string)) {
	    debug(54, 3)
		("ipc(%s,%d): request for shutdown received from parent. Exiting...\n",
		prog, pid);
	    TerminateProcess(hProcess, 0);
	    break;
	}
	debug(54, 5) ("ipc(%s,%d): received from parent: %s\n", prog, pid,
	    rfc1738_escape_unescaped(buf1));
	if (type == IPC_TCP_SOCKET)
	    x = write(c2p[1], buf1, x);
	else
	    x = send(pwfd_ipc, buf1, x, 0);
	if (x <= 0) {
	    debug(54, 3) ("ipc(%s,%d): %d bytes written to %s. Exiting...\n",
		prog, pid, x, prog);
	    break;
	}
    }

    retval = 0;

  cleanup:
    if (c2p[1] != -1)
	close(c2p[1]);

    if (fd_table[crfd].flags.open)
	ipcCloseAllFD(-1, -1, crfd, cwfd);

    if (prfd_ipc != -1) {
	send(crfd_ipc, shutdown_string, strlen(shutdown_string), 0);
	shutdown(crfd_ipc, SD_BOTH);
	shutdown(prfd_ipc, SD_BOTH);
    }
    ipcCloseAllFD(prfd_ipc, pwfd_ipc, crfd_ipc, cwfd_ipc);

    if (hProcess && WAIT_OBJECT_0 !=
	WaitForSingleObject(hProcess, type == IPC_UDP_SOCKET ? 12000 : 5000)) {

	getCurrentTime();
	debug(54, 0) ("ipc(%s,%d): WARNING: %s didn't exit in %d seconds.\n",
	    prog, pid, prog, type == IPC_UDP_SOCKET ? 12 : 5);
    }
    if (thread && WAIT_OBJECT_0 != WaitForSingleObject(thread, 3000)) {
	getCurrentTime();
	debug(54, 0)
	    ("ipc(%s,%d): WARNING: ipc_thread_2 didn't exit in 3 seconds.\n",
	    prog, pid);
    }
    getCurrentTime();

    if (!retval)
	debug(54, 2) ("ipc(%s,%d): normal exit\n", prog, pid);

    if (buf1)
	xfree(buf1);

    if (prog)
	xfree(prog);

    if (env_str)
	xfree(env_str);

    if (thread)
	CloseHandle(thread);

    if (hProcess)
	CloseHandle(hProcess);

    if (p2c[0] != -1)
	close(p2c[0]);

    return retval;
}
Ejemplo n.º 30
0
int
pipe2 (int fd[2], int flags)
{
  /* Mingw _pipe() corrupts fd on failure; also, if we succeed at
     creating the pipe but later fail at changing fcntl, we want
     to leave fd unchanged: http://austingroupbugs.net/view.php?id=467  */
  int tmp[2];
  tmp[0] = fd[0];
  tmp[1] = fd[1];

#if HAVE_PIPE2
# undef pipe2
  /* Try the system call first, if it exists.  (We may be running with a glibc
     that has the function but with an older kernel that lacks it.)  */
  {
    /* Cache the information whether the system call really exists.  */
    static int have_pipe2_really; /* 0 = unknown, 1 = yes, -1 = no */
    if (have_pipe2_really >= 0)
      {
        int result = pipe2 (fd, flags);
        if (!(result < 0 && errno == ENOSYS))
          {
            have_pipe2_really = 1;
            return result;
          }
        have_pipe2_really = -1;
      }
  }
#endif

  /* Check the supported flags.  */
  if ((flags & ~(O_CLOEXEC | O_NONBLOCK | O_BINARY | O_TEXT)) != 0)
    {
      errno = EINVAL;
      return -1;
    }

#if defined _WIN32 && ! defined __CYGWIN__
/* Native Windows API.  */

  if (_pipe (fd, 4096, flags & ~O_NONBLOCK) < 0)
    {
      fd[0] = tmp[0];
      fd[1] = tmp[1];
      return -1;
    }

  /* O_NONBLOCK handling.
     On native Windows platforms, O_NONBLOCK is defined by gnulib.  Use the
     functions defined by the gnulib module 'nonblocking'.  */
# if GNULIB_defined_O_NONBLOCK
  if (flags & O_NONBLOCK)
    {
      if (set_nonblocking_flag (fd[0], true) != 0
          || set_nonblocking_flag (fd[1], true) != 0)
        goto fail;
    }
# else
  {
    verify (O_NONBLOCK == 0);
  }
# endif

  return 0;

#else
/* Unix API.  */

  if (pipe (fd) < 0)
    return -1;

  /* POSIX <http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html>
     says that initially, the O_NONBLOCK and FD_CLOEXEC flags are cleared on
     both fd[0] and fd[1].  */

  /* O_NONBLOCK handling.
     On Unix platforms, O_NONBLOCK is defined by the system.  Use fcntl().  */
  if (flags & O_NONBLOCK)
    {
      int fcntl_flags;

      if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0
          || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) == -1
          || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0
          || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1)
        goto fail;
    }

  if (flags & O_CLOEXEC)
    {
      int fcntl_flags;

      if ((fcntl_flags = fcntl (fd[1], F_GETFD, 0)) < 0
          || fcntl (fd[1], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1
          || (fcntl_flags = fcntl (fd[0], F_GETFD, 0)) < 0
          || fcntl (fd[0], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1)
        goto fail;
    }

# if O_BINARY
  if (flags & O_BINARY)
    {
      set_binary_mode (fd[1], O_BINARY);
      set_binary_mode (fd[0], O_BINARY);
    }
  else if (flags & O_TEXT)
    {
      set_binary_mode (fd[1], O_TEXT);
      set_binary_mode (fd[0], O_TEXT);
    }
# endif

  return 0;

#endif

#if GNULIB_defined_O_NONBLOCK || !(defined _WIN32 && ! defined __CYGWIN__)
 fail:
  {
    int saved_errno = errno;
    close (fd[0]);
    close (fd[1]);
    fd[0] = tmp[0];
    fd[1] = tmp[1];
    errno = saved_errno;
    return -1;
  }
#endif
}