fork download
  1. #include <stdexcept>
  2. #include <string>
  3. #include <iostream>
  4. #include <thread>
  5.  
  6. #include <unistd.h>
  7.  
  8. void reader(std::string& out, int fd)
  9. {
  10. char buf[1024];
  11. int rnum = 0;
  12. do {
  13. rnum = read(fd, buf, 1024);
  14. if (rnum > 0) {
  15. out.append(buf, rnum);
  16. }
  17. } while (rnum > 0);
  18. }
  19.  
  20. void exec(const std::string& cmd, const std::string& in,
  21. std::string& out, std::string& err)
  22. {
  23. int outfd[2];
  24. int infd[2];
  25. int errfd[2];
  26.  
  27. // Where the parent is going to write to
  28. if (pipe(infd) != 0)
  29. throw std::runtime_error("failed to create a pipe");
  30.  
  31. // From where parent is going to read
  32. if (pipe(outfd) != 0)
  33. throw std::runtime_error("failed to create a pipe");
  34. if (pipe(errfd) != 0)
  35. throw std::runtime_error("failed to create a pipe");
  36.  
  37. if (fork()==0) {
  38. close(STDOUT_FILENO);
  39. close(STDIN_FILENO);
  40. close(STDERR_FILENO);
  41.  
  42. dup2(infd[0], STDIN_FILENO);
  43. dup2(outfd[1], STDOUT_FILENO);
  44. dup2(errfd[1], STDERR_FILENO);
  45.  
  46. close(outfd[0]); // Not required for the child
  47. close(outfd[1]);
  48. close(infd[0]);
  49. close(infd[1]);
  50. close(errfd[0]);
  51. close(errfd[1]);
  52.  
  53. execl("/bin/bash", "bash", "-c", cmd.c_str(), 0);
  54. exit(0);
  55. } else {
  56. //close unused file descriptors
  57. close(infd[0]);
  58. close(outfd[1]);
  59. close(errfd[1]);
  60.  
  61. //create some threads to write to in[1] and read from out[0] err[0]
  62. std::thread write_in(write, infd[1], in.c_str(), in.size());
  63. std::thread read_out(reader, std::ref(out), outfd[0]);
  64. std::thread read_err(reader, std::ref(err), errfd[0]);
  65.  
  66. write_in.join();
  67. read_out.join();
  68. read_err.join();
  69.  
  70. close(infd[1]);
  71. close(outfd[0]);
  72. close(errfd[0]);
  73. }
  74. }
  75.  
  76. int main()
  77. {
  78. std::string out, err;
  79. exec("ls", "", out, err);
  80. std::cout << out;
  81. }
  82.  
  83.  
Runtime error #stdin #stdout 0s 4200KB
stdin
Standard input is empty
stdout
Standard output is empty