~ubuntu-branches/ubuntu/quantal/recoll/quantal

« back to all changes in this revision

Viewing changes to utils/execmd.cpp

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2012-03-27 12:15:51 UTC
  • mfrom: (1.3.8)
  • Revision ID: package-import@ubuntu.com-20120327121551-nmntidzpehudushy
Tags: 1.17.1-1
* New upstream release.
* Enable Python module resulting into new binary: python-recoll.
* debian/control:
  + Updated Build-Deps: libqtwebkit-dev, python-all-dev.
  + Added python-recoll binary.
  + Updated Standards-Version to 3.9.3
* debian/rules:
  + Build Python module by default.
* debian/recoll.menu, debian/python-recoll.install, debian/recoll.install:
  + Changes for new binary package.
* debian/copyright:
  + Updated to copyright-format 1.0
  + Updated upstream and Debian copyright.
  + Fixed unicode.org/copyright.html URL.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#ifndef TEST_EXECMD
18
18
#include "autoconfig.h"
19
19
 
 
20
#include <stdio.h>
20
21
#include <stdlib.h>
21
22
#include <unistd.h>
22
23
#include <sys/stat.h>
138
139
        int status;
139
140
        if (m_parent->m_pid > 0) {
140
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
143
            int ret = killpg(grp, SIGTERM);
143
144
            if (ret == 0) {
144
145
                for (int i = 0; i < 3; i++) {
173
174
}
174
175
 
175
176
int ExecCmd::startExec(const string &cmd, const list<string>& args,
176
 
                  bool has_input, bool has_output)
 
177
                       bool has_input, bool has_output)
177
178
{
178
179
    { // Debug and logging
179
180
        string command = cmd + " ";
255
256
    {
256
257
        if (!m_input) return -1;
257
258
        LOGDEB1(("ExecWriter: input m_cnt %d input length %d\n", m_cnt, 
258
 
                m_input->length()));
 
259
                 m_input->length()));
259
260
        if (m_cnt >= m_input->length()) {
260
261
            // Fd ready for more but we got none.
261
262
            if (m_provide) {
266
267
                    m_cnt = 0;
267
268
                }
268
269
                LOGDEB2(("ExecWriter: provide m_cnt %d input length %d\n", 
269
 
                        m_cnt, m_input->length()));
 
270
                         m_cnt, m_input->length()));
270
271
            } else {
271
272
                return 0;
272
273
            }
385
386
    // Normal return: deactivate cleaner, wait() will do the cleanup
386
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
395
int ExecCmd::send(const string& data)
457
461
}
458
462
 
459
463
// Wait for command status and clean up all resources.
460
 
int ExecCmd::wait(bool haderror)
 
464
int ExecCmd::wait()
461
465
{
462
466
    ExecCmdRsrc e(this);
463
467
    int status = -1;
464
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
471
            status = -1;
 
472
        }
467
473
        LOGDEB(("ExecCmd::wait: got status 0x%x\n", status));
468
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
506
// In child process. Set up pipes, environment, and exec command. 
546
579
    }
547
580
        
548
581
    // Fill up argv
549
 
    argv[0] = path_getsimple(cmd).c_str();
 
582
    argv[0] = cmd.c_str();
550
583
    int i = 1;
551
584
    list<string>::const_iterator it;
552
585
    for (it = args.begin(); it != args.end(); it++) {
574
607
    _exit(127);
575
608
}
576
609
 
 
610
ReExec::ReExec(int argc, char *args[])
 
611
{
 
612
    init(argc, args);
 
613
}
 
614
 
 
615
void ReExec::init(int argc, char *args[])
 
616
{
 
617
    for (int i = 0; i < argc; i++) {
 
618
        m_argv.push_back(args[i]);
 
619
    }
 
620
    m_cfd = open(".", 0);
 
621
    char *cd = getcwd(0, 0);
 
622
    if (cd) 
 
623
        m_curdir = cd;
 
624
    free(cd);
 
625
}
 
626
 
 
627
// Reexecute myself, as close as possible to the initial exec
 
628
void ReExec::reexec()
 
629
{
 
630
 
 
631
#if 0
 
632
    char *cwd;
 
633
    cwd = getcwd(0,0);
 
634
    FILE *fp = stdout; //fopen("/tmp/exectrace", "w");
 
635
    if (fp) {
 
636
        fprintf(fp, "reexec: pwd: [%s] args: ", cwd?cwd:"getcwd failed");
 
637
        for (vector<string>::const_iterator it = m_argv.begin();
 
638
             it != m_argv.end(); it++) {
 
639
            fprintf(fp, "[%s] ", it->c_str());
 
640
        }
 
641
        fprintf(fp, "\n");
 
642
    }
 
643
#endif
 
644
 
 
645
    // Execute the atexit funcs
 
646
    while (!m_atexitfuncs.empty()) {
 
647
        (m_atexitfuncs.top())();
 
648
        m_atexitfuncs.pop();
 
649
    }
 
650
 
 
651
    // Try to get back to the initial working directory
 
652
    if (m_cfd < 0 || fchdir(m_cfd) < 0) {
 
653
        LOGINFO(("ReExec::reexec: fchdir failed, trying chdir\n"));
 
654
        if (!m_curdir.empty() && chdir(m_curdir.c_str())) {
 
655
            LOGERR(("ReExec::reexec: chdir failed\n"));
 
656
        }
 
657
    }
 
658
 
 
659
    // Close all descriptors except 0,1,2
 
660
    libclf_closefrom(3);
 
661
 
 
662
    // Allocate arg vector (1 more for final 0)
 
663
    typedef const char *Ccharp;
 
664
    Ccharp *argv;
 
665
    argv = (Ccharp *)malloc((m_argv.size()+1) * sizeof(char *));
 
666
    if (argv == 0) {
 
667
        LOGERR(("ExecCmd::doexec: malloc() failed. errno %d\n", errno));
 
668
        return;
 
669
    }
 
670
        
 
671
    // Fill up argv
 
672
    int i = 0;
 
673
    vector<string>::const_iterator it;
 
674
    for (it = m_argv.begin(); it != m_argv.end(); it++) {
 
675
        argv[i++] = it->c_str();
 
676
    }
 
677
    argv[i] = 0;
 
678
    execvp(m_argv[0].c_str(), (char *const*)argv);
 
679
}
 
680
 
577
681
////////////////////////////////////////////////////////////////////
578
682
#else // TEST
579
683
#include <stdio.h>
593
697
#define OPT_b     0x4 
594
698
#define OPT_w     0x8
595
699
#define OPT_c     0x10
 
700
#define OPT_r     0x20
596
701
 
597
702
const char *data = "Une ligne de donnees\n";
598
703
class MEAdv : public ExecCmdAdvise {
638
743
 
639
744
static char *thisprog;
640
745
static char usage [] =
641
 
"trexecmd [-c] cmd [arg1 arg2 ...]\n" 
 
746
"trexecmd [-c|-r] cmd [arg1 arg2 ...]\n" 
642
747
" -c : test cancellation (ie: trexecmd -c sleep 1000)\n"
 
748
" -r : test reexec\n"
643
749
"trexecmd -w cmd : do the which thing\n"
644
750
;
645
751
static void Usage(void)
648
754
    exit(1);
649
755
}
650
756
 
651
 
int main(int argc, char **argv)
 
757
ReExec reexec;
 
758
 
 
759
int main(int argc, char *argv[])
652
760
{
 
761
    reexec.init(argc, argv);
653
762
    thisprog = argv[0];
654
763
    argc--; argv++;
655
764
 
660
769
            Usage();
661
770
        while (**argv)
662
771
            switch (*(*argv)++) {
 
772
            case 'c':   op_flags |= OPT_c; break;
 
773
            case 'r':   op_flags |= OPT_r; break;
663
774
            case 'w':   op_flags |= OPT_w; break;
664
 
            case 'c':   op_flags |= OPT_c; break;
665
775
            default: Usage();   break;
666
776
            }
667
777
    b1: argc--; argv++;
675
785
    while (argc > 0) {
676
786
        l.push_back(*argv++); argc--;
677
787
    }
678
 
 
679
788
    DebugLog::getdbl()->setloglevel(DEBDEB1);
680
789
    DebugLog::setfilename("stderr");
681
790
    signal(SIGPIPE, SIG_IGN);
 
791
 
 
792
    if (op_flags & OPT_r) {
 
793
        chdir("/");
 
794
        argv[0] = strdup("");
 
795
        sleep(1);
 
796
        reexec.reexec();
 
797
    }
 
798
 
682
799
    if (op_flags & OPT_w) {
683
800
        string path;
684
801
        if (ExecCmd::which(cmd, path)) {