|
a/src/utils/execmd.cpp |
|
b/src/utils/execmd.cpp |
|
... |
|
... |
313 |
private:
|
313 |
private:
|
314 |
string *m_output;
|
314 |
string *m_output;
|
315 |
ExecCmdAdvise *m_advise;
|
315 |
ExecCmdAdvise *m_advise;
|
316 |
};
|
316 |
};
|
317 |
|
317 |
|
|
|
318 |
|
|
|
319 |
// The netcon selectloop that doexec() uses for reading/writing would
|
|
|
320 |
// be complicated to render thread-safe. Use locking to ensure only
|
|
|
321 |
// one thread in there
|
|
|
322 |
class ExecLocking {
|
|
|
323 |
public:
|
|
|
324 |
pthread_mutex_t m_mutex;
|
|
|
325 |
ExecLocking()
|
|
|
326 |
{
|
|
|
327 |
pthread_mutex_init(&m_mutex, 0);
|
|
|
328 |
}
|
|
|
329 |
};
|
|
|
330 |
ExecLocking o_lock;
|
|
|
331 |
class ExecLocker {
|
|
|
332 |
public:
|
|
|
333 |
ExecLocker()
|
|
|
334 |
{
|
|
|
335 |
pthread_mutex_lock(&o_lock.m_mutex);
|
|
|
336 |
}
|
|
|
337 |
~ExecLocker()
|
|
|
338 |
{
|
|
|
339 |
pthread_mutex_unlock(&o_lock.m_mutex);
|
|
|
340 |
}
|
|
|
341 |
};
|
|
|
342 |
|
318 |
int ExecCmd::doexec(const string &cmd, const list<string>& args,
|
343 |
int ExecCmd::doexec(const string &cmd, const list<string>& args,
|
319 |
const string *input, string *output)
|
344 |
const string *input, string *output)
|
320 |
{
|
345 |
{
|
321 |
if (startExec(cmd, args, input != 0, output != 0) < 0) {
|
346 |
if (startExec(cmd, args, input != 0, output != 0) < 0) {
|
322 |
return -1;
|
347 |
return -1;
|
323 |
}
|
348 |
}
|
324 |
|
349 |
|
325 |
// Cleanup in case we return early
|
350 |
// Cleanup in case we return early
|
326 |
ExecCmdRsrc e(this);
|
351 |
ExecCmdRsrc e(this);
|
|
|
352 |
// Only one thread allowed in here...
|
|
|
353 |
ExecLocker locker;
|
327 |
|
354 |
|
328 |
int ret = 0;
|
355 |
int ret = 0;
|
329 |
if (input || output) {
|
356 |
if (input || output) {
|
330 |
// Setup output
|
357 |
// Setup output
|
331 |
if (output) {
|
358 |
if (output) {
|