7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $PostgreSQL: pgsql/src/port/exec.c,v 1.16 2004/06/10 22:26:24 momjian Exp $
10
+ * $PostgreSQL: pgsql/src/port/exec.c,v 1.17 2004/07/26 01:48:00 momjian Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -279,6 +279,128 @@ find_my_exec(const char *argv0, char *retpath)
279
279
#endif
280
280
}
281
281
282
+ /*
283
+ * The runtime librarys popen() on win32 does not work when being
284
+ * called from a service when running on windows <= 2000, because
285
+ * there is no stdin/stdout/stderr.
286
+ *
287
+ * Executing a command in a pipe and reading the first line from it
288
+ * is all we need.
289
+ */
290
+
291
+ static char * pipe_read_line (char * cmd , char * line , int maxsize )
292
+ {
293
+ #ifndef WIN32
294
+ FILE * pgver ;
295
+
296
+ /* flush output buffers in case popen does not... */
297
+ fflush (stdout );
298
+ fflush (stderr );
299
+
300
+ if ((pgver = popen (cmd , "r" )) == NULL )
301
+ return NULL ;
302
+
303
+ if (fgets (line , maxsize , pgver ) == NULL )
304
+ {
305
+ perror ("fgets failure" );
306
+ return NULL ;
307
+ }
308
+
309
+ if (pclose_check (pgver ))
310
+ return NULL ;
311
+
312
+ return line ;
313
+ #else
314
+ /* Win32 */
315
+ SECURITY_ATTRIBUTES sattr ;
316
+ HANDLE childstdoutrd , childstdoutwr , childstdoutrddup ;
317
+ PROCESS_INFORMATION pi ;
318
+ STARTUPINFO si ;
319
+ char * retval = NULL ;
320
+
321
+ sattr .nLength = sizeof (SECURITY_ATTRIBUTES );
322
+ sattr .bInheritHandle = TRUE;
323
+ sattr .lpSecurityDescriptor = NULL ;
324
+
325
+ if (!CreatePipe (& childstdoutrd , & childstdoutwr , & sattr , 0 ))
326
+ return NULL ;
327
+
328
+ if (!DuplicateHandle (GetCurrentProcess (),
329
+ childstdoutrd ,
330
+ GetCurrentProcess (),
331
+ & childstdoutrddup ,
332
+ 0 ,
333
+ FALSE,
334
+ DUPLICATE_SAME_ACCESS ))
335
+ {
336
+ CloseHandle (childstdoutrd );
337
+ CloseHandle (childstdoutwr );
338
+ return NULL ;
339
+ }
340
+
341
+ CloseHandle (childstdoutrd );
342
+
343
+ ZeroMemory (& pi ,sizeof (pi ));
344
+ ZeroMemory (& si ,sizeof (si ));
345
+ si .cb = sizeof (si );
346
+ si .dwFlags = STARTF_USESTDHANDLES ;
347
+ si .hStdError = childstdoutwr ;
348
+ si .hStdOutput = childstdoutwr ;
349
+ si .hStdInput = INVALID_HANDLE_VALUE ;
350
+
351
+ if (CreateProcess (NULL ,
352
+ cmd ,
353
+ NULL ,
354
+ NULL ,
355
+ TRUE,
356
+ 0 ,
357
+ NULL ,
358
+ NULL ,
359
+ & si ,
360
+ & pi ))
361
+ {
362
+ DWORD bytesread = 0 ;
363
+ /* Successfully started the process */
364
+
365
+ ZeroMemory (line ,maxsize );
366
+
367
+ /* Let's see if we can read */
368
+ if (WaitForSingleObject (childstdoutrddup , 10000 ) != WAIT_OBJECT_0 )
369
+ {
370
+ /* Got timeout */
371
+ CloseHandle (pi .hProcess );
372
+ CloseHandle (pi .hThread );
373
+ CloseHandle (childstdoutwr );
374
+ CloseHandle (childstdoutrddup );
375
+ return NULL ;
376
+ }
377
+
378
+
379
+ /* We try just once */
380
+ if (ReadFile (childstdoutrddup , line , maxsize , & bytesread , NULL ) &&
381
+ bytesread > 0 )
382
+ {
383
+ /* So we read some data */
384
+ retval = line ;
385
+
386
+ /* We emulate fgets() behaviour. So if there is no newline
387
+ * at the end, we add one... */
388
+ if (line [strlen (line )- 1 ] != '\n' )
389
+ strcat (line ,"\n" );
390
+ }
391
+
392
+ CloseHandle (pi .hProcess );
393
+ CloseHandle (pi .hThread );
394
+ }
395
+
396
+ CloseHandle (childstdoutwr );
397
+ CloseHandle (childstdoutrddup );
398
+
399
+ return retval ;
400
+ #endif
401
+ }
402
+
403
+
282
404
283
405
/*
284
406
* Find our binary directory, then make sure the "target" executable
@@ -290,14 +412,12 @@ find_other_exec(const char *argv0, const char *target,
290
412
{
291
413
char cmd [MAXPGPATH ];
292
414
char line [100 ];
293
- FILE * pgver ;
294
-
415
+
295
416
if (find_my_exec (argv0 , retpath ) < 0 )
296
417
return -1 ;
297
418
298
419
/* Trim off program name and keep just directory */
299
420
* last_dir_separator (retpath ) = '\0' ;
300
-
301
421
snprintf (retpath + strlen (retpath ), MAXPGPATH - strlen (retpath ),
302
422
"/%s%s" , target , EXE );
303
423
@@ -306,19 +426,9 @@ find_other_exec(const char *argv0, const char *target,
306
426
307
427
snprintf (cmd , sizeof (cmd ), "\"%s\" -V 2>%s" , retpath , DEVNULL );
308
428
309
- /* flush output buffers in case popen does not... */
310
- fflush (stdout );
311
- fflush (stderr );
312
-
313
- if ((pgver = popen (cmd , "r" )) == NULL )
314
- return -1 ;
315
-
316
- if (fgets (line , sizeof (line ), pgver ) == NULL )
317
- perror ("fgets failure" );
318
-
319
- if (pclose_check (pgver ))
429
+ if (!pipe_read_line (cmd , line , sizeof (line )))
320
430
return -1 ;
321
-
431
+
322
432
if (strcmp (line , versionstr ) != 0 )
323
433
return -2 ;
324
434
0 commit comments