42
42
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
43
43
* Portions Copyright (c) 1994, Regents of the University of California
44
44
*
45
- * $Header: /cvsroot/pgsql/src/bin/initdb/initdb.c,v 1.9 2003/11/14 17:30:41 tgl Exp $
45
+ * $Header: /cvsroot/pgsql/src/bin/initdb/initdb.c,v 1.10 2003/11/14 18:32:34 tgl Exp $
46
46
*
47
47
*-------------------------------------------------------------------------
48
48
*/
51
51
52
52
#include <dirent.h>
53
53
#include <sys/stat.h>
54
+ #include <sys/wait.h>
54
55
#include <unistd.h>
55
56
#include <locale.h>
56
57
#include <signal.h>
@@ -112,8 +113,10 @@ char *system_views_file;
112
113
char * effective_user ;
113
114
bool testpath = true;
114
115
bool made_new_pgdata = false;
116
+ bool found_existing_pgdata = false;
115
117
char infoversion [100 ];
116
- bool not_ok = false;
118
+ bool caught_signal = false;
119
+ bool output_failed = false;
117
120
118
121
/* defaults */
119
122
int n_connections = 10 ;
@@ -159,6 +162,7 @@ static char *expanded_path(char *);
159
162
#endif
160
163
static char * * readfile (char * );
161
164
static void writefile (char * , char * * );
165
+ static void pclose_check (FILE * stream );
162
166
static char * get_id (void );
163
167
static char * get_encoding_id (char * );
164
168
static char * get_short_version (void );
@@ -206,22 +210,20 @@ static void *xmalloc(size_t);
206
210
do { \
207
211
fflush(stdout); \
208
212
fflush(stderr); \
209
- pg = popen(cmd, PG_BINARY_W ); \
213
+ pg = popen(cmd, "w" ); \
210
214
if (pg == NULL) \
211
215
exit_nicely(); \
212
216
} while (0)
213
217
214
218
#define PG_CMD_CLOSE \
215
219
do { \
216
- if ((pclose(pg) >> 8) & 0xff) \
217
- exit_nicely(); \
220
+ pclose_check(pg); \
218
221
} while (0)
219
222
220
223
#define PG_CMD_PUTLINE \
221
224
do { \
222
- if (fputs(*line, pg) < 0) \
223
- exit_nicely(); \
224
- fflush(pg); \
225
+ if (fputs(*line, pg) < 0 || fflush(pg) < 0) \
226
+ output_failed = true; \
225
227
} while (0)
226
228
227
229
#ifndef WIN32
@@ -460,6 +462,41 @@ writefile(char *path, char **lines)
460
462
exit_nicely ();
461
463
}
462
464
465
+ /* pclose() plus useful error reporting */
466
+ static void
467
+ pclose_check (FILE * stream )
468
+ {
469
+ int exitstatus ;
470
+
471
+ exitstatus = pclose (stream );
472
+
473
+ if (exitstatus == 0 )
474
+ return ; /* all is well */
475
+
476
+ if (exitstatus == -1 )
477
+ {
478
+ /* pclose() itself failed, and hopefully set errno */
479
+ perror ("pclose failed" );
480
+ }
481
+ else if (WIFEXITED (exitstatus ))
482
+ {
483
+ fprintf (stderr , "child process exited with exit code %d\n" ,
484
+ WEXITSTATUS (exitstatus ));
485
+ }
486
+ else if (WIFSIGNALED (exitstatus ))
487
+ {
488
+ fprintf (stderr , "child process was terminated by signal %d\n" ,
489
+ WTERMSIG (exitstatus ));
490
+ }
491
+ else
492
+ {
493
+ fprintf (stderr , "child process exited with unexpected status %d\n" ,
494
+ exitstatus );
495
+ }
496
+
497
+ exit_nicely ();
498
+ }
499
+
463
500
/* source stolen from FreeBSD /src/bin/mkdir/mkdir.c and adapted */
464
501
465
502
/*
@@ -585,21 +622,24 @@ exit_nicely(void)
585
622
if (!rmtree (pg_data , true))
586
623
fprintf (stderr , "%s: failed\n" , progname );
587
624
}
588
- else
625
+ else if ( found_existing_pgdata )
589
626
{
590
627
fprintf (stderr ,
591
628
"%s: removing contents of data directory \"%s\"\n" ,
592
629
progname , pg_data );
593
630
if (!rmtree (pg_data , false))
594
631
fprintf (stderr , "%s: failed\n" , progname );
595
632
}
633
+ /* otherwise died during startup, do nothing! */
596
634
}
597
635
else
598
636
{
599
- fprintf (stderr ,
600
- "%s: data directory \"%s\" not removed at user's request\n" ,
601
- progname , pg_data );
637
+ if (made_new_pgdata || found_existing_pgdata )
638
+ fprintf (stderr ,
639
+ "%s: data directory \"%s\" not removed at user's request\n" ,
640
+ progname , pg_data );
602
641
}
642
+
603
643
exit (1 );
604
644
}
605
645
@@ -874,7 +914,7 @@ find_postgres(char *path)
874
914
if (fgets (line , sizeof (line ), pgver ) == NULL )
875
915
perror ("fgets failure" );
876
916
877
- pclose (pgver );
917
+ pclose_check (pgver );
878
918
879
919
if (strcmp (line , PG_VERSIONSTR ) != 0 )
880
920
return FIND_WRONG_VERSION ;
@@ -1839,7 +1879,7 @@ trapsig(int signum)
1839
1879
{
1840
1880
/* handle systems that reset the handler, like Windows (grr) */
1841
1881
pqsignal (signum , trapsig );
1842
- not_ok = true;
1882
+ caught_signal = true;
1843
1883
}
1844
1884
1845
1885
/*
@@ -1848,14 +1888,19 @@ trapsig(int signum)
1848
1888
static void
1849
1889
check_ok ()
1850
1890
{
1851
- if (not_ok )
1891
+ if (caught_signal )
1892
+ {
1893
+ printf ("caught signal\n" );
1894
+ exit_nicely ();
1895
+ }
1896
+ else if (output_failed )
1852
1897
{
1853
- printf ("Caught Signal. \n" );
1898
+ printf ("failed to write to child process \n" );
1854
1899
exit_nicely ();
1855
1900
}
1856
1901
else
1857
1902
{
1858
- /* no signal caught */
1903
+ /* all seems well */
1859
1904
printf ("ok\n" );
1860
1905
}
1861
1906
}
@@ -2329,6 +2374,11 @@ main(int argc, char *argv[])
2329
2374
pqsignal (SIGTERM , trapsig );
2330
2375
#endif
2331
2376
2377
+ /* Ignore SIGPIPE when writing to backend, so we can clean up */
2378
+ #ifdef SIGPIPE
2379
+ pqsignal (SIGPIPE , SIG_IGN );
2380
+ #endif
2381
+
2332
2382
switch (check_data_dir ())
2333
2383
{
2334
2384
case 0 :
@@ -2354,11 +2404,12 @@ main(int argc, char *argv[])
2354
2404
if (chmod (pg_data , 0700 ) != 0 )
2355
2405
{
2356
2406
perror (pg_data );
2357
- /* don't exit_nicely(), it'll try to remove pg_data contents */
2358
- exit (1 );
2407
+ exit_nicely ();
2359
2408
}
2360
2409
else
2361
2410
check_ok ();
2411
+
2412
+ found_existing_pgdata = true;
2362
2413
break ;
2363
2414
2364
2415
case 2 :
@@ -2369,14 +2420,12 @@ main(int argc, char *argv[])
2369
2420
"the directory \"%s\" or run %s\n"
2370
2421
"with an argument other than \"%s\".\n" ,
2371
2422
progname , pg_data , pg_data , progname , pg_data );
2372
- /* don't exit_nicely(), it'll try to remove pg_data contents */
2373
- exit (1 );
2423
+ exit (1 ); /* no further message needed */
2374
2424
2375
2425
default :
2376
2426
/* Trouble accessing directory */
2377
2427
perror (pg_data );
2378
- /* don't exit_nicely(), it'll try to remove pg_data contents */
2379
- exit (1 );
2428
+ exit_nicely ();
2380
2429
}
2381
2430
2382
2431
/* Create required subdirectories */
0 commit comments