Repository: ossrs/srs
File: trunk/src/app/srs_app_process.cpp (C++)

Code before:
        // redirect stderr to file if possible.
        if ((err = srs_redirect_output(stderr_file, STDERR_FILENO)) != srs_success) {
            child_err = srs_error_wrap(err, "redirect output");
        }

        // No stdin for process, @bug https://github.com/ossrs/srs/issues/1592
        if ((err = srs_redirect_output("/dev/null", STDIN_FILENO)) != srs_success) {
            child_err = srs_error_wrap(err, "redirect input");
        }

        // should never close the fd 3+, for it myabe used.
        // for fd should close at exec, use fnctl to set it.
        
        // log basic info to stderr.
        if (true) {
            fprintf(stdout, "\n");
            fprintf(stdout, "process ppid=%d, cid=%s, pid=%d, in=%d, out=%d, err=%d\n",
                ppid, cid.c_str(), getpid(), STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
            fprintf(stdout, "process binary=%s, cli: %s\n", bin.c_str(), cli.c_str());
            fprintf(stdout, "process actual cli: %s\n", actual_cli.c_str());
        }
        
        // output error to stdout and exit child process.
        if (child_err != srs_success) {
            fprintf(stdout, "child process error, %s\n", srs_error_desc(child_err).c_str());
            exit(-1);
        }
        
        // memory leak in child process, it's ok.
        char** argv = new char*[params.size() + 1];
        for (int i = 0; i < (int)params.size(); i++) {
            std::string& p = params[i];
            
            // memory leak in child process, it's ok.
            char* v = new char[p.length() + 1];
            argv[i] = strcpy(v, p.data());
        }
        argv[params.size()] = NULL;
        
        // use execv to start the program.
        int r0 = execv(bin.c_str(), argv);
        if (r0 < 0) {
            fprintf(stderr, "fork process failed, errno=%d(%s)", errno, strerror(errno));
        }
        exit(r0);
    }
    
    // parent.
    if (pid > 0) {
        // Wait for a while for process to really started.
        // @see https://github.com/ossrs/srs/issues/1634#issuecomment-597568840

Review comment (suggestion):
You can change `srs_redirect_output` to a function call, for example:

```
srs_error_t SrsProcess::redirect_io()
```

This way, when calling, there is no need to define names like `child_err`, but instead:

```
        err = redirect_io();

        if (true) {
            fprintf(stdout, "\n");
            fprintf(stdout, "process ppid=%d, cid=%s, pid=%d, in=%d, out=%d, err=%d\n",
                ppid, cid.c_str(), getpid(), STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
            fprintf(stdout, "process binary=%s, cli: %s\n", bin.c_str(), cli.c_str());
            fprintf(stdout, "process actual cli: %s\n", actual_cli.c_str());
        }

        // output error to stdout and exit child process.
        if (err != srs_success) {
            fprintf(stdout, "child process error, %s\n", srs_error_desc(err).c_str());
            exit(-1);
        }
```

Similarly, when implementing, there is no need to define special error variable names, but instead use `err`:

```
srs_error_t SrsProcess::redirect_io()
{
    srs_error_t err = srs_success;

    // for the stdout, ignore when not specified.
    // redirect stdout to file if possible.
    if ((err = srs_redirect_output(stdout_file, STDOUT_FILENO)) != srs_success) {
        return srs_error_wrap(err, "redirect output");
    }

    .......

    return err;
}
```

The variable name `err` is easier to understand and less prone to misuse, making it easier to maintain.

`TRANS_BY_GPT3`

Code after:
    
    // TODO: fork or vfork?
    if ((pid = fork()) < 0) {
        return srs_error_new(ERROR_ENCODER_FORK, "vfork process failed, cli=%s", cli.c_str());
    }
    
    // for osx(lldb) to debug the child process.
    // user can use "lldb -p <pid>" to resume the parent or child process.
    //kill(0, SIGSTOP);
    
    // child process: ffmpeg encoder engine.
    if (pid == 0) {
        // ignore the SIGINT and SIGTERM
        signal(SIGINT, SIG_IGN);
        signal(SIGTERM, SIG_IGN);
        
        // redirect standard I/O, if it failed, output error to stdout, and exit child process.
        if ((err = redirect_io()) != srs_success) {
            fprintf(stdout, "child process error, %s\n", srs_error_desc(err).c_str());
            exit(-1);
        }
        
        // should never close the fd 3+, for it myabe used.
        // for fd should close at exec, use fnctl to set it.
        
        // log basic info to stderr.
        if (true) {
            fprintf(stdout, "\n");
            fprintf(stdout, "process ppid=%d, cid=%s, pid=%d, in=%d, out=%d, err=%d\n",
                ppid, cid.c_str(), getpid(), STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
            fprintf(stdout, "process binary=%s, cli: %s\n", bin.c_str(), cli.c_str());
            fprintf(stdout, "process actual cli: %s\n", actual_cli.c_str());
        }
        
        // memory leak in child process, it's ok.
        char** argv = new char*[params.size() + 1];
        for (int i = 0; i < (int)params.size(); i++) {
            std::string& p = params[i];
            
            // memory leak in child process, it's ok.
            char* v = new char[p.length() + 1];
            argv[i] = strcpy(v, p.data());
        }
        argv[params.size()] = NULL;
        
        // use execv to start the program.
        int r0 = execv(bin.c_str(), argv);
        if (r0 < 0) {
            fprintf(stderr, "fork process failed, errno=%d(%s)", errno, strerror(errno));
        }
        exit(r0);