[Slad] Re: Patch for Windows: don't use popen from stock cygwin

Jan-Oliver Wagner jan at intevation.de
Mon Feb 13 10:01:37 UTC 2006


On Mon, Feb 13, 2006 at 11:00:58AM +0100, Jan-Oliver Wagner wrote:
> attached is a patch that introduces 'our' popen implementation.

and now it is $%&$%

-- 
Jan-Oliver Wagner: www.intevation.de/~jan  | GISpatcher: www.gispatcher.de
Kolab Konsortium : www.kolab-konsortium.de | Thuban    : thuban.intevation.org
Intevation GmbH  : www.intevation.de       | Kolab     : www.kolab.org
FreeGIS          : www.freegis.org         | GAV       : www.grass-verein.de
-------------- next part --------------
Index: tools.cpp
===================================================================
RCS file: /anoncvs/sladinstaller/tools.cpp,v
retrieving revision 1.21
diff -u -3 -p -r1.21 tools.cpp
--- tools.cpp	25 Nov 2005 17:04:21 -0000	1.21
+++ tools.cpp	13 Feb 2006 09:55:21 -0000
@@ -16,9 +16,12 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
 #include <time.h>
 #include <unistd.h>
 #include <utime.h>
+#include <sstream>
 
 #define _(a) gettext (a)
 
@@ -577,6 +580,47 @@ std::string installonclient(void *ssh_se
   return ret;
 }
 
+static FILE*
+mypopen(const char * dir, char ** argv, pid_t * p_pid)
+{
+  int ret;
+  pid_t pid;
+  int thepipe[2];
+
+  if (pipe(thepipe) < 0)
+    {
+      LOG(std::string(_("\nerror creating pipes")));
+      return 0;
+    }
+
+  pid = fork();
+  if (pid == 0)
+    {
+      if (chdir(dir) < 0)
+    {
+      exit(127);
+    }
+      dup2(thepipe[1], 1);
+      dup2(thepipe[1], 2);
+      for (int i = 3 ; i < getdtablesize(); i++ ) 
+    close(i);
+      ret = execvp(argv[0], argv);
+      if (ret)
+    exit(127);
+      else
+    exit(0);
+    }
+  if ( pid < 0 )
+    {
+      LOG(std::string(_("\nerror starting subprocess ")));
+      return 0;
+    }
+
+  close(thepipe[1]);
+  *p_pid = pid;
+  return fdopen(thepipe[0], "r");
+}
+
 std::string checkpackage(const std::string& pkg)
 {
   LOG(std::string("\n")+_("check")+' '+pkg+'\n');
@@ -587,13 +631,13 @@ std::string checkpackage(const std::stri
   if(tolower(pkg[pkg.size()-3])=='b' && tolower(pkg[pkg.size()-2])=='z' && pkg[pkg.size()-1]=='2')
     tarcmd="tfj";
 
-  std::string cmd="tar ";
-  cmd+=tarcmd;
-  cmd+=' ';
-  cmd+=pkg;
-  FILE *f=popen(cmd.c_str(), "r");
+  char * cmd[] = { "tar", (char*)tarcmd.c_str(), (char *)pkg.c_str(), 0};
+  pid_t tar_pid;
+  LOG(std::string("\ntar command: ")+cmd[0]+" "+ cmd[1]+" "+ cmd[2]);
+  FILE *f=mypopen(".", cmd, &tar_pid);
   if(!f)
-    return std::string(SLAD_ERROR)+' '+_("could not execute")+": "+cmd;
+    return std::string(SLAD_ERROR) +' '+_("could not execute")+": "
+                       +cmd[0]+" "+ cmd[1]+" "+ cmd[2];
   bool ok=false;
   std::string dir;
   while(!feof(f))
@@ -617,7 +661,21 @@ std::string checkpackage(const std::stri
 	  dir=d;
 	}
     }
-  pclose(f);
+  fclose(f);
+
+  while (true)
+    {
+      int ret;
+      pid_t e = waitpid(tar_pid, &ret, 0);
+      if (e < 0 && errno == EINTR)
+        continue;
+      ret = WEXITSTATUS(ret);
+      std::ostringstream msg;
+      msg << "\ntar result " << ret;
+      if (ret != 0)
+        return std::string(SLAD_ERROR)+' '+msg.str();
+      break;
+    }
 
   if(!ok)
     return std::string(SLAD_ERROR)+' '+_("did not find slad-install.sh in")+": "+pkg;


More information about the Slad mailing list