proxygen
Subprocess.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2012-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _GNU_SOURCE
18 #define _GNU_SOURCE
19 #endif
20 
21 #include <folly/Subprocess.h>
22 
23 #if __linux__
24 #include <sys/prctl.h>
25 #endif
26 #include <fcntl.h>
27 
28 #include <algorithm>
29 #include <array>
30 #include <system_error>
31 
32 #include <boost/container/flat_set.hpp>
33 #include <boost/range/adaptors.hpp>
34 
35 #include <glog/logging.h>
36 
37 #include <folly/Conv.h>
38 #include <folly/Exception.h>
39 #include <folly/ScopeGuard.h>
40 #include <folly/String.h>
41 #include <folly/io/Cursor.h>
42 #include <folly/lang/Assume.h>
47 #include <folly/system/Shell.h>
48 
49 constexpr int kExecFailure = 127;
50 constexpr int kChildFailure = 126;
51 
52 namespace folly {
53 
55  if (!WIFEXITED(status) && !WIFSIGNALED(status)) {
56  throw std::runtime_error(
57  to<std::string>("Invalid ProcessReturnCode: ", status));
58  }
59  return ProcessReturnCode(status);
60 }
61 
63  : rawStatus_(p.rawStatus_) {
64  p.rawStatus_ = ProcessReturnCode::RV_NOT_STARTED;
65 }
66 
69  rawStatus_ = p.rawStatus_;
70  p.rawStatus_ = ProcessReturnCode::RV_NOT_STARTED;
71  return *this;
72 }
73 
75  if (rawStatus_ == RV_NOT_STARTED) {
76  return NOT_STARTED;
77  }
78  if (rawStatus_ == RV_RUNNING) {
79  return RUNNING;
80  }
81  if (WIFEXITED(rawStatus_)) {
82  return EXITED;
83  }
84  if (WIFSIGNALED(rawStatus_)) {
85  return KILLED;
86  }
88 }
89 
90 void ProcessReturnCode::enforce(State expected) const {
91  State s = state();
92  if (s != expected) {
93  throw std::logic_error(to<std::string>(
94  "Bad use of ProcessReturnCode; state is ", s, " expected ", expected));
95  }
96 }
97 
99  enforce(EXITED);
100  return WEXITSTATUS(rawStatus_);
101 }
102 
104  enforce(KILLED);
105  return WTERMSIG(rawStatus_);
106 }
107 
109  enforce(KILLED);
110  return WCOREDUMP(rawStatus_);
111 }
112 
114  switch (state()) {
115  case NOT_STARTED:
116  return "not started";
117  case RUNNING:
118  return "running";
119  case EXITED:
120  return to<std::string>("exited with status ", exitStatus());
121  case KILLED:
122  return to<std::string>(
123  "killed by signal ",
124  killSignal(),
125  (coreDumped() ? " (core dumped)" : ""));
126  }
128 }
129 
131  : SubprocessError(rc.str()), returnCode_(rc) {}
132 
134  char const* executable,
135  int errCode,
136  int errnoValue) {
137  auto prefix = errCode == kExecFailure ? "failed to execute "
138  : "error preparing to execute ";
139  return to<std::string>(prefix, executable, ": ", errnoStr(errnoValue));
140 }
141 
143  const char* executable,
144  int errCode,
145  int errnoValue)
146  : SubprocessError(
147  toSubprocessSpawnErrorMessage(executable, errCode, errnoValue)),
148  errnoValue_(errnoValue) {}
149 
150 namespace {
151 
152 // Copy pointers to the given strings in a format suitable for posix_spawn
153 std::unique_ptr<const char* []> cloneStrings(
154  const std::vector<std::string>& s) {
155  std::unique_ptr<const char*[]> d(new const char*[s.size() + 1]);
156  for (size_t i = 0; i < s.size(); i++) {
157  d[i] = s[i].c_str();
158  }
159  d[s.size()] = nullptr;
160  return d;
161 }
162 
163 // Check a wait() status, throw on non-successful
164 void checkStatus(ProcessReturnCode returnCode) {
165  if (returnCode.state() != ProcessReturnCode::EXITED ||
166  returnCode.exitStatus() != 0) {
167  throw CalledProcessError(returnCode);
168  }
169 }
170 
171 } // namespace
172 
174  if (action == Subprocess::PIPE) {
175  if (fd == 0) {
176  action = Subprocess::PIPE_IN;
177  } else if (fd == 1 || fd == 2) {
178  action = Subprocess::PIPE_OUT;
179  } else {
180  throw std::invalid_argument(
181  to<std::string>("Only fds 0, 1, 2 are valid for action=PIPE: ", fd));
182  }
183  }
184  fdActions_[fd] = action;
185  return *this;
186 }
187 
189 
191  const std::vector<std::string>& argv,
192  const Options& options,
193  const char* executable,
194  const std::vector<std::string>* env) {
195  if (argv.empty()) {
196  throw std::invalid_argument("argv must not be empty");
197  }
198  if (!executable) {
199  executable = argv[0].c_str();
200  }
201  spawn(cloneStrings(argv), executable, options, env);
202 }
203 
205  const std::string& cmd,
206  const Options& options,
207  const std::vector<std::string>* env) {
208  if (options.usePath_) {
209  throw std::invalid_argument("usePath() not allowed when running in shell");
210  }
211 
212  std::vector<std::string> argv = {"/bin/sh", "-c", cmd};
213  spawn(cloneStrings(argv), argv[0].c_str(), options, env);
214 }
215 
217  CHECK_NE(returnCode_.state(), ProcessReturnCode::RUNNING)
218  << "Subprocess destroyed without reaping child";
219 }
220 
221 namespace {
222 
223 struct ChildErrorInfo {
224  int errCode;
226 };
227 
228 [[noreturn]] void childError(int errFd, int errCode, int errnoValue) {
229  ChildErrorInfo info = {errCode, errnoValue};
230  // Write the error information over the pipe to our parent process.
231  // We can't really do anything else if this write call fails.
232  writeNoInt(errFd, &info, sizeof(info));
233  // exit
234  _exit(errCode);
235 }
236 
237 } // namespace
238 
240  for (auto& p : pipes_) {
241  int fd = p.pipe.fd();
242  int flags = ::fcntl(fd, F_GETFL);
243  checkUnixError(flags, "fcntl");
244  int r = ::fcntl(fd, F_SETFL, flags | O_NONBLOCK);
245  checkUnixError(r, "fcntl");
246  }
247 }
248 
250  std::unique_ptr<const char*[]> argv,
251  const char* executable,
252  const Options& optionsIn,
253  const std::vector<std::string>* env) {
254  if (optionsIn.usePath_ && env) {
255  throw std::invalid_argument(
256  "usePath() not allowed when overriding environment");
257  }
258 
259  // Make a copy, we'll mutate options
260  Options options(optionsIn);
261 
262  // On error, close all pipes_ (ignoring errors, but that seems fine here).
263  auto pipesGuard = makeGuard([this] { pipes_.clear(); });
264 
265  // Create a pipe to use to receive error information from the child,
266  // in case it fails before calling exec()
267  int errFds[2];
268 #if FOLLY_HAVE_PIPE2
269  checkUnixError(::pipe2(errFds, O_CLOEXEC), "pipe2");
270 #else
271  checkUnixError(::pipe(errFds), "pipe");
272 #endif
273  SCOPE_EXIT {
274  CHECK_ERR(::close(errFds[0]));
275  if (errFds[1] >= 0) {
276  CHECK_ERR(::close(errFds[1]));
277  }
278  };
279 
280 #if !FOLLY_HAVE_PIPE2
281  // Ask the child to close the read end of the error pipe.
282  checkUnixError(fcntl(errFds[0], F_SETFD, FD_CLOEXEC), "set FD_CLOEXEC");
283  // Set the close-on-exec flag on the write side of the pipe.
284  // This way the pipe will be closed automatically in the child if execve()
285  // succeeds. If the exec fails the child can write error information to the
286  // pipe.
287  checkUnixError(fcntl(errFds[1], F_SETFD, FD_CLOEXEC), "set FD_CLOEXEC");
288 #endif
289 
290  // Perform the actual work of setting up pipes then forking and
291  // executing the child.
292  spawnInternal(std::move(argv), executable, options, env, errFds[1]);
293 
294  // After spawnInternal() returns the child is alive. We have to be very
295  // careful about throwing after this point. We are inside the constructor,
296  // so if we throw the Subprocess object will have never existed, and the
297  // destructor will never be called.
298  //
299  // We should only throw if we got an error via the errFd, and we know the
300  // child has exited and can be immediately waited for. In all other cases,
301  // we have no way of cleaning up the child.
302 
303  // Close writable side of the errFd pipe in the parent process
304  CHECK_ERR(::close(errFds[1]));
305  errFds[1] = -1;
306 
307  // Read from the errFd pipe, to tell if the child ran into any errors before
308  // calling exec()
309  readChildErrorPipe(errFds[0], executable);
310 
311  // If we spawned a detached child, wait on the intermediate child process.
312  // It always exits immediately.
313  if (options.detach_) {
314  wait();
315  }
316 
317  // We have fully succeeded now, so release the guard on pipes_
318  pipesGuard.dismiss();
319 }
320 
321 // With -Wclobbered, gcc complains about vfork potentially cloberring the
322 // childDir variable, even though we only use it on the child side of the
323 // vfork.
324 
326 FOLLY_GCC_DISABLE_WARNING("-Wclobbered")
327 void Subprocess::spawnInternal(
328  std::unique_ptr<const char*[]> argv,
329  const char* executable,
330  Options& options,
331  const std::vector<std::string>* env,
332  int errFd) {
333  // Parent work, pre-fork: create pipes
334  std::vector<int> childFds;
335  // Close all of the childFds as we leave this scope
336  SCOPE_EXIT {
337  // These are only pipes, closing them shouldn't fail
338  for (int cfd : childFds) {
339  CHECK_ERR(::close(cfd));
340  }
341  };
342 
343  int r;
344  for (auto& p : options.fdActions_) {
345  if (p.second == PIPE_IN || p.second == PIPE_OUT) {
346  int fds[2];
347  // We're setting both ends of the pipe as close-on-exec. The child
348  // doesn't need to reset the flag on its end, as we always dup2() the fd,
349  // and dup2() fds don't share the close-on-exec flag.
350 #if FOLLY_HAVE_PIPE2
351  // If possible, set close-on-exec atomically. Otherwise, a concurrent
352  // Subprocess invocation can fork() between "pipe" and "fnctl",
353  // causing FDs to leak.
354  r = ::pipe2(fds, O_CLOEXEC);
355  checkUnixError(r, "pipe2");
356 #else
357  r = ::pipe(fds);
358  checkUnixError(r, "pipe");
359  r = fcntl(fds[0], F_SETFD, FD_CLOEXEC);
360  checkUnixError(r, "set FD_CLOEXEC");
361  r = fcntl(fds[1], F_SETFD, FD_CLOEXEC);
362  checkUnixError(r, "set FD_CLOEXEC");
363 #endif
364  pipes_.emplace_back();
365  Pipe& pipe = pipes_.back();
366  pipe.direction = p.second;
367  int cfd;
368  if (p.second == PIPE_IN) {
369  // Child gets reading end
370  pipe.pipe = folly::File(fds[1], /*ownsFd=*/true);
371  cfd = fds[0];
372  } else {
373  pipe.pipe = folly::File(fds[0], /*ownsFd=*/true);
374  cfd = fds[1];
375  }
376  p.second = cfd; // ensure it gets dup2()ed
377  pipe.childFd = p.first;
378  childFds.push_back(cfd);
379  }
380  }
381 
382  // This should already be sorted, as options.fdActions_ is
383  DCHECK(std::is_sorted(pipes_.begin(), pipes_.end()));
384 
385  // Note that the const casts below are legit, per
386  // http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html
387 
388  char** argVec = const_cast<char**>(argv.get());
389 
390  // Set up environment
391  std::unique_ptr<const char*[]> envHolder;
392  char** envVec;
393  if (env) {
394  envHolder = cloneStrings(*env);
395  envVec = const_cast<char**>(envHolder.get());
396  } else {
397  envVec = environ;
398  }
399 
400  // Block all signals around vfork; see http://ewontfix.com/7/.
401  //
402  // As the child may run in the same address space as the parent until
403  // the actual execve() system call, any (custom) signal handlers that
404  // the parent has might alter parent's memory if invoked in the child,
405  // with undefined results. So we block all signals in the parent before
406  // vfork(), which will cause them to be blocked in the child as well (we
407  // rely on the fact that Linux, just like all sane implementations, only
408  // clones the calling thread). Then, in the child, we reset all signals
409  // to their default dispositions (while still blocked), and unblock them
410  // (so the exec()ed process inherits the parent's signal mask)
411  //
412  // The parent also unblocks all signals as soon as vfork() returns.
413  sigset_t allBlocked;
414  r = sigfillset(&allBlocked);
415  checkUnixError(r, "sigfillset");
416  sigset_t oldSignals;
417 
418  r = pthread_sigmask(SIG_SETMASK, &allBlocked, &oldSignals);
419  checkPosixError(r, "pthread_sigmask");
420  SCOPE_EXIT {
421  // Restore signal mask
422  r = pthread_sigmask(SIG_SETMASK, &oldSignals, nullptr);
423  CHECK_EQ(r, 0) << "pthread_sigmask: " << errnoStr(r); // shouldn't fail
424  };
425 
426  // Call c_str() here, as it's not necessarily safe after fork.
427  const char* childDir =
428  options.childDir_.empty() ? nullptr : options.childDir_.c_str();
429 
430  pid_t pid;
431 #ifdef __linux__
432  if (options.cloneFlags_) {
433  pid = syscall(SYS_clone, *options.cloneFlags_, 0, nullptr, nullptr);
434  } else {
435 #endif
436  if (options.detach_) {
437  // If we are detaching we must use fork() instead of vfork() for the first
438  // fork, since we aren't going to simply call exec() in the child.
439  pid = fork();
440  } else {
441  pid = vfork();
442  }
443 #ifdef __linux__
444  }
445 #endif
446  checkUnixError(pid, errno, "failed to fork");
447  if (pid == 0) {
448  // Fork a second time if detach_ was requested.
449  // This must be done before signals are restored in prepareChild()
450  if (options.detach_) {
451 #ifdef __linux__
452  if (options.cloneFlags_) {
453  pid = syscall(SYS_clone, *options.cloneFlags_, 0, nullptr, nullptr);
454  } else {
455 #endif
456  pid = vfork();
457 #ifdef __linux__
458  }
459 #endif
460  if (pid == -1) {
461  // Inform our parent process of the error so it can throw in the parent.
462  childError(errFd, kChildFailure, errno);
463  } else if (pid != 0) {
464  // We are the intermediate process. Exit immediately.
465  // Our child will still inform the original parent of success/failure
466  // through errFd. The pid of the grandchild process never gets
467  // propagated back up to the original parent. In the future we could
468  // potentially send it back using errFd if we needed to.
469  _exit(0);
470  }
471  }
472 
473  int errnoValue = prepareChild(options, &oldSignals, childDir);
474  if (errnoValue != 0) {
475  childError(errFd, kChildFailure, errnoValue);
476  }
477 
478  errnoValue = runChild(executable, argVec, envVec, options);
479  // If we get here, exec() failed.
480  childError(errFd, kExecFailure, errnoValue);
481  }
482 
483  // Child is alive. We have to be very careful about throwing after this
484  // point. We are inside the constructor, so if we throw the Subprocess
485  // object will have never existed, and the destructor will never be called.
486  //
487  // We should only throw if we got an error via the errFd, and we know the
488  // child has exited and can be immediately waited for. In all other cases,
489  // we have no way of cleaning up the child.
490  pid_ = pid;
491  returnCode_ = ProcessReturnCode::makeRunning();
492 }
494 
496  const Options& options,
497  const sigset_t* sigmask,
498  const char* childDir) const {
499  // While all signals are blocked, we must reset their
500  // dispositions to default.
501  for (int sig = 1; sig < NSIG; ++sig) {
502  ::signal(sig, SIG_DFL);
503  }
504 
505  {
506  // Unblock signals; restore signal mask.
507  int r = pthread_sigmask(SIG_SETMASK, sigmask, nullptr);
508  if (r != 0) {
509  return r; // pthread_sigmask() returns an errno value
510  }
511  }
512 
513  // Change the working directory, if one is given
514  if (childDir) {
515  if (::chdir(childDir) == -1) {
516  return errno;
517  }
518  }
519 
520  // We don't have to explicitly close the parent's end of all pipes,
521  // as they all have the FD_CLOEXEC flag set and will be closed at
522  // exec time.
523 
524  // Close all fds that we're supposed to close.
525  for (auto& p : options.fdActions_) {
526  if (p.second == CLOSE) {
527  if (::close(p.first) == -1) {
528  return errno;
529  }
530  } else if (p.second != p.first) {
531  if (::dup2(p.second, p.first) == -1) {
532  return errno;
533  }
534  }
535  }
536 
537  // If requested, close all other file descriptors. Don't close
538  // any fds in options.fdActions_, and don't touch stdin, stdout, stderr.
539  // Ignore errors.
540  if (options.closeOtherFds_) {
541  for (int fd = getdtablesize() - 1; fd >= 3; --fd) {
542  if (options.fdActions_.count(fd) == 0) {
543  ::close(fd);
544  }
545  }
546  }
547 
548 #if __linux__
549  // Opt to receive signal on parent death, if requested
550  if (options.parentDeathSignal_ != 0) {
551  const auto parentDeathSignal =
552  static_cast<unsigned long>(options.parentDeathSignal_);
553  if (prctl(PR_SET_PDEATHSIG, parentDeathSignal, 0, 0, 0) == -1) {
554  return errno;
555  }
556  }
557 #endif
558 
559  if (options.processGroupLeader_) {
560  if (setpgrp() == -1) {
561  return errno;
562  }
563  }
564 
565  // The user callback comes last, so that the child is otherwise all set up.
566  if (options.dangerousPostForkPreExecCallback_) {
567  if (int error = (*options.dangerousPostForkPreExecCallback_)()) {
568  return error;
569  }
570  }
571 
572  return 0;
573 }
574 
576  const char* executable,
577  char** argv,
578  char** env,
579  const Options& options) const {
580  // Now, finally, exec.
581  if (options.usePath_) {
582  ::execvp(executable, argv);
583  } else {
584  ::execve(executable, argv, env);
585  }
586  return errno;
587 }
588 
589 void Subprocess::readChildErrorPipe(int pfd, const char* executable) {
590  ChildErrorInfo info;
591  auto rc = readNoInt(pfd, &info, sizeof(info));
592  if (rc == 0) {
593  // No data means the child executed successfully, and the pipe
594  // was closed due to the close-on-exec flag being set.
595  return;
596  } else if (rc != sizeof(ChildErrorInfo)) {
597  // An error occurred trying to read from the pipe, or we got a partial read.
598  // Neither of these cases should really occur in practice.
599  //
600  // We can't get any error data from the child in this case, and we don't
601  // know if it is successfully running or not. All we can do is to return
602  // normally, as if the child executed successfully. If something bad
603  // happened the caller should at least get a non-normal exit status from
604  // the child.
605  LOG(ERROR) << "unexpected error trying to read from child error pipe "
606  << "rc=" << rc << ", errno=" << errno;
607  return;
608  }
609 
610  // We got error data from the child. The child should exit immediately in
611  // this case, so wait on it to clean up.
612  wait();
613 
614  // Throw to signal the error
615  throw SubprocessSpawnError(executable, info.errCode, info.errnoValue);
616 }
617 
619  returnCode_.enforce(ProcessReturnCode::RUNNING);
620  DCHECK_GT(pid_, 0);
621  int status;
622  pid_t found = ::wait4(pid_, &status, WNOHANG, ru);
623  // The spec guarantees that EINTR does not occur with WNOHANG, so the only
624  // two remaining errors are ECHILD (other code reaped the child?), or
625  // EINVAL (cosmic rays?), both of which merit an abort:
626  PCHECK(found != -1) << "waitpid(" << pid_ << ", &status, WNOHANG)";
627  if (found != 0) {
628  // Though the child process had quit, this call does not close the pipes
629  // since its descendants may still be using them.
630  returnCode_ = ProcessReturnCode::make(status);
631  pid_ = -1;
632  }
633  return returnCode_;
634 }
635 
638  return false;
639  }
640  checkStatus(returnCode_);
641  return true;
642 }
643 
645  returnCode_.enforce(ProcessReturnCode::RUNNING);
646  DCHECK_GT(pid_, 0);
647  int status;
648  pid_t found;
649  do {
650  found = ::waitpid(pid_, &status, 0);
651  } while (found == -1 && errno == EINTR);
652  // The only two remaining errors are ECHILD (other code reaped the
653  // child?), or EINVAL (cosmic rays?), and both merit an abort:
654  PCHECK(found != -1) << "waitpid(" << pid_ << ", &status, WNOHANG)";
655  // Though the child process had quit, this call does not close the pipes
656  // since its descendants may still be using them.
657  DCHECK_EQ(found, pid_);
658  returnCode_ = ProcessReturnCode::make(status);
659  pid_ = -1;
660  return returnCode_;
661 }
662 
664  wait();
665  checkStatus(returnCode_);
666 }
667 
668 void Subprocess::sendSignal(int signal) {
669  returnCode_.enforce(ProcessReturnCode::RUNNING);
670  int r = ::kill(pid_, signal);
671  checkUnixError(r, "kill");
672 }
673 
674 pid_t Subprocess::pid() const {
675  return pid_;
676 }
677 
678 namespace {
679 
680 ByteRange queueFront(const IOBufQueue& queue) {
681  auto* p = queue.front();
682  if (!p) {
683  return ByteRange{};
684  }
685  return io::Cursor(p).peekBytes();
686 }
687 
688 // fd write
689 bool handleWrite(int fd, IOBufQueue& queue) {
690  for (;;) {
691  auto b = queueFront(queue);
692  if (b.empty()) {
693  return true; // EOF
694  }
695 
696  ssize_t n = writeNoInt(fd, b.data(), b.size());
697  if (n == -1 && errno == EAGAIN) {
698  return false;
699  }
700  checkUnixError(n, "write");
701  queue.trimStart(n);
702  }
703 }
704 
705 // fd read
706 bool handleRead(int fd, IOBufQueue& queue) {
707  for (;;) {
708  auto p = queue.preallocate(100, 65000);
709  ssize_t n = readNoInt(fd, p.first, p.second);
710  if (n == -1 && errno == EAGAIN) {
711  return false;
712  }
713  checkUnixError(n, "read");
714  if (n == 0) {
715  return true;
716  }
717  queue.postallocate(n);
718  }
719 }
720 
721 bool discardRead(int fd) {
722  static const size_t bufSize = 65000;
723  // Thread unsafe, but it doesn't matter.
724  static std::unique_ptr<char[]> buf(new char[bufSize]);
725 
726  for (;;) {
727  ssize_t n = readNoInt(fd, buf.get(), bufSize);
728  if (n == -1 && errno == EAGAIN) {
729  return false;
730  }
731  checkUnixError(n, "read");
732  if (n == 0) {
733  return true;
734  }
735  }
736 }
737 
738 } // namespace
739 
740 std::pair<std::string, std::string> Subprocess::communicate(StringPiece input) {
741  IOBufQueue inputQueue;
742  inputQueue.wrapBuffer(input.data(), input.size());
743 
744  auto outQueues = communicateIOBuf(std::move(inputQueue));
745  auto outBufs =
746  std::make_pair(outQueues.first.move(), outQueues.second.move());
747  std::pair<std::string, std::string> out;
748  if (outBufs.first) {
749  outBufs.first->coalesce();
750  out.first.assign(
751  reinterpret_cast<const char*>(outBufs.first->data()),
752  outBufs.first->length());
753  }
754  if (outBufs.second) {
755  outBufs.second->coalesce();
756  out.second.assign(
757  reinterpret_cast<const char*>(outBufs.second->data()),
758  outBufs.second->length());
759  }
760  return out;
761 }
762 
763 std::pair<IOBufQueue, IOBufQueue> Subprocess::communicateIOBuf(
764  IOBufQueue input) {
765  // If the user supplied a non-empty input buffer, make sure
766  // that stdin is a pipe so we can write the data.
767  if (!input.empty()) {
768  // findByChildFd() will throw std::invalid_argument if no pipe for
769  // STDIN_FILENO exists
770  findByChildFd(STDIN_FILENO);
771  }
772 
773  std::pair<IOBufQueue, IOBufQueue> out;
774 
775  auto readCallback = [&](int pfd, int cfd) -> bool {
776  if (cfd == STDOUT_FILENO) {
777  return handleRead(pfd, out.first);
778  } else if (cfd == STDERR_FILENO) {
779  return handleRead(pfd, out.second);
780  } else {
781  // Don't close the file descriptor, the child might not like SIGPIPE,
782  // just read and throw the data away.
783  return discardRead(pfd);
784  }
785  };
786 
787  auto writeCallback = [&](int pfd, int cfd) -> bool {
788  if (cfd == STDIN_FILENO) {
789  return handleWrite(pfd, input);
790  } else {
791  // If we don't want to write to this fd, just close it.
792  return true;
793  }
794  };
795 
796  communicate(std::move(readCallback), std::move(writeCallback));
797 
798  return out;
799 }
800 
802  FdCallback readCallback,
803  FdCallback writeCallback) {
804  // This serves to prevent wait() followed by communicate(), but if you
805  // legitimately need that, send a patch to delete this line.
806  returnCode_.enforce(ProcessReturnCode::RUNNING);
807  setAllNonBlocking();
808 
809  std::vector<pollfd> fds;
810  fds.reserve(pipes_.size());
811  std::vector<size_t> toClose; // indexes into pipes_
812  toClose.reserve(pipes_.size());
813 
814  while (!pipes_.empty()) {
815  fds.clear();
816  toClose.clear();
817 
818  for (auto& p : pipes_) {
819  pollfd pfd;
820  pfd.fd = p.pipe.fd();
821  // Yes, backwards, PIPE_IN / PIPE_OUT are defined from the
822  // child's point of view.
823  if (!p.enabled) {
824  // Still keeping fd in watched set so we get notified of POLLHUP /
825  // POLLERR
826  pfd.events = 0;
827  } else if (p.direction == PIPE_IN) {
828  pfd.events = POLLOUT;
829  } else {
830  pfd.events = POLLIN;
831  }
832  fds.push_back(pfd);
833  }
834 
835  int r;
836  do {
837  r = ::poll(fds.data(), fds.size(), -1);
838  } while (r == -1 && errno == EINTR);
839  checkUnixError(r, "poll");
840 
841  for (size_t i = 0; i < pipes_.size(); ++i) {
842  auto& p = pipes_[i];
843  auto parentFd = p.pipe.fd();
844  DCHECK_EQ(fds[i].fd, parentFd);
845  short events = fds[i].revents;
846 
847  bool closed = false;
848  if (events & POLLOUT) {
849  DCHECK(!(events & POLLIN));
850  if (writeCallback(parentFd, p.childFd)) {
851  toClose.push_back(i);
852  closed = true;
853  }
854  }
855 
856  // Call read callback on POLLHUP, to give it a chance to read (and act
857  // on) end of file
858  if (events & (POLLIN | POLLHUP)) {
859  DCHECK(!(events & POLLOUT));
860  if (readCallback(parentFd, p.childFd)) {
861  toClose.push_back(i);
862  closed = true;
863  }
864  }
865 
866  if ((events & (POLLHUP | POLLERR)) && !closed) {
867  toClose.push_back(i);
868  closed = true;
869  }
870  }
871 
872  // Close the fds in reverse order so the indexes hold after erase()
873  for (int idx : boost::adaptors::reverse(toClose)) {
874  auto pos = pipes_.begin() + idx;
875  pos->pipe.close(); // Throws on error
876  pipes_.erase(pos);
877  }
878  }
879 }
880 
881 void Subprocess::enableNotifications(int childFd, bool enabled) {
882  pipes_[findByChildFd(childFd)].enabled = enabled;
883 }
884 
885 bool Subprocess::notificationsEnabled(int childFd) const {
886  return pipes_[findByChildFd(childFd)].enabled;
887 }
888 
889 size_t Subprocess::findByChildFd(int childFd) const {
890  auto pos = std::lower_bound(
891  pipes_.begin(), pipes_.end(), childFd, [](const Pipe& pipe, int fd) {
892  return pipe.childFd < fd;
893  });
894  if (pos == pipes_.end() || pos->childFd != childFd) {
895  throw std::invalid_argument(
896  folly::to<std::string>("child fd not found ", childFd));
897  }
898  return pos - pipes_.begin();
899 }
900 
901 void Subprocess::closeParentFd(int childFd) {
902  int idx = findByChildFd(childFd);
903  pipes_[idx].pipe.close(); // May throw
904  pipes_.erase(pipes_.begin() + idx);
905 }
906 
907 std::vector<Subprocess::ChildPipe> Subprocess::takeOwnershipOfPipes() {
908  std::vector<Subprocess::ChildPipe> pipes;
909  for (auto& p : pipes_) {
910  pipes.emplace_back(p.childFd, std::move(p.pipe));
911  }
912  // release memory
913  std::vector<Pipe>().swap(pipes_);
914  return pipes;
915 }
916 
917 namespace {
918 
919 class Initializer {
920  public:
921  Initializer() {
922  // We like EPIPE, thanks.
923  ::signal(SIGPIPE, SIG_IGN);
924  }
925 };
926 
927 Initializer initializer;
928 
929 } // namespace
930 
931 } // namespace folly
static const int PIPE
Definition: Subprocess.h:272
static constexpr int RV_RUNNING
Definition: Subprocess.h:223
ProcessReturnCode & operator=(const ProcessReturnCode &p)=default
const folly::IOBuf * front() const
Definition: IOBufQueue.h:476
int returnCode(int value)
def info()
Definition: deadlock.py:447
void readChildErrorPipe(int pfd, const char *executable)
Definition: Subprocess.cpp:589
#define FOLLY_POP_WARNING
Definition: Portability.h:179
static ProcessReturnCode makeRunning()
Definition: Subprocess.h:144
flags
Definition: http_parser.h:127
State state() const
Definition: Subprocess.cpp:74
size_t findByChildFd(const int childFd) const
Definition: Subprocess.cpp:889
static constexpr int RV_NOT_STARTED
Definition: Subprocess.h:222
#define FOLLY_PUSH_WARNING
Definition: Portability.h:178
char b
static ProcessReturnCode make(int status)
Definition: Subprocess.cpp:54
bool empty() const
Definition: IOBufQueue.h:503
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
constexpr int kExecFailure
Definition: Subprocess.cpp:49
ssize_t readNoInt(int fd, void *buf, size_t count)
Definition: FileUtil.cpp:102
STL namespace.
Options & fd(int fd, int action)
Definition: Subprocess.cpp:173
constexpr size_type size() const
Definition: Range.h:431
std::pair< std::string, std::string > communicate(StringPiece input=StringPiece())
Definition: Subprocess.cpp:740
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
void runChild(const char *file)
void spawn(std::unique_ptr< const char *[]> argv, const char *executable, const Options &options, const std::vector< std::string > *env)
Definition: Subprocess.cpp:249
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
requires E e noexcept(noexcept(s.error(std::move(e))))
bool prefix(Cursor &c, uint32_t expected)
CalledProcessError(ProcessReturnCode rc)
Definition: Subprocess.cpp:130
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
Definition: error.h:48
static const int PIPE_OUT
Definition: Subprocess.h:274
std::pair< void *, std::size_t > preallocate(std::size_t min, std::size_t newAllocationSize, std::size_t max=std::numeric_limits< std::size_t >::max())
Definition: IOBufQueue.h:356
DangerousPostForkPreExecCallback * dangerousPostForkPreExecCallback_
Definition: Subprocess.h:497
void closeParentFd(int childFd)
Definition: Subprocess.cpp:901
static std::string toSubprocessSpawnErrorMessage(char const *executable, int errCode, int errnoValue)
Definition: Subprocess.cpp:133
char ** argv
void enableNotifications(int childFd, bool enabled)
Definition: Subprocess.cpp:881
int errCode
Definition: Subprocess.cpp:224
FOLLY_ALWAYS_INLINE void assume_unreachable()
Definition: Assume.h:59
void checkPosixError(int err, Args &&...args)
Definition: Exception.h:83
std::pair< IOBufQueue, IOBufQueue > communicateIOBuf(IOBufQueue input=IOBufQueue())
Definition: Subprocess.cpp:763
int runChild(const char *executable, char **argv, char **env, const Options &options) const
Definition: Subprocess.cpp:575
static const int PIPE_IN
Definition: Subprocess.h:273
bool notificationsEnabled(int childFd) const
Definition: Subprocess.cpp:885
constexpr Iter data() const
Definition: Range.h:446
void sendSignal(int signal)
Definition: Subprocess.cpp:668
ssize_t writeNoInt(int fd, const void *buf, size_t count)
Definition: FileUtil.cpp:114
bool coreDumped() const
Definition: Subprocess.cpp:108
void wrapBuffer(const void *buf, size_t len, std::size_t blockSize=(1U<< 31))
Definition: IOBufQueue.cpp:194
constexpr detail::Sig< Sig > const sig
Definition: Poly.h:1165
bool wait(Waiter *waiter, bool shouldSleep, Waiter *&next)
SubprocessSpawnError(const char *executable, int errCode, int errnoValue)
Definition: Subprocess.cpp:142
std::string str() const
Definition: Subprocess.cpp:113
Definition: Traits.h:588
fbstring errnoStr(int err)
Definition: String.cpp:463
void checkUnixError(ssize_t ret, Args &&...args)
Definition: Exception.h:101
cmd
Definition: gtest-cfgcmd.txt:1
void swap(exception_wrapper &a, exception_wrapper &b) noexcept
FOLLY_NODISCARD detail::ScopeGuardImplDecay< F, true > makeGuard(F &&f) noexcept(noexcept(detail::ScopeGuardImplDecay< F, true >(static_cast< F && >(f))))
Definition: ScopeGuard.h:184
const char * string
Definition: Conv.cpp:212
std::vector< ChildPipe > takeOwnershipOfPipes()
Definition: Subprocess.cpp:907
int poll(PollDescriptor fds[], nfds_t nfds, int timeout)
Definition: NetOps.cpp:141
void setAllNonBlocking()
Definition: Subprocess.cpp:239
void enforce(State state) const
Definition: Subprocess.cpp:90
static set< string > s
const
Definition: upload.py:398
void trimStart(size_t amount)
Definition: IOBufQueue.cpp:255
int prepareChild(const Options &options, const sigset_t *sigmask, const char *childDir) const
Definition: Subprocess.cpp:495
ProcessReturnCode wait()
Definition: Subprocess.cpp:644
int errnoValue
Definition: Subprocess.cpp:225
void postallocate(std::size_t n)
Definition: IOBufQueue.h:380
int close(NetworkSocket s)
Definition: NetOps.cpp:90
ProcessReturnCode poll(struct rusage *ru=nullptr)
Definition: Subprocess.cpp:618
pid_t pid() const
Definition: Subprocess.cpp:674
constexpr int kChildFailure
Definition: Subprocess.cpp:50
void pipe(CPUExecutor cpu, IOExecutor io)
state
Definition: http_parser.c:272
#define FOLLY_GCC_DISABLE_WARNING(warningName)
Definition: Portability.h:181
action
Definition: upload.py:393