[GRASS-SVN] r42651 - grass/trunk/lib/db/dbmi_client
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Jun 23 16:27:01 EDT 2010
Author: glynn
Date: 2010-06-23 20:27:01 +0000 (Wed, 23 Jun 2010)
New Revision: 42651
Modified:
grass/trunk/lib/db/dbmi_client/start.c
Log:
Use G_spawn_ex()
Modified: grass/trunk/lib/db/dbmi_client/start.c
===================================================================
--- grass/trunk/lib/db/dbmi_client/start.c 2010-06-23 17:46:05 UTC (rev 42650)
+++ grass/trunk/lib/db/dbmi_client/start.c 2010-06-23 20:27:01 UTC (rev 42651)
@@ -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 /* not __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__ */
}
More information about the grass-commit
mailing list