|
a/src/utils/execmd.cpp |
|
b/src/utils/execmd.cpp |
|
... |
|
... |
311 |
string *m_output;
|
311 |
string *m_output;
|
312 |
ExecCmdAdvise *m_advise;
|
312 |
ExecCmdAdvise *m_advise;
|
313 |
};
|
313 |
};
|
314 |
|
314 |
|
315 |
|
315 |
|
316 |
// The netcon selectloop that doexec() uses for reading/writing would
|
|
|
317 |
// be complicated to render thread-safe. Use locking to ensure only
|
|
|
318 |
// one thread in there
|
|
|
319 |
static PTMutexInit o_lock;
|
|
|
320 |
|
|
|
321 |
int ExecCmd::doexec(const string &cmd, const list<string>& args,
|
316 |
int ExecCmd::doexec(const string &cmd, const list<string>& args,
|
322 |
const string *input, string *output)
|
317 |
const string *input, string *output)
|
323 |
{
|
318 |
{
|
324 |
// Only one thread allowed in here...
|
|
|
325 |
PTMutexLocker locker(o_lock);
|
|
|
326 |
|
319 |
|
327 |
if (startExec(cmd, args, input != 0, output != 0) < 0) {
|
320 |
if (startExec(cmd, args, input != 0, output != 0) < 0) {
|
328 |
return -1;
|
321 |
return -1;
|
329 |
}
|
322 |
}
|
330 |
|
323 |
|
331 |
// Cleanup in case we return early
|
324 |
// Cleanup in case we return early
|
332 |
ExecCmdRsrc e(this);
|
325 |
ExecCmdRsrc e(this);
|
333 |
|
326 |
SelectLoop myloop;
|
334 |
int ret = 0;
|
327 |
int ret = 0;
|
335 |
if (input || output) {
|
328 |
if (input || output) {
|
336 |
// Setup output
|
329 |
// Setup output
|
337 |
if (output) {
|
330 |
if (output) {
|
338 |
NetconCli *oclicon = dynamic_cast<NetconCli *>(m_fromcmd.getptr());
|
331 |
NetconCli *oclicon = dynamic_cast<NetconCli *>(m_fromcmd.getptr());
|
|
... |
|
... |
340 |
LOGERR(("ExecCmd::doexec: no connection from command\n"));
|
333 |
LOGERR(("ExecCmd::doexec: no connection from command\n"));
|
341 |
return -1;
|
334 |
return -1;
|
342 |
}
|
335 |
}
|
343 |
oclicon->setcallback(RefCntr<NetconWorker>
|
336 |
oclicon->setcallback(RefCntr<NetconWorker>
|
344 |
(new ExecReader(output, m_advise)));
|
337 |
(new ExecReader(output, m_advise)));
|
345 |
Netcon::addselcon(m_fromcmd, Netcon::NETCONPOLL_READ);
|
338 |
myloop.addselcon(m_fromcmd, Netcon::NETCONPOLL_READ);
|
346 |
// Give up ownership
|
339 |
// Give up ownership
|
347 |
m_fromcmd.release();
|
340 |
m_fromcmd.release();
|
348 |
}
|
341 |
}
|
349 |
// Setup input
|
342 |
// Setup input
|
350 |
if (input) {
|
343 |
if (input) {
|
|
... |
|
... |
353 |
LOGERR(("ExecCmd::doexec: no connection from command\n"));
|
346 |
LOGERR(("ExecCmd::doexec: no connection from command\n"));
|
354 |
return -1;
|
347 |
return -1;
|
355 |
}
|
348 |
}
|
356 |
iclicon->setcallback(RefCntr<NetconWorker>
|
349 |
iclicon->setcallback(RefCntr<NetconWorker>
|
357 |
(new ExecWriter(input, m_provide)));
|
350 |
(new ExecWriter(input, m_provide)));
|
358 |
Netcon::addselcon(m_tocmd, Netcon::NETCONPOLL_WRITE);
|
351 |
myloop.addselcon(m_tocmd, Netcon::NETCONPOLL_WRITE);
|
359 |
// Give up ownership
|
352 |
// Give up ownership
|
360 |
m_tocmd.release();
|
353 |
m_tocmd.release();
|
361 |
}
|
354 |
}
|
362 |
|
355 |
|
363 |
// Do the actual reading/writing/waiting
|
356 |
// Do the actual reading/writing/waiting
|
364 |
Netcon::setperiodichandler(0, 0, m_timeoutMs);
|
357 |
myloop.setperiodichandler(0, 0, m_timeoutMs);
|
365 |
while ((ret = Netcon::selectloop()) > 0) {
|
358 |
while ((ret = myloop.doLoop()) > 0) {
|
366 |
LOGDEB(("ExecCmd::doexec: selectloop returned %d\n", ret));
|
359 |
LOGDEB(("ExecCmd::doexec: selectloop returned %d\n", ret));
|
367 |
if (m_advise)
|
360 |
if (m_advise)
|
368 |
m_advise->newData(0);
|
361 |
m_advise->newData(0);
|
369 |
if (m_killRequest) {
|
362 |
if (m_killRequest) {
|
370 |
LOGINFO(("ExecCmd::doexec: cancel request\n"));
|
363 |
LOGINFO(("ExecCmd::doexec: cancel request\n"));
|