winlin

refine the dup2 of stdout and stderr.

@@ -141,6 +141,43 @@ int SrsProcess::initialize(string binary, vector<string> argv) @@ -141,6 +141,43 @@ int SrsProcess::initialize(string binary, vector<string> argv)
141 return ret; 141 return ret;
142 } 142 }
143 143
  144 +int srs_redirect_output(string from_file, int to_fd)
  145 +{
  146 + int ret = ERROR_SUCCESS;
  147 +
  148 + // use default output.
  149 + if (from_file.empty()) {
  150 + return ret;
  151 + }
  152 +
  153 + // disable output.
  154 + if (from_file == SRS_CONSTS_NULL_FILE) {
  155 + ::close(to_fd);
  156 + return ret;
  157 + }
  158 +
  159 + // redirect the fd to file.
  160 + int fd = -1;
  161 + int flags = O_CREAT|O_WRONLY|O_APPEND;
  162 + mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
  163 +
  164 + if ((fd = ::open(from_file.c_str(), flags, mode)) < 0) {
  165 + ret = ERROR_FORK_OPEN_LOG;
  166 + fprintf(stderr, "open process %d %s failed. ret=%d", to_fd, from_file.c_str(), ret);
  167 + exit(ret);
  168 + }
  169 +
  170 + if (dup2(fd, to_fd) < 0) {
  171 + ret = ERROR_FORK_DUP2_LOG;
  172 + srs_error("dup2 process %d failed. ret=%d", to_fd, ret);
  173 + exit(ret);
  174 + }
  175 +
  176 + ::close(fd);
  177 +
  178 + return ret;
  179 +}
  180 +
144 int SrsProcess::start() 181 int SrsProcess::start()
145 { 182 {
146 int ret = ERROR_SUCCESS; 183 int ret = ERROR_SUCCESS;
@@ -173,42 +210,19 @@ int SrsProcess::start() @@ -173,42 +210,19 @@ int SrsProcess::start()
173 signal(SIGINT, SIG_IGN); 210 signal(SIGINT, SIG_IGN);
174 signal(SIGTERM, SIG_IGN); 211 signal(SIGTERM, SIG_IGN);
175 212
176 - // redirect stdout to file.  
177 - if (!stdout_file.empty()) {  
178 - int stdout_fd = -1;  
179 - int flags = O_CREAT|O_WRONLY|O_APPEND;  
180 - mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;  
181 -  
182 - if ((stdout_fd = ::open(stdout_file.c_str(), flags, mode)) < 0) {  
183 - ret = ERROR_ENCODER_OPEN;  
184 - fprintf(stderr, "open process stdout %s failed. ret=%d", stdout_file.c_str(), ret);  
185 - exit(ret);  
186 - }  
187 -  
188 - if (dup2(stdout_fd, STDOUT_FILENO) < 0) {  
189 - ret = ERROR_ENCODER_DUP2;  
190 - srs_error("dup2 process stdout failed. ret=%d", ret);  
191 - exit(ret);  
192 - } 213 + // for the stdin,
  214 + // should never close it or ffmpeg will error.
  215 +
  216 + // for the stdout, ignore when not specified.
  217 + // redirect stdout to file if possible.
  218 + if ((ret = srs_redirect_output(stdout_file, STDOUT_FILENO)) != ERROR_SUCCESS) {
  219 + return ret;
193 } 220 }
194 221
195 - // redirect stderr to file.  
196 - if (!stderr_file.empty()) {  
197 - int stderr_fd = -1;  
198 - int flags = O_CREAT|O_WRONLY|O_APPEND;  
199 - mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;  
200 -  
201 - if ((stderr_fd = ::open(stderr_file.c_str(), flags, mode)) < 0) {  
202 - ret = ERROR_ENCODER_OPEN;  
203 - fprintf(stderr, "open process stderr %s failed. ret=%d", stderr_file.c_str(), ret);  
204 - exit(ret);  
205 - }  
206 -  
207 - if (dup2(stderr_fd, STDERR_FILENO) < 0) {  
208 - ret = ERROR_ENCODER_DUP2;  
209 - srs_error("dup2 process stderr failed. ret=%d", ret);  
210 - exit(ret);  
211 - } 222 + // for the stderr, ignore when not specified.
  223 + // redirect stderr to file if possible.
  224 + if ((ret = srs_redirect_output(stderr_file, STDERR_FILENO)) != ERROR_SUCCESS) {
  225 + return ret;
212 } 226 }
213 227
214 // should never close the fd 3+, for it myabe used. 228 // should never close the fd 3+, for it myabe used.
@@ -202,8 +202,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -202,8 +202,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
202 #define ERROR_ENCODER_VBITRATE 3027 202 #define ERROR_ENCODER_VBITRATE 3027
203 #define ERROR_ENCODER_FORK 3028 203 #define ERROR_ENCODER_FORK 3028
204 #define ERROR_ENCODER_LOOP 3029 204 #define ERROR_ENCODER_LOOP 3029
205 -#define ERROR_ENCODER_OPEN 3030  
206 -#define ERROR_ENCODER_DUP2 3031 205 +#define ERROR_FORK_OPEN_LOG 3030
  206 +#define ERROR_FORK_DUP2_LOG 3031
207 #define ERROR_ENCODER_PARSE 3032 207 #define ERROR_ENCODER_PARSE 3032
208 #define ERROR_ENCODER_NO_INPUT 3033 208 #define ERROR_ENCODER_NO_INPUT 3033
209 #define ERROR_ENCODER_NO_OUTPUT 3034 209 #define ERROR_ENCODER_NO_OUTPUT 3034