Switch to side-by-side view

--- a/src/utils/execmd.cpp
+++ b/src/utils/execmd.cpp
@@ -173,7 +173,7 @@
 }
 
 int ExecCmd::startExec(const string &cmd, const list<string>& args,
-		  bool has_input, bool has_output)
+		       bool has_input, bool has_output)
 {
     { // Debug and logging
 	string command = cmd + " ";
@@ -255,7 +255,7 @@
     {
 	if (!m_input) return -1;
 	LOGDEB1(("ExecWriter: input m_cnt %d input length %d\n", m_cnt, 
-		m_input->length()));
+		 m_input->length()));
 	if (m_cnt >= m_input->length()) {
 	    // Fd ready for more but we got none.
 	    if (m_provide) {
@@ -266,7 +266,7 @@
 		    m_cnt = 0;
 		}
 		LOGDEB2(("ExecWriter: provide m_cnt %d input length %d\n", 
-			m_cnt, m_input->length()));
+			 m_cnt, m_input->length()));
 	    } else {
 		return 0;
 	    }
@@ -546,7 +546,7 @@
     }
 	
     // Fill up argv
-    argv[0] = path_getsimple(cmd).c_str();
+    argv[0] = cmd.c_str();
     int i = 1;
     list<string>::const_iterator it;
     for (it = args.begin(); it != args.end(); it++) {
@@ -572,6 +572,65 @@
     LOGERR(("ExecCmd::doexec: execvp(%s) failed. errno %d\n", cmd.c_str(),
 	    errno));
     _exit(127);
+}
+
+ReExec::ReExec(int argc, char *args[])
+{
+    init(argc, args);
+}
+
+void ReExec::init(int argc, char *args[])
+{
+    for (int i = 0; i < argc; i++) {
+	m_argv.push_back(args[i]);
+    }
+    m_cfd = open(".", 0);
+    char *cd = getcwd(0, 0);
+    if (cd) 
+	m_curdir = cd;
+    free(cd);
+}
+
+void ReExec::reexec()
+{
+    char *cwd;
+    cwd = getcwd(0,0);
+    FILE *fp = stdout; //fopen("/tmp/exectrace", "w");
+    if (fp) {
+	fprintf(fp, "reexec: pwd: [%s] args: ", cwd?cwd:"getcwd failed");
+	for (vector<string>::const_iterator it = m_argv.begin();
+	     it != m_argv.end(); it++) {
+	    fprintf(fp, "[%s] ", it->c_str());
+	}
+	fprintf(fp, "\n");
+    }
+    if (m_cfd < 0 || fchdir(m_cfd) < 0) {
+	if (fp) fprintf(fp, "fchdir failed, trying chdir\n");
+	if (!m_curdir.empty() && chdir(m_curdir.c_str())) {
+	    if (fp) fprintf(fp, "chdir failed too\n");
+	}
+    }
+
+    // Close all descriptors except 0,1,2
+    libclf_closefrom(3);
+
+    // Allocate arg vector (1 more for final 0)
+    typedef const char *Ccharp;
+    Ccharp *argv;
+    argv = (Ccharp *)malloc((m_argv.size()+1) * sizeof(char *));
+    if (argv == 0) {
+	LOGERR(("ExecCmd::doexec: malloc() failed. errno %d\n",	errno));
+	return;
+    }
+	
+    // Fill up argv
+    int i = 0;
+    vector<string>::const_iterator it;
+    for (it = m_argv.begin(); it != m_argv.end(); it++) {
+	argv[i++] = it->c_str();
+    }
+    argv[i] = 0;
+    execvp(m_argv[0].c_str(), (char *const*)argv);
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -593,6 +652,7 @@
 #define OPT_b	  0x4 
 #define OPT_w     0x8
 #define OPT_c     0x10
+#define OPT_r     0x20
 
 const char *data = "Une ligne de donnees\n";
 class MEAdv : public ExecCmdAdvise {
@@ -638,8 +698,9 @@
 
 static char *thisprog;
 static char usage [] =
-"trexecmd [-c] cmd [arg1 arg2 ...]\n" 
+"trexecmd [-c|-r] cmd [arg1 arg2 ...]\n" 
 " -c : test cancellation (ie: trexecmd -c sleep 1000)\n"
+" -r : test reexec\n"
 "trexecmd -w cmd : do the which thing\n"
 ;
 static void Usage(void)
@@ -648,8 +709,11 @@
     exit(1);
 }
 
-int main(int argc, char **argv)
-{
+ReExec reexec;
+
+int main(int argc, char *argv[])
+{
+    reexec.init(argc, argv);
     thisprog = argv[0];
     argc--; argv++;
 
@@ -660,8 +724,9 @@
 	    Usage();
 	while (**argv)
 	    switch (*(*argv)++) {
+	    case 'c':	op_flags |= OPT_c; break;
+	    case 'r':	op_flags |= OPT_r; break;
 	    case 'w':	op_flags |= OPT_w; break;
-	    case 'c':	op_flags |= OPT_c; break;
 	    default: Usage();	break;
 	    }
     b1: argc--; argv++;
@@ -675,10 +740,17 @@
     while (argc > 0) {
 	l.push_back(*argv++); argc--;
     }
-
     DebugLog::getdbl()->setloglevel(DEBDEB1);
     DebugLog::setfilename("stderr");
     signal(SIGPIPE, SIG_IGN);
+
+    if (op_flags & OPT_r) {
+	chdir("/");
+        argv[0] = strdup("");
+	sleep(1);
+        reexec.reexec();
+    }
+
     if (op_flags & OPT_w) {
 	string path;
 	if (ExecCmd::which(cmd, path)) {