Пример #1
0
static bool
SpawnIOChild(char* const* aArgs, PRProcess** aPID,
             PRFileDesc** aFromChildFD, PRFileDesc** aToChildFD)
{
    PRFileDesc* toChildPipeRead;
    PRFileDesc* toChildPipeWrite;
    if (PR_CreatePipe(&toChildPipeRead, &toChildPipeWrite) != PR_SUCCESS)
        return false;
    PR_SetFDInheritable(toChildPipeRead, true);
    PR_SetFDInheritable(toChildPipeWrite, false);

    PRFileDesc* fromChildPipeRead;
    PRFileDesc* fromChildPipeWrite;
    if (PR_CreatePipe(&fromChildPipeRead, &fromChildPipeWrite) != PR_SUCCESS) {
        PR_Close(toChildPipeRead);
        PR_Close(toChildPipeWrite);
        return false;
    }
    PR_SetFDInheritable(fromChildPipeRead, false);
    PR_SetFDInheritable(fromChildPipeWrite, true);

    PRProcessAttr* attr = PR_NewProcessAttr();
    if (!attr) {
        PR_Close(fromChildPipeRead);
        PR_Close(fromChildPipeWrite);
        PR_Close(toChildPipeRead);
        PR_Close(toChildPipeWrite);
        return false;
    }

    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, toChildPipeRead);
    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, fromChildPipeWrite);   

    PRProcess* process = PR_CreateProcess(aArgs[0], aArgs, nullptr, attr);
    PR_DestroyProcessAttr(attr);
    PR_Close(fromChildPipeWrite);
    PR_Close(toChildPipeRead);
    if (!process) {
        LOG(("ntlm_auth exec failure [%d]", PR_GetError()));
        PR_Close(fromChildPipeRead);
        PR_Close(toChildPipeWrite);
        return false;        
    }

    *aPID = process;
    *aFromChildFD = fromChildPipeRead;
    *aToChildFD = toChildPipeWrite;
    return true;
}
Пример #2
0
PollableEvent::PollableEvent()
  : mWriteFD(nullptr)
  , mReadFD(nullptr)
  , mSignaled(false)
{
  MOZ_COUNT_CTOR(PollableEvent);
  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
  // create pair of prfiledesc that can be used as a poll()ble
  // signal. on windows use a localhost socket pair, and on
  // unix use a pipe.
#ifdef USEPIPE
  SOCKET_LOG(("PollableEvent() using pipe\n"));
  if (PR_CreatePipe(&mReadFD, &mWriteFD) == PR_SUCCESS) {
    // make the pipe non blocking. NSPR asserts at
    // trying to use SockOpt here
    PROsfd fd = PR_FileDesc2NativeHandle(mReadFD);
    int flags = fcntl(fd, F_GETFL, 0);
    (void)fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    fd = PR_FileDesc2NativeHandle(mWriteFD);
    flags = fcntl(fd, F_GETFL, 0);
    (void)fcntl(fd, F_SETFL, flags | O_NONBLOCK);
  } else {
    mReadFD = nullptr;
    mWriteFD = nullptr;
    SOCKET_LOG(("PollableEvent() pipe failed\n"));
  }
#else
  SOCKET_LOG(("PollableEvent() using socket pair\n"));
  PRFileDesc *fd[2];
  LazyInitSocket();
  if (NewTCPSocketPair(fd)) {
    mReadFD = fd[0];
    mWriteFD = fd[1];

    // compatibility with LSPs such as McAfee that assume a NSPR
    // layer for read ala the nspr Pollable Event - Bug 698882. This layer is a nop.
    PRFileDesc *topLayer =
      PR_CreateIOLayerStub(sPollableEventLayerIdentity,
                           sPollableEventLayerMethodsPtr);
    if (topLayer) {
      if (PR_PushIOLayer(fd[0], PR_TOP_IO_LAYER, topLayer) == PR_FAILURE) {
        topLayer->dtor(topLayer);
      } else {
        SOCKET_LOG(("PollableEvent() nspr layer ok\n"));
        mReadFD = topLayer;
      }
    }

  } else {
    SOCKET_LOG(("PollableEvent() socketpair failed\n"));
  }
#endif

  if (mReadFD && mWriteFD) {
    // prime the system to deal with races invovled in [dc]tor cycle
    SOCKET_LOG(("PollableEvent() ctor ok\n"));
    mSignaled = true;
    PR_Write(mWriteFD, "I", 1);
  }
}
Пример #3
0
static int
e_prpipe (PRFileDesc **fds)
{
#ifdef G_OS_WIN32
	if (PR_NewTCPSocketPair (fds) != PR_FAILURE)
		return 0;
#else
	if (PR_CreatePipe (&fds[0], &fds[1]) != PR_FAILURE)
		return 0;
#endif
	
	fds[0] = NULL;
	fds[1] = NULL;
	
	return -1;
}
Пример #4
0
/* Create a half duplex nspr pipe */
void
wrap_PR_CreatePipe(const char* msg, PRFileDesc **readPipe, PRFileDesc **writePipe) {
    /* We could use the TCPSocketPair to get a full duplex channel but
       there was a comment in prio.h (the nspr header) about whether
       TCPSocketPair is implemented on all platforms
       */
    PR_CreatePipe(readPipe, writePipe);
    if (tracing) {
	int readfd = PRFileDesc_To_FD(*readPipe);
	int writefd = PRFileDesc_To_FD(*readPipe);
	int readflags = fcntl(readfd, F_GETFL);
	int writeflags = fcntl(writefd, F_GETFL);
	trace("Created pipe %s read=%d write=%d\n", msg, readfd, writefd);
	trace(" read flags=%X write flags=%X\n", readflags, writeflags);
    }
}
void SocketTransportServiceTest::SetUp() {
  // Get the transport service as a dispatch target
  nsresult rv;
  target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
  ASSERT_TRUE(NS_SUCCEEDED(rv));

  // Get the transport service as a transport service
  stservice_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
  ASSERT_TRUE(NS_SUCCEEDED(rv));

  // Create a loopback pipe
  PRStatus status = PR_CreatePipe(&readpipe_, &writepipe_);
  ASSERT_EQ(status, PR_SUCCESS);

  // Register ourselves as a listener for the read side of the
  // socket. The registration has to happen on the STS thread,
  // hence this event stuff.
  rv = target_->Dispatch(new RegisterEvent(this), 0);
  ASSERT_TRUE(NS_SUCCEEDED(rv));
  ASSERT_TRUE_WAIT(registered_, 10000);

}
Пример #6
0
static nsresult vboxsvcSpawnDaemon(void)
{
    PRFileDesc *readable = nsnull, *writable = nsnull;
    PRProcessAttr *attr = nsnull;
    nsresult rv = NS_ERROR_FAILURE;
    PRFileDesc *devNull;
    // The ugly casts are necessary because the PR_CreateProcessDetached has
    // a const array of writable strings as a parameter. It won't write. */
    char * const args[] = { (char *)VBoxSVCPath, (char *)"--auto-shutdown", 0 };

    // Use a pipe to determine when the daemon process is in the position
    // to actually process requests. The daemon will write "READY" to the pipe.
    if (PR_CreatePipe(&readable, &writable) != PR_SUCCESS)
        goto end;
    PR_SetFDInheritable(writable, PR_TRUE);

    attr = PR_NewProcessAttr();
    if (!attr)
        goto end;

    if (PR_ProcessAttrSetInheritableFD(attr, writable, VBOXSVC_STARTUP_PIPE_NAME) != PR_SUCCESS)
        goto end;

    devNull = PR_Open("/dev/null", PR_RDWR, 0);
    if (!devNull)
        goto end;

    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, devNull);
    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, devNull);
    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardError, devNull);

    if (PR_CreateProcessDetached(VBoxSVCPath, args, nsnull, attr) != PR_SUCCESS)
        goto end;

    // Close /dev/null
    PR_Close(devNull);
    // Close the child end of the pipe to make it the only owner of the
    // file descriptor, so that unexpected closing can be detected.
    PR_Close(writable);
    writable = nsnull;

    char msg[10];
    RT_ZERO(msg);
    if (   PR_Read(readable, msg, sizeof(msg)-1) != 5
        || strcmp(msg, "READY"))
    {
        /* If several clients start VBoxSVC simultaneously only one can
         * succeed. So treat this as success as well. */
        rv = NS_OK;
        goto end;
    }

    rv = NS_OK;

end:
    if (readable)
        PR_Close(readable);
    if (writable)
        PR_Close(writable);
    if (attr)
        PR_DestroyProcessAttr(attr);
    return rv;
}
JD_METHOD_(JDBool) CNSAdapter_NSPR::JD_CreatePipe(void** readPipe, void** writePipe)
{
  return PR_CreatePipe((PRFileDesc**)readPipe, (PRFileDesc**)writePipe);
}
Пример #8
0
PollableEvent::PollableEvent()
  : mWriteFD(nullptr)
  , mReadFD(nullptr)
  , mSignaled(false)
{
  MOZ_COUNT_CTOR(PollableEvent);
  MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
  // create pair of prfiledesc that can be used as a poll()ble
  // signal. on windows use a localhost socket pair, and on
  // unix use a pipe.
#ifdef USEPIPE
  SOCKET_LOG(("PollableEvent() using pipe\n"));
  if (PR_CreatePipe(&mReadFD, &mWriteFD) == PR_SUCCESS) {
    // make the pipe non blocking. NSPR asserts at
    // trying to use SockOpt here
    PROsfd fd = PR_FileDesc2NativeHandle(mReadFD);
    int flags = fcntl(fd, F_GETFL, 0);
    (void)fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    fd = PR_FileDesc2NativeHandle(mWriteFD);
    flags = fcntl(fd, F_GETFL, 0);
    (void)fcntl(fd, F_SETFL, flags | O_NONBLOCK);
  } else {
    mReadFD = nullptr;
    mWriteFD = nullptr;
    SOCKET_LOG(("PollableEvent() pipe failed\n"));
  }
#else
  SOCKET_LOG(("PollableEvent() using socket pair\n"));
  PRFileDesc *fd[2];
  LazyInitSocket();

  // Try with a increased recv buffer first (bug 1248358).
  if (NewTCPSocketPair(fd, true)) {
    mReadFD = fd[0];
    mWriteFD = fd[1];
  // If the previous fails try without recv buffer increase (bug 1305436).
  } else if (NewTCPSocketPair(fd, false)) {
    mReadFD = fd[0];
    mWriteFD = fd[1];
  // If both fail, try the old version.
  } else if (PR_NewTCPSocketPair(fd) == PR_SUCCESS) {
    mReadFD = fd[0];
    mWriteFD = fd[1];

    PRSocketOptionData socket_opt;
    DebugOnly<PRStatus> status;
    socket_opt.option = PR_SockOpt_NoDelay;
    socket_opt.value.no_delay = true;
    PR_SetSocketOption(mWriteFD, &socket_opt);
    PR_SetSocketOption(mReadFD, &socket_opt);
    socket_opt.option = PR_SockOpt_Nonblocking;
    socket_opt.value.non_blocking = true;
    status = PR_SetSocketOption(mWriteFD, &socket_opt);
    MOZ_ASSERT(status == PR_SUCCESS);
    status = PR_SetSocketOption(mReadFD, &socket_opt);
    MOZ_ASSERT(status == PR_SUCCESS);
  }

  if (mReadFD && mWriteFD) {
    // compatibility with LSPs such as McAfee that assume a NSPR
    // layer for read ala the nspr Pollable Event - Bug 698882. This layer is a nop.
    PRFileDesc *topLayer =
      PR_CreateIOLayerStub(sPollableEventLayerIdentity,
                           sPollableEventLayerMethodsPtr);
    if (topLayer) {
      if (PR_PushIOLayer(fd[0], PR_TOP_IO_LAYER, topLayer) == PR_FAILURE) {
        topLayer->dtor(topLayer);
      } else {
        SOCKET_LOG(("PollableEvent() nspr layer ok\n"));
        mReadFD = topLayer;
      }
    }

  } else {
    SOCKET_LOG(("PollableEvent() socketpair failed\n"));
  }
#endif

  if (mReadFD && mWriteFD) {
    // prime the system to deal with races invovled in [dc]tor cycle
    SOCKET_LOG(("PollableEvent() ctor ok\n"));
    mSignaled = true;
    PR_Write(mWriteFD, "I", 1);
  }
}
Пример #9
0
nsresult
sbProcess::Run()
{
  PRStatus status;
  nsresult rv;

  // Set up to auto-kill process.
  sbAutoKillProcess autoSelf(this);

  // Operate under the process lock.
  {
    NS_ENSURE_TRUE(mProcessLock, NS_ERROR_NOT_INITIALIZED);
    nsAutoLock autoProcessLock(mProcessLock);

    // Get the number of arguments.
    PRUint32 argCount = mArgList.Length();
    NS_ENSURE_TRUE(argCount > 0, NS_ERROR_ILLEGAL_VALUE);

    // Convert the UTF-16 argument list to a UTF-8 argument list.
    nsTArray<nsCString> argListUTF8;
    for (PRUint32 i = 0; i < argCount; i++) {
      NS_ENSURE_TRUE(argListUTF8.AppendElement
                                   (NS_ConvertUTF16toUTF8(mArgList[i])),
                     NS_ERROR_OUT_OF_MEMORY);
    }

    // Allocate a null-terminated char* argument list and set it up for
    // auto-disposal.
    char** argList = reinterpret_cast<char**>
                       (NS_Alloc((argCount + 1) * sizeof(char*)));
    NS_ENSURE_TRUE(argList, NS_ERROR_OUT_OF_MEMORY);
    sbAutoNSTypePtr<char*> autoArgList(argList);

    // Convert the argument list to a null-terminated char* argument list.
    for (PRUint32 i = 0; i < argCount; i++) {
      argList[i] = const_cast<char*>(argListUTF8[i].get());
    }
    argList[argCount] = NULL;

    // Set up the process attributes and set them up for auto-disposal.
    PRProcessAttr* processAttr = PR_NewProcessAttr();
    NS_ENSURE_TRUE(processAttr, NS_ERROR_FAILURE);
    sbAutoPRProcessAttr autoProcessAttr(processAttr);

    // Set up process stdin.
    if (mPipeStdinString) {
      // Create a process stdin pipe and set it up for auto-disposal.
      PRFileDesc* stdinReadFD;
      PRFileDesc* stdinWriteFD;
      status = PR_CreatePipe(&stdinReadFD, &stdinWriteFD);
      NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
      sbAutoPRFileDesc autoStdinReadFD(stdinReadFD);
      sbAutoPRFileDesc autoStdinWriteFD(stdinWriteFD);

      // Set up stdin pipe file descriptors.
      status = PR_SetFDInheritable(stdinReadFD, PR_TRUE);
      NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
      status = PR_SetFDInheritable(stdinWriteFD, PR_FALSE);
      NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);

      // Fill pipe.
      nsCAutoString writeData = NS_ConvertUTF16toUTF8(mStdinString);
      PRInt32 bytesWritten;
      bytesWritten = PR_Write(stdinWriteFD,
                              writeData.get(),
                              writeData.Length());
      NS_ENSURE_TRUE(bytesWritten == writeData.Length(), NS_ERROR_FAILURE);

      // Redirect process stdin.
      PR_ProcessAttrSetStdioRedirect(processAttr,
                                     PR_StandardInput,
                                     stdinReadFD);

      // Keep stdin read descriptor open for the process to read.  Close the
      // stdin write descriptor so that the process gets EOF when all of the
      // data is read.
      mStdinReadFD = autoStdinReadFD.forget();
      PR_Close(autoStdinWriteFD.forget());
    }

    // Set up process stdout.
    if (mPipeStdoutString) {
      // Create a process stdout pipe and set it up for auto-disposal.
      PRFileDesc* stdoutReadFD;
      PRFileDesc* stdoutWriteFD;
      status = PR_CreatePipe(&stdoutReadFD, &stdoutWriteFD);
      NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
      sbAutoPRFileDesc autoStdoutReadFD(stdoutReadFD);
      sbAutoPRFileDesc autoStdoutWriteFD(stdoutWriteFD);

      // Set up stdout pipe file descriptors.
      status = PR_SetFDInheritable(stdoutReadFD, PR_FALSE);
      NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);
      status = PR_SetFDInheritable(stdoutWriteFD, PR_TRUE);
      NS_ENSURE_TRUE(status == PR_SUCCESS, NS_ERROR_FAILURE);

      // Redirect process stdout.
      PR_ProcessAttrSetStdioRedirect(processAttr,
                                     PR_StandardOutput,
                                     stdoutWriteFD);

      // Keep descriptors.
      mStdoutReadFD = autoStdoutReadFD.forget();
      mStdoutWriteFD = autoStdoutWriteFD.forget();
    }

    // Create and start running the process.
    mBaseProcess = PR_CreateProcess(argList[0], argList, NULL, processAttr);
    NS_ENSURE_TRUE(mBaseProcess, NS_ERROR_FAILURE);

    // Wait for process done on another thread.
    nsCOMPtr<nsIRunnable> runnable = NS_NEW_RUNNABLE_METHOD(sbProcess,
                                                            this,
                                                            WaitForDone);
    NS_ENSURE_TRUE(runnable, NS_ERROR_OUT_OF_MEMORY);
    rv = NS_NewThread(getter_AddRefs(mWaitForDoneThread), runnable);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Clear process auto-kill.
  autoSelf.forget();

  return NS_OK;
}