Switch to unified view

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;