|
a/src/utils/execmd.cpp |
|
b/src/utils/execmd.cpp |
1 |
#ifndef lint
|
1 |
#ifndef lint
|
2 |
static char rcsid[] = "@(#$Id: execmd.cpp,v 1.17 2006-04-03 09:42:47 dockes Exp $ (C) 2004 J.F.Dockes";
|
2 |
static char rcsid[] = "@(#$Id: execmd.cpp,v 1.18 2006-10-09 16:37:08 dockes Exp $ (C) 2004 J.F.Dockes";
|
3 |
#endif
|
3 |
#endif
|
4 |
/*
|
4 |
/*
|
5 |
* This program is free software; you can redistribute it and/or modify
|
5 |
* This program is free software; you can redistribute it and/or modify
|
6 |
* it under the terms of the GNU General Public License as published by
|
6 |
* it under the terms of the GNU General Public License as published by
|
7 |
* the Free Software Foundation; either version 2 of the License, or
|
7 |
* the Free Software Foundation; either version 2 of the License, or
|
|
... |
|
... |
51 |
|
51 |
|
52 |
/** A resource manager to ensure that execcmd cleans up if an exception is
|
52 |
/** A resource manager to ensure that execcmd cleans up if an exception is
|
53 |
* raised in the callback */
|
53 |
* raised in the callback */
|
54 |
class ExecCmdRsrc {
|
54 |
class ExecCmdRsrc {
|
55 |
public:
|
55 |
public:
|
|
|
56 |
// Pipe for data going to the command
|
56 |
int pipein[2];
|
57 |
int pipein[2];
|
|
|
58 |
// Pipe for data coming out
|
57 |
int pipeout[2];
|
59 |
int pipeout[2];
|
58 |
pid_t pid;
|
60 |
pid_t pid;
|
59 |
ExecCmdRsrc() {
|
61 |
ExecCmdRsrc() {
|
60 |
reset();
|
62 |
reset();
|
61 |
}
|
63 |
}
|
|
... |
|
... |
122 |
LOGERR(("ExecCmd::doexec: fork(2) failed. errno %d\n", errno));
|
124 |
LOGERR(("ExecCmd::doexec: fork(2) failed. errno %d\n", errno));
|
123 |
return -1;
|
125 |
return -1;
|
124 |
}
|
126 |
}
|
125 |
|
127 |
|
126 |
if (e.pid) {
|
128 |
if (e.pid) {
|
|
|
129 |
// Father process
|
127 |
if (input) {
|
130 |
if (input) {
|
128 |
close(e.pipein[0]);
|
131 |
close(e.pipein[0]);
|
129 |
e.pipein[0] = -1;
|
132 |
e.pipein[0] = -1;
|
|
|
133 |
fcntl(e.pipein[1], F_SETFL, O_NONBLOCK);
|
130 |
}
|
134 |
}
|
131 |
if (output) {
|
135 |
if (output) {
|
132 |
close(e.pipeout[1]);
|
136 |
close(e.pipeout[1]);
|
133 |
e.pipeout[1] = -1;
|
137 |
e.pipeout[1] = -1;
|
|
|
138 |
fcntl(e.pipeout[0], F_SETFL, O_NONBLOCK);
|
134 |
}
|
139 |
}
|
135 |
fd_set readfds, writefds;
|
|
|
136 |
struct timeval tv;
|
|
|
137 |
tv.tv_sec = 1;
|
|
|
138 |
tv.tv_usec = 0;
|
|
|
139 |
|
140 |
|
140 |
if (input || output) {
|
141 |
if (input || output) {
|
141 |
if (input)
|
|
|
142 |
fcntl(e.pipein[1], F_SETFL, O_NONBLOCK);
|
|
|
143 |
if (output)
|
|
|
144 |
fcntl(e.pipeout[0], F_SETFL, O_NONBLOCK);
|
|
|
145 |
unsigned int nwritten = 0;
|
142 |
unsigned int nwritten = 0;
|
146 |
int nfds = MAX(e.pipein[1], e.pipeout[0]) + 1;
|
143 |
int nfds = MAX(e.pipein[1], e.pipeout[0]) + 1;
|
|
|
144 |
fd_set readfds, writefds;
|
|
|
145 |
struct timeval tv;
|
|
|
146 |
tv.tv_sec = m_timeoutMs / 1000;
|
|
|
147 |
tv.tv_usec = 1000 * (m_timeoutMs % 1000);
|
147 |
for(; nfds > 0;) {
|
148 |
for(; nfds > 0;) {
|
148 |
if (m_cancelRequest)
|
149 |
if (m_cancelRequest)
|
149 |
break;
|
150 |
break;
|
150 |
|
151 |
|
151 |
FD_ZERO(&writefds);
|
152 |
FD_ZERO(&writefds);
|
|
... |
|
... |
238 |
errno));
|
239 |
errno));
|
239 |
}
|
240 |
}
|
240 |
e.pipeout[1] = -1;
|
241 |
e.pipeout[1] = -1;
|
241 |
}
|
242 |
}
|
242 |
}
|
243 |
}
|
243 |
|
244 |
// Do we need to redirect stderr ?
|
|
|
245 |
if (!m_stderrFile.empty()) {
|
|
|
246 |
int fd = open(m_stderrFile.c_str(), O_WRONLY|O_CREAT
|
|
|
247 |
#ifdef O_APPEND
|
|
|
248 |
|O_APPEND
|
|
|
249 |
#endif
|
|
|
250 |
, 0600);
|
|
|
251 |
if (fd < 0) {
|
|
|
252 |
close(2);
|
|
|
253 |
} else {
|
|
|
254 |
if (fd != 2) {
|
|
|
255 |
dup2(fd, 2);
|
|
|
256 |
}
|
|
|
257 |
lseek(2, 0, 2);
|
|
|
258 |
}
|
|
|
259 |
}
|
244 |
e.reset();
|
260 |
e.reset();
|
245 |
|
261 |
|
246 |
// Allocate arg vector (2 more for arg0 + final 0)
|
262 |
// Allocate arg vector (2 more for arg0 + final 0)
|
247 |
typedef const char *Ccharp;
|
263 |
typedef const char *Ccharp;
|
248 |
Ccharp *argv;
|
264 |
Ccharp *argv;
|
|
... |
|
... |
298 |
|
314 |
|
299 |
const char *data = "Une ligne de donnees\n";
|
315 |
const char *data = "Une ligne de donnees\n";
|
300 |
class MEAdv : public ExecCmdAdvise {
|
316 |
class MEAdv : public ExecCmdAdvise {
|
301 |
public:
|
317 |
public:
|
302 |
ExecCmd *cmd;
|
318 |
ExecCmd *cmd;
|
303 |
void newData(int) {
|
319 |
void newData(int cnt) {
|
304 |
cerr << "New Data!" << endl;
|
320 |
cerr << "newData(" << cnt << ")" << endl;
|
305 |
CancelCheck::instance().setCancel();
|
321 |
// CancelCheck::instance().setCancel();
|
306 |
CancelCheck::instance().checkCancel();
|
322 |
// CancelCheck::instance().checkCancel();
|
307 |
// cmd->setCancel();
|
323 |
// cmd->setCancel();
|
308 |
}
|
324 |
}
|
309 |
};
|
325 |
};
|
310 |
|
326 |
|
311 |
int main(int argc, const char **argv)
|
327 |
int main(int argc, const char **argv)
|
|
... |
|
... |
323 |
}
|
339 |
}
|
324 |
ExecCmd mexec;
|
340 |
ExecCmd mexec;
|
325 |
MEAdv adv;
|
341 |
MEAdv adv;
|
326 |
adv.cmd = &mexec;
|
342 |
adv.cmd = &mexec;
|
327 |
mexec.setAdvise(&adv);
|
343 |
mexec.setAdvise(&adv);
|
|
|
344 |
mexec.setTimeout(500);
|
|
|
345 |
mexec.setStderr("/tmp/trexecStderr");
|
|
|
346 |
|
328 |
string input, output;
|
347 |
string input, output;
|
329 |
input = data;
|
348 |
input = data;
|
330 |
string *ip = 0;
|
349 |
string *ip = 0;
|
331 |
//ip = &input;
|
350 |
ip = &input;
|
332 |
mexec.putenv("TESTVARIABLE1=TESTVALUE1");
|
351 |
mexec.putenv("TESTVARIABLE1=TESTVALUE1");
|
333 |
mexec.putenv("TESTVARIABLE2=TESTVALUE2");
|
352 |
mexec.putenv("TESTVARIABLE2=TESTVALUE2");
|
334 |
mexec.putenv("TESTVARIABLE3=TESTVALUE3");
|
353 |
mexec.putenv("TESTVARIABLE3=TESTVALUE3");
|
335 |
|
354 |
|
336 |
int status = -1;
|
355 |
int status = -1;
|