Switch to unified view

a/src/utils/execmd.cpp b/src/utils/execmd.cpp
...
...
15
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16
 */
16
 */
17
#ifndef TEST_EXECMD
17
#ifndef TEST_EXECMD
18
#include "autoconfig.h"
18
#include "autoconfig.h"
19
19
20
#include <stdio.h>
20
#include <stdlib.h>
21
#include <stdlib.h>
21
#include <unistd.h>
22
#include <unistd.h>
22
#include <sys/stat.h>
23
#include <sys/stat.h>
23
#include <sys/types.h>
24
#include <sys/types.h>
24
#include <sys/wait.h>
25
#include <sys/wait.h>
...
...
136
    if (m_parent->m_pipeout[1] >= 0)
137
    if (m_parent->m_pipeout[1] >= 0)
137
        close(m_parent->m_pipeout[1]);
138
        close(m_parent->m_pipeout[1]);
138
    int status;
139
    int status;
139
    if (m_parent->m_pid > 0) {
140
    if (m_parent->m_pid > 0) {
140
            pid_t grp = getpgid(m_parent->m_pid);
141
            pid_t grp = getpgid(m_parent->m_pid);
141
        LOGDEB2(("ExecCmd: killpg(%d, SIGTERM)\n", grp));
142
        LOGDEB(("ExecCmd: killpg(%d, SIGTERM)\n", grp));
142
            int ret = killpg(grp, SIGTERM);
143
            int ret = killpg(grp, SIGTERM);
143
        if (ret == 0) {
144
        if (ret == 0) {
144
        for (int i = 0; i < 3; i++) {
145
        for (int i = 0; i < 3; i++) {
145
            (void)waitpid(m_parent->m_pid, &status, WNOHANG);
146
            (void)waitpid(m_parent->m_pid, &status, WNOHANG);
146
            if (kill(m_parent->m_pid, 0) != 0)
147
            if (kill(m_parent->m_pid, 0) != 0)
...
...
383
    }
384
    }
384
385
385
    // Normal return: deactivate cleaner, wait() will do the cleanup
386
    // Normal return: deactivate cleaner, wait() will do the cleanup
386
    e.inactivate();
387
    e.inactivate();
387
388
388
    return ExecCmd::wait(ret);
389
    int ret1 = ExecCmd::wait();
390
    if (ret)
391
  return -1;
392
    return ret1;
389
}
393
}
390
394
391
int ExecCmd::send(const string& data)
395
int ExecCmd::send(const string& data)
392
{
396
{
393
    NetconCli *con = dynamic_cast<NetconCli *>(m_tocmd.getptr());
397
    NetconCli *con = dynamic_cast<NetconCli *>(m_tocmd.getptr());
...
...
455
    }
459
    }
456
    return n;
460
    return n;
457
}
461
}
458
462
459
// Wait for command status and clean up all resources.
463
// Wait for command status and clean up all resources.
460
int ExecCmd::wait(bool haderror)
464
int ExecCmd::wait()
461
{
465
{
462
    ExecCmdRsrc e(this);
466
    ExecCmdRsrc e(this);
463
    int status = -1;
467
    int status = -1;
464
    if (!m_killRequest && m_pid > 0) {
468
    if (!m_killRequest && m_pid > 0) {
465
    if (waitpid(m_pid, &status, 0) < 0) 
469
    if (waitpid(m_pid, &status, 0) < 0) {
470
      LOGERR(("ExecCmd::waitpid: returned -1 errno %d\n", errno));
466
        status = -1;
471
        status = -1;
472
  }
467
        LOGDEB(("ExecCmd::wait: got status 0x%x\n", status));
473
        LOGDEB(("ExecCmd::wait: got status 0x%x\n", status));
468
    m_pid = -1;
474
    m_pid = -1;
469
    }
475
    }
470
    return haderror ? -1 : status;
476
    // Let the ExecCmdRsrc cleanup
477
    return status;
478
}
479
480
bool ExecCmd::maybereap(int *status)
481
{
482
    ExecCmdRsrc e(this);
483
    *status = -1;
484
485
    if (m_pid <= 0) {
486
  // Already waited for ??
487
  return true;
488
    }
489
490
    pid_t pid = waitpid(m_pid, status, WNOHANG);
491
    if (pid < 0) {
492
        LOGERR(("ExecCmd::maybereap: returned -1 errno %d\n", errno));
493
  m_pid = -1;
494
  return true;
495
    } else if (pid == 0) {
496
  LOGDEB1(("ExecCmd::maybereap: not exited yet\n"));
497
  e.inactivate();
498
  return false;
499
    } else {
500
        LOGDEB(("ExecCmd::maybereap: got status 0x%x\n", status));
501
  m_pid = -1;
502
  return true;
503
    }
471
}
504
}
472
505
473
// In child process. Set up pipes, environment, and exec command. 
506
// In child process. Set up pipes, environment, and exec command. 
474
// This must not return. exit() on error.
507
// This must not return. exit() on error.
475
void ExecCmd::dochild(const string &cmd, const list<string>& args,
508
void ExecCmd::dochild(const string &cmd, const list<string>& args,
...
...
589
    if (cd) 
622
    if (cd) 
590
    m_curdir = cd;
623
    m_curdir = cd;
591
    free(cd);
624
    free(cd);
592
}
625
}
593
626
627
// Reexecute myself, as close as possible to the initial exec
594
void ReExec::reexec()
628
void ReExec::reexec()
595
{
629
{
630
631
#if 0
596
    char *cwd;
632
    char *cwd;
597
    cwd = getcwd(0,0);
633
    cwd = getcwd(0,0);
598
    FILE *fp = stdout; //fopen("/tmp/exectrace", "w");
634
    FILE *fp = stdout; //fopen("/tmp/exectrace", "w");
599
    if (fp) {
635
    if (fp) {
600
    fprintf(fp, "reexec: pwd: [%s] args: ", cwd?cwd:"getcwd failed");
636
    fprintf(fp, "reexec: pwd: [%s] args: ", cwd?cwd:"getcwd failed");
...
...
602
         it != m_argv.end(); it++) {
638
         it != m_argv.end(); it++) {
603
        fprintf(fp, "[%s] ", it->c_str());
639
        fprintf(fp, "[%s] ", it->c_str());
604
    }
640
    }
605
    fprintf(fp, "\n");
641
    fprintf(fp, "\n");
606
    }
642
    }
643
#endif
644
645
    // Try to get back to the initial working directory
607
    if (m_cfd < 0 || fchdir(m_cfd) < 0) {
646
    if (m_cfd < 0 || fchdir(m_cfd) < 0) {
608
  if (fp) fprintf(fp, "fchdir failed, trying chdir\n");
647
  LOGINFO(("ReExec::reexec: fchdir failed, trying chdir\n"));
609
    if (!m_curdir.empty() && chdir(m_curdir.c_str())) {
648
    if (!m_curdir.empty() && chdir(m_curdir.c_str())) {
610
      if (fp) fprintf(fp, "chdir failed too\n");
649
      LOGERR(("ReExec::reexec: chdir failed\n"));
611
    }
650
    }
612
    }
651
    }
613
652
614
    // Close all descriptors except 0,1,2
653
    // Close all descriptors except 0,1,2
615
    libclf_closefrom(3);
654
    libclf_closefrom(3);