|
a/src/utils/execmd.cpp |
|
b/src/utils/execmd.cpp |
|
... |
|
... |
126 |
void inactivate() {m_active = false;}
|
126 |
void inactivate() {m_active = false;}
|
127 |
~ExecCmdRsrc() {
|
127 |
~ExecCmdRsrc() {
|
128 |
if (!m_active || !m_parent)
|
128 |
if (!m_active || !m_parent)
|
129 |
return;
|
129 |
return;
|
130 |
LOGDEB1(("~ExecCmdRsrc: working. mypid: %d\n", (int)getpid()));
|
130 |
LOGDEB1(("~ExecCmdRsrc: working. mypid: %d\n", (int)getpid()));
|
|
|
131 |
|
|
|
132 |
// Better to close the descs first in case the child is waiting in read
|
|
|
133 |
if (m_parent->m_pipein[0] >= 0)
|
|
|
134 |
close(m_parent->m_pipein[0]);
|
|
|
135 |
if (m_parent->m_pipein[1] >= 0)
|
|
|
136 |
close(m_parent->m_pipein[1]);
|
|
|
137 |
if (m_parent->m_pipeout[0] >= 0)
|
|
|
138 |
close(m_parent->m_pipeout[0]);
|
|
|
139 |
if (m_parent->m_pipeout[1] >= 0)
|
|
|
140 |
close(m_parent->m_pipeout[1]);
|
131 |
int status;
|
141 |
int status;
|
132 |
if (m_parent->m_pid > 0) {
|
142 |
if (m_parent->m_pid > 0) {
|
133 |
LOGDEB(("ExecCmd: killing cmd\n"));
|
|
|
134 |
pid_t grp = getpgid(m_parent->m_pid);
|
143 |
pid_t grp = getpgid(m_parent->m_pid);
|
|
|
144 |
LOGDEB2(("ExecCmd: killpg(%d, SIGTERM)\n", grp));
|
135 |
int ret = killpg(grp, SIGTERM);
|
145 |
int ret = killpg(grp, SIGTERM);
|
136 |
if (ret == 0) {
|
146 |
if (ret == 0) {
|
137 |
for (int i = 0; i < 3; i++) {
|
147 |
for (int i = 0; i < 3; i++) {
|
138 |
(void)waitpid(m_parent->m_pid, &status, WNOHANG);
|
148 |
(void)waitpid(m_parent->m_pid, &status, WNOHANG);
|
139 |
if (kill(m_parent->m_pid, 0) != 0)
|
149 |
if (kill(m_parent->m_pid, 0) != 0)
|
140 |
break;
|
150 |
break;
|
141 |
sleep(1);
|
151 |
sleep(1);
|
142 |
if (i == 2) {
|
152 |
if (i == 2) {
|
143 |
LOGDEB(("ExecCmd: killing (KILL) cmd\n"));
|
153 |
LOGDEB(("ExecCmd: killpg(%d, SIGKILL)\n", grp));
|
144 |
killpg(grp, SIGKILL);
|
154 |
killpg(grp, SIGKILL);
|
|
|
155 |
(void)waitpid(m_parent->m_pid, &status, WNOHANG);
|
145 |
}
|
156 |
}
|
146 |
}
|
157 |
}
|
147 |
} else {
|
158 |
} else {
|
148 |
LOGERR(("ExecCmd: error killing process group %d: %d\n",
|
159 |
LOGERR(("ExecCmd: error killing process group %d: %d\n",
|
149 |
grp, errno));
|
160 |
grp, errno));
|
150 |
}
|
161 |
}
|
151 |
}
|
162 |
}
|
152 |
if (m_parent->m_pipein[0] >= 0)
|
|
|
153 |
close(m_parent->m_pipein[0]);
|
|
|
154 |
if (m_parent->m_pipein[1] >= 0)
|
|
|
155 |
close(m_parent->m_pipein[1]);
|
|
|
156 |
if (m_parent->m_pipeout[0] >= 0)
|
|
|
157 |
close(m_parent->m_pipeout[0]);
|
|
|
158 |
if (m_parent->m_pipeout[1] >= 0)
|
|
|
159 |
close(m_parent->m_pipeout[1]);
|
|
|
160 |
m_parent->m_tocmd.release();
|
163 |
m_parent->m_tocmd.release();
|
161 |
m_parent->m_fromcmd.release();
|
164 |
m_parent->m_fromcmd.release();
|
162 |
pthread_sigmask(SIG_UNBLOCK, &m_parent->m_blkcld, 0);
|
165 |
pthread_sigmask(SIG_UNBLOCK, &m_parent->m_blkcld, 0);
|
163 |
m_parent->reset();
|
166 |
m_parent->reset();
|
164 |
}
|
167 |
}
|
|
... |
|
... |
472 |
// This must not return. exit() on error.
|
475 |
// This must not return. exit() on error.
|
473 |
void ExecCmd::dochild(const string &cmd, const list<string>& args,
|
476 |
void ExecCmd::dochild(const string &cmd, const list<string>& args,
|
474 |
bool has_input, bool has_output)
|
477 |
bool has_input, bool has_output)
|
475 |
{
|
478 |
{
|
476 |
// Start our own process group
|
479 |
// Start our own process group
|
477 |
setpgid(0, getpid());
|
480 |
if (setpgid(0, getpid())) {
|
|
|
481 |
LOGINFO(("ExecCmd::dochild: setpgid(0, %d) failed: errno %d\n",
|
|
|
482 |
getpid(), errno));
|
478 |
|
483 |
}
|
|
|
484 |
|
|
|
485 |
// Restore SIGTERM to default. Really, signal handling should be
|
|
|
486 |
// specified when creating the execmd. Help Recoll get rid of its
|
|
|
487 |
// filter children though. To be fixed one day... Not sure that
|
|
|
488 |
// all of this is needed. But an ignored sigterm and the masks are
|
|
|
489 |
// normally inherited.
|
|
|
490 |
if (signal(SIGTERM, SIG_DFL) == SIG_ERR) {
|
|
|
491 |
LOGERR(("ExecCmd::dochild: signal() failed, errno %d\n", errno));
|
|
|
492 |
}
|
|
|
493 |
sigset_t sset;
|
|
|
494 |
sigfillset(&sset);
|
|
|
495 |
pthread_sigmask(SIG_UNBLOCK, &sset, 0);
|
|
|
496 |
sigprocmask(SIG_UNBLOCK, &sset, 0);
|
|
|
497 |
|
479 |
if (has_input) {
|
498 |
if (has_input) {
|
480 |
close(m_pipein[1]);
|
499 |
close(m_pipein[1]);
|
481 |
m_pipein[1] = -1;
|
500 |
m_pipein[1] = -1;
|
482 |
if (m_pipein[0] != 0) {
|
501 |
if (m_pipein[0] != 0) {
|
483 |
dup2(m_pipein[0], 0);
|
502 |
dup2(m_pipein[0], 0);
|