1010 *
1111 *
1212 * IDENTIFICATION
13- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.128 1999/12/03 06:26:34 ishii Exp $
13+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.129 1999/12/04 08:23:43 ishii Exp $
1414 *
1515 * NOTES
1616 *
@@ -257,7 +257,7 @@ extern intoptind,
257257/*
258258 * postmaster.c - function prototypes
259259 */
260- static void pmdaemonize (void );
260+ static void pmdaemonize (char * extraoptions );
261261static Port * ConnCreate (int serverFd );
262262static void ConnFree (Port * port );
263263static void reset_shared (unsigned short port );
@@ -645,13 +645,13 @@ PostmasterMain(int argc, char *argv[])
645645BackendList = DLNewList ();
646646PortList = DLNewList ();
647647
648- if (silentflag )
649- pmdaemonize ();
650-
651- /*
652- * create pid file. if the file has already existed, exits.
653- */
654- if (SetPidFile (
648+ if (silentflag ) {
649+ pmdaemonize (original_extraoptions );
650+ } else {
651+ /*
652+ * create pid file. if the file has already existed, exits.
653+ */
654+ if (SetPidFile (
655655getpid (),/* postmaster process id */
656656progname ,/* postmaster executable file */
657657PostPortName ,/* port number */
@@ -670,9 +670,10 @@ PostmasterMain(int argc, char *argv[])
670670SendStop ,/* -s: send SIGSTOP */
671671original_extraoptions /* options for backend */
672672 )
673- ) {
674- ExitPostmaster (1 );
675- return 0 ;
673+ ) {
674+ ExitPostmaster (1 );
675+ return 0 ;/* not reached */
676+ }
676677}
677678
678679/*
@@ -703,12 +704,50 @@ PostmasterMain(int argc, char *argv[])
703704}
704705
705706static void
706- pmdaemonize (void )
707+ pmdaemonize (char * extraoptions )
707708{
708709int i ;
710+ pid_t pid ;
709711
710- if (fork ())
712+ pid = fork ();
713+ if (pid == -1 ) {
714+ perror ("Failed to fork postmaster" );
715+ ExitPostmaster (1 );
716+ return ;/* not reached */
717+ }else if (pid ) {/* parent */
718+ /*
719+ * create pid file. if the file has already existed, exits.
720+ */
721+ if (SetPidFile (
722+ pid ,/* postmaster process id */
723+ progname ,/* postmaster executable file */
724+ PostPortName ,/* port number */
725+ DataDir ,/* PGDATA */
726+ assert_enabled ,/* whether -A is specified or not */
727+ NBuffers ,/* -B: number of shared buffers */
728+ Execfile ,/* -b: postgres executable file */
729+ DebugLvl ,/* -d: debug level */
730+ NetServer ,/* -i: accept connection from INET */
731+ #ifdef USE_SSL
732+ SecureNetServer ,/* -l: use SSL */
733+ #endif
734+ MaxBackends ,/* -N: max number of backends */
735+ Reinit ,/* -n: reinit shared mem after failure */
736+ 1 ,/* -S: detach tty */
737+ SendStop ,/* -s: send SIGSTOP */
738+ extraoptions /* options for backend */
739+ )
740+ ) {
741+ /*
742+ * Failed to create pid file. kill the child and
743+ * exit now.
744+ */
745+ kill (pid ,SIGTERM );
746+ ExitPostmaster (1 );
747+ return ;/* not reached */
748+ }
711749_exit (0 );
750+ }
712751/* GH: If there's no setsid(), we hopefully don't need silent mode.
713752 * Until there's a better solution.
714753 */
@@ -2145,22 +2184,74 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
21452184int fd ;
21462185char optsfile [MAXPGPATH ];
21472186char pidstr [32 ];
2187+ int len ;
2188+ pid_t post_pid ;
21482189char opts [1024 ];
21492190char buf [1024 ];
21502191
21512192/*
21522193 * Creating pid file
21532194 */
2154- sprintf (PidFile ,"%s/%s" ,datadir ,PIDFNAME );
2195+ snprintf (PidFile ,sizeof ( PidFile ), "%s/%s" ,datadir ,PIDFNAME );
21552196fd = open (PidFile ,O_RDWR |O_CREAT |O_EXCL ,0600 );
21562197if (fd < 0 ) {
2157- fprintf (stderr ,"Can't create pidfile: %s\n" ,PidFile );
2158- fprintf (stderr ,"Is another postmaser running?\n" );
2159- return (-1 );
2198+ /*
2199+ * Couldn't create the pid file. Probably
2200+ * it already exists. Read the file to see if the process
2201+ * actually exists
2202+ */
2203+ fd = open (PidFile ,O_RDONLY ,0600 );
2204+ if (fd < 0 ) {
2205+ fprintf (stderr ,"Can't create/read pid file: %s\n" ,PidFile );
2206+ fprintf (stderr ,"Please check the permission and try again.\n" );
2207+ return (-1 );
2208+ }
2209+
2210+ if ((len = read (fd ,pidstr ,sizeof (pidstr )- 1 ))< 0 ) {
2211+ fprintf (stderr ,"Can't create/read pid file: %s\n" ,PidFile );
2212+ fprintf (stderr ,"Please check the permission and try again.\n" );
2213+ close (fd );
2214+ return (-1 );
2215+ }
2216+ close (fd );
2217+
2218+ /*
2219+ * Check to see if the process actually exists
2220+ */
2221+ pidstr [len ]= '\0' ;
2222+ post_pid = (pid_t )atoi (pidstr );
2223+
2224+ if (post_pid == 0 || (post_pid > 0 && kill (post_pid ,0 )< 0 )) {
2225+ /*
2226+ * No, the process did not exist. Unlink
2227+ * the file and try to create it
2228+ */
2229+ if (unlink (PidFile )< 0 ) {
2230+ fprintf (stderr ,"Can't remove pidfile: %s\n" ,PidFile );
2231+ fprintf (stderr ,"The file seems accidently left, but I couldn't remove it.\n" );
2232+ fprintf (stderr ,"Please remove the file by hand and try again.\n" );
2233+ return (-1 );
2234+ }
2235+ fd = open (PidFile ,O_RDWR |O_CREAT |O_EXCL ,0600 );
2236+ if (fd < 0 ) {
2237+ fprintf (stderr ,"Can't create pidfile: %s\n" ,PidFile );
2238+ fprintf (stderr ,"Please check the permission and try again.\n" );
2239+ return (-1 );
2240+ }
2241+ }else {
2242+ /*
2243+ * Another postmaster is running
2244+ */
2245+ fprintf (stderr ,"Can't create pidfile: %s\n" ,PidFile );
2246+ fprintf (stderr ,"Is another postmaser (pid: %s) running?\n" ,pidstr );
2247+ return (-1 );
2248+ }
21602249}
2250+
21612251sprintf (pidstr ,"%d" ,pid );
21622252if (write (fd ,pidstr ,strlen (pidstr ))!= strlen (pidstr )) {
21632253fprintf (stderr ,"Write to pid file failed\n" );
2254+ fprintf (stderr ,"Please check the permission and try again.\n" );
21642255close (fd );
21652256unlink (PidFile );
21662257return (-1 );
@@ -2170,20 +2261,20 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
21702261/*
21712262 * Creating opts file
21722263 */
2173- sprintf (optsfile ,"%s/%s" ,datadir ,OPTSFNAME );
2264+ snprintf (optsfile ,sizeof ( optsfile ), "%s/%s" ,datadir ,OPTSFNAME );
21742265fd = open (optsfile ,O_RDWR |O_TRUNC |O_CREAT ,0600 );
21752266if (fd < 0 ) {
21762267fprintf (stderr ,"Can't create optsfile:%s" ,optsfile );
21772268unlink (PidFile );
21782269return (-1 );
21792270}
2180- sprintf (opts ,"%s\n-p %d\n-D %s\n" ,progname ,port ,datadir );
2271+ snprintf (opts , sizeof ( opts ) ,"%s\n-p %d\n-D %s\n" ,progname ,port ,datadir );
21812272if (assert ) {
21822273sprintf (buf ,"-A %d\n" ,assert );
21832274strcat (opts ,buf );
21842275}
21852276
2186- sprintf (buf ,"-B %d\n-b %s\n" ,nbuf ,execfile );
2277+ snprintf (buf , sizeof ( buf ) ,"-B %d\n-b %s\n" ,nbuf ,execfile );
21872278strcat (opts ,buf );
21882279
21892280if (debuglvl ) {
@@ -2201,7 +2292,7 @@ static int SetPidFile(pid_t pid, char *progname, int port, char *datadir,
22012292}
22022293#endif
22032294
2204- sprintf (buf ,"-N %d\n" ,maxbackends );
2295+ snprintf (buf , sizeof ( buf ) ,"-N %d\n" ,maxbackends );
22052296strcat (opts ,buf );
22062297
22072298if (!reinit ) {