[GRASS-SVN] r42668 - in grass/branches/releasebranch_6_4/lib: db/dbmi_client gis

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Jun 27 16:38:44 EDT 2010


Author: martinl
Date: 2010-06-27 20:38:44 +0000 (Sun, 27 Jun 2010)
New Revision: 42668

Modified:
   grass/branches/releasebranch_6_4/lib/db/dbmi_client/start.c
   grass/branches/releasebranch_6_4/lib/gis/spawn.c
Log:
glynn: Use G_spawn_ex() (merge r42651 from trunk)
glynn: Don't warn about not close()ing descriptors other than
std{in,out,err} on Windows (merge r40905 from trunk)


Modified: grass/branches/releasebranch_6_4/lib/db/dbmi_client/start.c
===================================================================
--- grass/branches/releasebranch_6_4/lib/db/dbmi_client/start.c	2010-06-27 20:34:30 UTC (rev 42667)
+++ grass/branches/releasebranch_6_4/lib/db/dbmi_client/start.c	2010-06-27 20:38:44 UTC (rev 42668)
@@ -22,6 +22,7 @@
 #include <fcntl.h>
 #endif
 
+#include <grass/spawn.h>
 #include <grass/dbmi.h>
 
 #define READ  0
@@ -50,12 +51,6 @@
     dbConnection connection;
     char ebuf[5];
 
-#ifdef __MINGW32__
-    int stdin_orig, stdout_orig;
-    int have_stdin, have_stdout;
-    int stdin_fd, stdout_fd;
-#endif
-
     /* Set some environment variables which are later read by driver.
      * This is necessary when application is running without GISRC file and all
      * gis variables are set by application. 
@@ -128,145 +123,40 @@
     /* run the driver as a child process and create pipes to its stdin, stdout */
 
 #ifdef __MINGW32__
-    /* create pipes (0 in array for reading, 1 for writing) */
-    /* p1 : module -> driver, p2 driver -> module */
+#define pipe(fds) _pipe(fds, 250000, _O_BINARY)
+#endif
 
-    /* I have seen problems with pipes on NT 5.1 probably related
-     * to buffer size (psize, originaly 512 bytes). 
-     * But I am not sure, some problems were fixed by bigger 
-     * buffer but others remain. 
-     * Simple test which failed on NT 5.1 worked on NT 5.2 
-     * But there are probably other factors. 
-     */
-    /* More info about pipes from MSDN:
-       - Anonymous pipes are implemented using a named pipe 
-       with a unique name.
-       - CreatePipe() - nSize :
-       ... The size is only a suggestion; the system uses 
-       the value to calculate an appropriate buffering 
-       mechanism. ...
-       => that that the size specified is not significant 
-       - If the pipe buffer is full before all bytes are written, 
-       WriteFile does not return until another process or thread 
-       uses ReadFile to make more buffer space available.
-       (Which does not seem to be true on NT 5.1)
-     */
-    if (_pipe(p1, 250000, _O_BINARY) < 0 || _pipe(p2, 250000, _O_BINARY) < 0) {
+    /* open the pipes */
+    if ((pipe(p1) < 0) || (pipe(p2) < 0)) {
 	db_syserror("can't open any pipes");
 	return (dbDriver *) NULL;
     }
 
-    /* convert pipes to FILE* */
-    driver->send = fdopen(p1[WRITE], "wb");
-    driver->recv = fdopen(p2[READ], "rb");
+    pid = G_spawn_ex(startup,
+		     SF_BACKGROUND,
+		     SF_REDIRECT_DESCRIPTOR, 0, p1[READ],
+		     SF_CLOSE_DESCRIPTOR, p1[WRITE],
+		     SF_REDIRECT_DESCRIPTOR, 1, p2[WRITE],
+		     SF_CLOSE_DESCRIPTOR, p2[READ],
+		     startup, NULL);
 
-    fflush(stdout);
-    fflush(stderr);
-
-    /* Set pipes for stdin/stdout driver */
-
-    have_stdin = have_stdout = 1;
-
-    if (_fileno(stdin) < 0) {
-	have_stdin = 0;
-	stdin_fd = 0;
-    }
-    else {
-	stdin_fd = _fileno(stdin);
-
-	if ((stdin_orig = _dup(_fileno(stdin))) < 0) {
-	    db_syserror("can't duplicate stdin");
-	    return (dbDriver *) NULL;
-	}
-
-    }
-
-    if (_dup2(p1[0], stdin_fd) != 0) {
-	db_syserror("can't duplicate pipe");
+    /* create a child */
+    if (pid < 0) {
+	db_syserror("can't create fork");
 	return (dbDriver *) NULL;
     }
 
-    if (_fileno(stdout) < 0) {
-	have_stdout = 0;
-	stdout_fd = 1;
-    }
-    else {
-	stdout_fd = _fileno(stdout);
+    close(p1[READ]);
+    close(p2[WRITE]);
 
-	if ((stdout_orig = _dup(_fileno(stdout))) < 0) {
-	    db_syserror("can't duplicate stdout");
-	    return (dbDriver *) NULL;
-	}
-
-    }
-
-    if (_dup2(p2[1], stdout_fd) != 0) {
-	db_syserror("can't duplicate pipe");
-	return (dbDriver *) NULL;
-    }
-
-    /* Warning: the driver on Windows must have extension .exe
-     *          otherwise _spawnl fails. The name used as _spawnl 
-     *          parameter can be without .exe 
-     */
-    /* spawnl() works but the process inherits all handlers, 
-     * that means, for example p1[WRITE] remains open and if 
-     * module exits the pipe is not close and driver remains running. 
-     * Using CreateProcess() + SetHandleInformation() does not help.
-     * => currently the only know solution is to close all file 
-     *    descriptors in driver (which is another problem)
-     */
-
-    G_debug(2, "dbmi_client/start startup: [%s]", startup);
-    pid = _spawnl(_P_NOWAIT, startup, startup, NULL);
-
-    /* This does not help. It runs but pipe remains open when close() is 
-     * called in model but caling close() on that descriptor in driver gives 
-     * error. */
-    /* 
-       {
-       STARTUPINFO    si;
-       PROCESS_INFORMATION  pi;
-
-       GetStartupInfo(&si);
-
-       SetHandleInformation ( stdin, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
-       SetHandleInformation ( stdout, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
-       SetHandleInformation ( driver->send, HANDLE_FLAG_INHERIT, 0);
-       SetHandleInformation ( driver->recv, HANDLE_FLAG_INHERIT, 0);
-
-       CreateProcess(NULL, startup, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
-       }
-     */
-
-    /* Reset stdin/stdout for module and close duplicates */
-    if (have_stdin) {
-	if (_dup2(stdin_orig, _fileno(stdin)) != 0) {
-	    db_syserror("can't reset stdin");
-	    return (dbDriver *) NULL;
-	}
-	close(stdin_orig);
-    }
-
-
-    if (have_stdout) {
-	if (_dup2(stdout_orig, _fileno(stdout)) != 0) {
-	    db_syserror("can't reset stdout");
-	    return (dbDriver *) NULL;
-	}
-	close(stdout_orig);
-    }
-
-    if (pid == -1) {
-	db_syserror("can't _spawnl");
-	return (dbDriver *) NULL;
-    }
-
     /* record driver process id in driver struct */
     driver->pid = pid;
 
-    /* most systems will have to use unbuffered io to get the 
-     *  send/recv to work */
+    /* convert pipes to FILE* */
+    driver->send = fdopen(p1[WRITE], "wb");
+    driver->recv = fdopen(p2[READ], "rb");
+
+    /* most systems will have to use unbuffered io to get the send/recv to work */
 #ifndef USE_BUFFERED_IO
     setbuf(driver->send, NULL);
     setbuf(driver->recv, NULL);
@@ -277,67 +167,4 @@
 	driver = NULL;
 
     return driver;
-
-#else /* __MINGW32__ */
-
-    /* open the pipes */
-    if ((pipe(p1) < 0) || (pipe(p2) < 0)) {
-	db_syserror("can't open any pipes");
-	return (dbDriver *) NULL;
-    }
-
-    /* create a child */
-    if ((pid = fork()) < 0) {
-	db_syserror("can't create fork");
-	return (dbDriver *) NULL;
-    }
-
-    if (pid > 0) {		/* parent */
-	close(p1[READ]);
-	close(p2[WRITE]);
-
-	/* record driver process id in driver struct */
-	driver->pid = pid;
-
-	/* convert pipes to FILE* */
-	driver->send = fdopen(p1[WRITE], "wb");
-	driver->recv = fdopen(p2[READ], "rb");
-
-	/* most systems will have to use unbuffered io to get the send/recv to work */
-#ifndef USE_BUFFERED_IO
-	setbuf(driver->send, NULL);
-	setbuf(driver->recv, NULL);
-#endif
-
-	db__set_protocol_fds(driver->send, driver->recv);
-	if (db__recv_return_code(&stat) != DB_OK || stat != DB_OK)
-	    driver = NULL;
-
-	return driver;
-    }
-    else {			/* child process */
-
-	close(p1[WRITE]);
-	close(p2[READ]);
-
-	close(0);
-	close(1);
-
-	if (dup(p1[READ]) != 0) {
-	    db_syserror("dup r");
-	    _exit(EXIT_FAILURE);
-	}
-
-	if (dup(p2[WRITE]) != 1) {
-	    db_syserror("dup w");
-	    _exit(EXIT_FAILURE);
-	}
-
-	execl(startup, startup, NULL);
-
-	db_syserror("execl");
-	return NULL;		/* to keep lint, et. al. happy */
-    }
-
-#endif /* __MINGW32__ */
 }

Modified: grass/branches/releasebranch_6_4/lib/gis/spawn.c
===================================================================
--- grass/branches/releasebranch_6_4/lib/gis/spawn.c	2010-06-27 20:34:30 UTC (rev 42667)
+++ grass/branches/releasebranch_6_4/lib/gis/spawn.c	2010-06-27 20:38:44 UTC (rev 42668)
@@ -407,7 +407,8 @@
 	struct redirect *r = &redirects[i];
 
 	if (r->dst_fd < 0 || r->dst_fd > 2) {
-	    G_warning(_("G_spawn: unable to redirect descriptor %d"), r->dst_fd);
+	    if (r->file || r->src_fd >= 0)
+		G_warning(_("G_spawn: unable to redirect descriptor %d"), r->dst_fd);
 	    continue;
 	}
 



More information about the grass-commit mailing list