winlin

for #367, process support redirect stdout and stderr.

@@ -24,12 +24,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -24,12 +24,16 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include <srs_app_ffmpeg.hpp> 24 #include <srs_app_ffmpeg.hpp>
25 25
26 #include <stdlib.h> 26 #include <stdlib.h>
27 -#include <unistd.h>  
28 #include <sys/wait.h> 27 #include <sys/wait.h>
29 #include <fcntl.h> 28 #include <fcntl.h>
30 #include <signal.h> 29 #include <signal.h>
31 #include <sys/types.h> 30 #include <sys/types.h>
32 31
  32 +// for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213
  33 +#ifndef _WIN32
  34 +#include <unistd.h>
  35 +#endif
  36 +
33 #include <vector> 37 #include <vector>
34 using namespace std; 38 using namespace std;
35 39
@@ -407,7 +411,7 @@ int SrsFFMPEG::start() @@ -407,7 +411,7 @@ int SrsFFMPEG::start()
407 params.push_back(_output); 411 params.push_back(_output);
408 412
409 // when specified the log file. 413 // when specified the log file.
410 - if (false && !log_file.empty()) { 414 + if (!log_file.empty()) {
411 // stdout 415 // stdout
412 params.push_back("1"); 416 params.push_back("1");
413 params.push_back(">"); 417 params.push_back(">");
@@ -30,6 +30,11 @@ @@ -30,6 +30,11 @@
30 #include <signal.h> 30 #include <signal.h>
31 #include <sys/types.h> 31 #include <sys/types.h>
32 32
  33 +// for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213
  34 +#ifndef _WIN32
  35 +#include <unistd.h>
  36 +#endif
  37 +
33 using namespace std; 38 using namespace std;
34 39
35 #include <srs_kernel_error.hpp> 40 #include <srs_kernel_error.hpp>
@@ -57,8 +62,34 @@ int SrsProcess::initialize(string binary, vector<string> argv) @@ -57,8 +62,34 @@ int SrsProcess::initialize(string binary, vector<string> argv)
57 { 62 {
58 int ret = ERROR_SUCCESS; 63 int ret = ERROR_SUCCESS;
59 64
60 - bin = binary;  
61 - params = argv; 65 + cli = bin = binary;
  66 +
  67 + for (int i = 0; i < (int)argv.size(); i++) {
  68 + std::string ffp = argv[i];
  69 + cli += " " + ffp;
  70 + }
  71 +
  72 + for (int i = 0; i < (int)argv.size(); i++) {
  73 + std::string ffp = argv[i];
  74 +
  75 + // remove the stdout and stderr.
  76 + if (ffp == "1") {
  77 + if (i + 2 < (int)argv.size()) {
  78 + stdout_file = argv[i + 2];
  79 + i += 2;
  80 + }
  81 + continue;
  82 + } else if (ffp == "2") {
  83 + if (i + 2 < (int)argv.size()) {
  84 + stderr_file = argv[i + 2];
  85 + i += 2;
  86 + }
  87 + continue;
  88 + }
  89 +
  90 + // startup params.
  91 + params.push_back(ffp);
  92 + }
62 93
63 return ret; 94 return ret;
64 } 95 }
@@ -71,20 +102,12 @@ int SrsProcess::start() @@ -71,20 +102,12 @@ int SrsProcess::start()
71 return ret; 102 return ret;
72 } 103 }
73 104
74 - std::string cli;  
75 - if (true) {  
76 - for (int i = 0; i < (int)params.size(); i++) {  
77 - std::string ffp = params[i];  
78 - cli += ffp;  
79 - if (i < (int)params.size() - 1) {  
80 - cli += " ";  
81 - }  
82 - }  
83 - srs_trace("fork process: %s %s", bin.c_str(), cli.c_str());  
84 - } 105 + // generate the argv of process.
  106 + srs_trace("fork process: %s", cli.c_str());
85 107
86 // for log 108 // for log
87 int cid = _srs_context->get_id(); 109 int cid = _srs_context->get_id();
  110 + int ppid = getpid();
88 111
89 // TODO: fork or vfork? 112 // TODO: fork or vfork?
90 if ((pid = fork()) < 0) { 113 if ((pid = fork()) < 0) {
@@ -99,12 +122,51 @@ int SrsProcess::start() @@ -99,12 +122,51 @@ int SrsProcess::start()
99 signal(SIGINT, SIG_IGN); 122 signal(SIGINT, SIG_IGN);
100 signal(SIGTERM, SIG_IGN); 123 signal(SIGTERM, SIG_IGN);
101 124
  125 + // redirect stdout to file.
  126 + if (!stdout_file.empty()) {
  127 + int stdout_fd = -1;
  128 + int flags = O_CREAT|O_WRONLY|O_APPEND;
  129 + mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
  130 +
  131 + if ((stdout_fd = ::open(stdout_file.c_str(), flags, mode)) < 0) {
  132 + ret = ERROR_ENCODER_OPEN;
  133 + fprintf(stderr, "open process stdout %s failed. ret=%d", stdout_file.c_str(), ret);
  134 + return ret;
  135 + }
  136 +
  137 + if (dup2(stdout_fd, STDOUT_FILENO) < 0) {
  138 + ret = ERROR_ENCODER_DUP2;
  139 + srs_error("dup2 process stdout failed. ret=%d", ret);
  140 + return ret;
  141 + }
  142 + }
  143 +
  144 + // redirect stderr to file.
  145 + if (!stderr_file.empty()) {
  146 + int stderr_fd = -1;
  147 + int flags = O_CREAT|O_WRONLY|O_APPEND;
  148 + mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
  149 +
  150 + if ((stderr_fd = ::open(stderr_file.c_str(), flags, mode)) < 0) {
  151 + ret = ERROR_ENCODER_OPEN;
  152 + fprintf(stderr, "open process stderr %s failed. ret=%d", stderr_file.c_str(), ret);
  153 + return ret;
  154 + }
  155 +
  156 + if (dup2(stderr_fd, STDERR_FILENO) < 0) {
  157 + ret = ERROR_ENCODER_DUP2;
  158 + srs_error("dup2 process stderr failed. ret=%d", ret);
  159 + return ret;
  160 + }
  161 + }
  162 +
102 // log basic info 163 // log basic info
103 if (true) { 164 if (true) {
104 fprintf(stderr, "\n"); 165 fprintf(stderr, "\n");
105 - fprintf(stderr, "process parent cid=%d", cid);  
106 - fprintf(stderr, "process binary=%s", bin.c_str());  
107 - fprintf(stderr, "process params: %s %s", bin.c_str(), cli.c_str()); 166 + fprintf(stderr, "process parent pid=%d\n", ppid);
  167 + fprintf(stderr, "process parent cid=%d\n", cid);
  168 + fprintf(stderr, "process binary=%s\n", bin.c_str());
  169 + fprintf(stderr, "process cli: %s\n", cli.c_str());
108 } 170 }
109 171
110 // close other fds 172 // close other fds
@@ -133,7 +195,7 @@ int SrsProcess::start() @@ -133,7 +195,7 @@ int SrsProcess::start()
133 // parent. 195 // parent.
134 if (pid > 0) { 196 if (pid > 0) {
135 is_started = true; 197 is_started = true;
136 - srs_trace("vfored process, pid=%d, cli=%s", pid, bin.c_str()); 198 + srs_trace("vfored process, pid=%d, bin=%s", pid, bin.c_str());
137 return ret; 199 return ret;
138 } 200 }
139 201
@@ -51,7 +51,11 @@ private: @@ -51,7 +51,11 @@ private:
51 pid_t pid; 51 pid_t pid;
52 private: 52 private:
53 std::string bin; 53 std::string bin;
  54 + std::string stdout_file;
  55 + std::string stderr_file;
54 std::vector<std::string> params; 56 std::vector<std::string> params;
  57 + // the cli to fork process.
  58 + std::string cli;
55 public: 59 public:
56 SrsProcess(); 60 SrsProcess();
57 virtual ~SrsProcess(); 61 virtual ~SrsProcess();