Switch to unified view

a/src/execmd.cpp b/src/execmd.cpp
...
...
61
61
62
extern char **environ;
62
extern char **environ;
63
63
64
class ExecCmd::Internal {
64
class ExecCmd::Internal {
65
public:
65
public:
66
    Internal()
66
    Internal() {
67
        : m_advise(0), m_provide(0), m_timeoutMs(1000),
67
        sigemptyset(&m_blkcld);
68
          m_rlimit_as_mbytes(0) {
69
    }
68
    }
70
69
71
    static bool      o_useVfork;
70
    static bool      o_useVfork;
72
71
73
    std::vector<std::string>   m_env;
72
    vector<string>   m_env;
74
    ExecCmdAdvise   *m_advise;
73
    ExecCmdAdvise   *m_advise{0};
75
    ExecCmdProvide  *m_provide;
74
    ExecCmdProvide  *m_provide{0};
76
    bool             m_killRequest;
75
    bool             m_killRequest{false};
77
    int              m_timeoutMs;
76
    int              m_timeoutMs{1000};
78
    int              m_rlimit_as_mbytes;
77
    int              m_rlimit_as_mbytes{0};
79
    string           m_stderrFile;
78
    string           m_stderrFile;
80
    // Pipe for data going to the command
79
    // Pipe for data going to the command
81
    int              m_pipein[2];
80
    int              m_pipein[2]{-1,-1};
82
    std::shared_ptr<NetconCli> m_tocmd;
81
    std::shared_ptr<NetconCli> m_tocmd;
83
    // Pipe for data coming out
82
    // Pipe for data coming out
84
    int              m_pipeout[2];
83
    int              m_pipeout[2]{-1,-1};
85
    std::shared_ptr<NetconCli> m_fromcmd;
84
    std::shared_ptr<NetconCli> m_fromcmd;
86
    // Subprocess id
85
    // Subprocess id
87
    pid_t            m_pid;
86
    pid_t            m_pid{-1};
88
    // Saved sigmask
87
    // Saved sigmask
89
    sigset_t         m_blkcld;
88
    sigset_t         m_blkcld;
90
89
91
    // Reset internal state indicators. Any resources should have been
90
    // Reset internal state indicators. Any resources should have been
92
    // previously freed
91
    // previously freed
...
...
98
    }
97
    }
99
    // Child process code
98
    // Child process code
100
    inline void dochild(const std::string& cmd, const char **argv,
99
    inline void dochild(const std::string& cmd, const char **argv,
101
                        const char **envv, bool has_input, bool has_output);
100
                        const char **envv, bool has_input, bool has_output);
102
};
101
};
103
bool ExecCmd::Internal::o_useVfork = false;
102
bool ExecCmd::Internal::o_useVfork{false};
104
103
105
ExecCmd::ExecCmd(int)
104
ExecCmd::ExecCmd(int)
106
{
105
{
107
    m = new Internal();
106
    m = new Internal();
108
    if (m) {
107
    if (m) {
...
...
271
        // this case, we have to conclude that the child process does
270
        // this case, we have to conclude that the child process does
272
        // not exist. Not too sure what causes this, but the previous code
271
        // not exist. Not too sure what causes this, but the previous code
273
        // definitely tried to call killpg(-1,) from time to time.
272
        // definitely tried to call killpg(-1,) from time to time.
274
        pid_t grp;
273
        pid_t grp;
275
        if (m_parent->m_pid > 0 && (grp = getpgid(m_parent->m_pid)) > 0) {
274
        if (m_parent->m_pid > 0 && (grp = getpgid(m_parent->m_pid)) > 0) {
276
            LOGDEB("ExecCmd: killpg(" << (grp) << ", SIGTERM)\n");
275
            LOGDEB("ExecCmd: pid " << m_parent->m_pid << " killpg(" << grp <<
276
                   ", SIGTERM)\n");
277
            int ret = killpg(grp, SIGTERM);
277
            int ret = killpg(grp, SIGTERM);
278
            if (ret == 0) {
278
            if (ret == 0) {
279
                for (int i = 0; i < 3; i++) {
279
                for (int i = 0; i < 3; i++) {
280
                    msleep(i == 0 ? 5 : (i == 1 ? 100 : 2000));
280
                    msleep(i == 0 ? 5 : (i == 1 ? 100 : 2000));
281
                    int status;
281
                    int status;
...
...
331
inline void ExecCmd::Internal::dochild(const string& cmd, const char **argv,
331
inline void ExecCmd::Internal::dochild(const string& cmd, const char **argv,
332
                                       const char **envv,
332
                                       const char **envv,
333
                                       bool has_input, bool has_output)
333
                                       bool has_input, bool has_output)
334
{
334
{
335
    // Start our own process group
335
    // Start our own process group
336
    if (setpgid(0, getpid())) {
336
    if (setpgid(0, 0)) {
337
        LOGINFO("ExecCmd::DOCHILD: setpgid(0, " << getpid() <<
337
        LOGINFO("ExecCmd::DOCHILD: setpgid(0, 0) failed: errno " << errno <<
338
                ") failed: errno " << errno << "\n");
338
                "\n");
339
    }
339
    }
340
340
341
    // Restore SIGTERM to default. Really, signal handling should be
341
    // Restore SIGTERM to default. Really, signal handling should be
342
    // specified when creating the execmd, there might be other
342
    // specified when creating the execmd, there might be other
343
    // signals to reset. Resetting SIGTERM helps Recoll get rid of its
343
    // signals to reset. Resetting SIGTERM helps Recoll get rid of its
...
...
538
    envv[i++] = 0;
538
    envv[i++] = 0;
539
539
540
    // As we are going to use execve, not execvp, do the PATH thing.
540
    // As we are going to use execve, not execvp, do the PATH thing.
541
    string exe;
541
    string exe;
542
    if (!which(cmd, exe)) {
542
    if (!which(cmd, exe)) {
543
        LOGERR("ExecCmd::startExec: " << (cmd) << " not found\n");
543
        LOGERR("ExecCmd::startExec: " << cmd << " not found\n");
544
        free(argv);
544
        free(argv);
545
        free(envv);
545
        free(envv);
546
        return -1;
546
        return 127 << 8;
547
    }
547
    }
548
//////////////////////////////// End vfork child prepare section.
548
//////////////////////////////// End vfork child prepare section.
549
549
550
#if HAVE_POSIX_SPAWN && USE_POSIX_SPAWN
550
#if HAVE_POSIX_SPAWN && USE_POSIX_SPAWN
551
    // Note that posix_spawn provides no way to setrlimit() the child.
551
    // Note that posix_spawn provides no way to setrlimit() the child.
...
...
763
763
764
764
765
int ExecCmd::doexec(const string& cmd, const vector<string>& args,
765
int ExecCmd::doexec(const string& cmd, const vector<string>& args,
766
                    const string *input, string *output)
766
                    const string *input, string *output)
767
{
767
{
768
769
    if (startExec(cmd, args, input != 0, output != 0) < 0) {
768
    int status = startExec(cmd, args, input != 0, output != 0);
769
    if (status) {
770
        return -1;
770
        return status;
771
    }
771
    }
772
772
773
    // Cleanup in case we return early
773
    // Cleanup in case we return early
774
    ExecCmdRsrc e(m);
774
    ExecCmdRsrc e(m);
775
    SelectLoop myloop;
775
    SelectLoop myloop;