3737 *
3838 *
3939 * IDENTIFICATION
40- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.262 2001/12/04 16:17:48 tgl Exp $
40+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.263 2002/01/06 21:40:02 tgl Exp $
4141 *
4242 * NOTES
4343 *
@@ -249,6 +249,7 @@ static intBackendStartup(Port *port);
249249static int ProcessStartupPacket (Port * port ,bool SSLdone );
250250static void processCancelRequest (Port * port ,void * pkt );
251251static int initMasks (fd_set * rmask ,fd_set * wmask );
252+ static void report_fork_failure_to_client (Port * port ,int errnum );
252253enum CAC_state
253254{
254255CAC_OK ,CAC_STARTUP ,CAC_SHUTDOWN ,CAC_RECOVERY ,CAC_TOOMANY
@@ -1864,11 +1865,11 @@ BackendStartup(Port *port)
18641865{
18651866int status ;
18661867
1867- free (bn );
18681868#ifdef __BEOS__
18691869/* Specific beos backend startup actions */
18701870beos_backend_startup ();
18711871#endif
1872+ free (bn );
18721873
18731874status = DoBackend (port );
18741875if (status != 0 )
@@ -1883,13 +1884,16 @@ BackendStartup(Port *port)
18831884/* in parent, error */
18841885if (pid < 0 )
18851886{
1886- free (bn );
1887+ int save_errno = errno ;
1888+
18871889#ifdef __BEOS__
18881890/* Specific beos backend startup actions */
18891891beos_backend_startup_failed ();
18901892#endif
1893+ free (bn );
18911894elog (DEBUG ,"connection startup failed (fork failure): %s" ,
1892- strerror (errno ));
1895+ strerror (save_errno ));
1896+ report_fork_failure_to_client (port ,save_errno );
18931897return STATUS_ERROR ;
18941898}
18951899
@@ -1910,6 +1914,40 @@ BackendStartup(Port *port)
19101914}
19111915
19121916
1917+ /*
1918+ * Try to report backend fork() failure to client before we close the
1919+ * connection. Since we do not care to risk blocking the postmaster on
1920+ * this connection, we set the connection to non-blocking and try only once.
1921+ *
1922+ * This is grungy special-purpose code; we cannot use backend libpq since
1923+ * it's not up and running.
1924+ */
1925+ static void
1926+ report_fork_failure_to_client (Port * port ,int errnum )
1927+ {
1928+ char buffer [1000 ];
1929+ #ifdef __BEOS__
1930+ int on = 1 ;
1931+ #endif
1932+
1933+ /* Format the error message packet */
1934+ snprintf (buffer ,sizeof (buffer ),"E%s%s\n" ,
1935+ gettext ("Server process fork() failed: " ),
1936+ strerror (errnum ));
1937+
1938+ /* Set port to non-blocking. Don't do send() if this fails */
1939+ #ifdef __BEOS__
1940+ if (ioctl (port -> sock ,FIONBIO ,& on )!= 0 )
1941+ return ;
1942+ #else
1943+ if (fcntl (port -> sock ,F_SETFL ,O_NONBLOCK )< 0 )
1944+ return ;
1945+ #endif
1946+
1947+ send (port -> sock ,buffer ,strlen (buffer )+ 1 ,0 );
1948+ }
1949+
1950+
19131951/*
19141952 * split_opts -- split a string of options and append it to an argv array
19151953 *