37
37
*
38
38
*
39
39
* 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 $
41
41
*
42
42
* NOTES
43
43
*
@@ -249,6 +249,7 @@ static intBackendStartup(Port *port);
249
249
static int ProcessStartupPacket (Port * port ,bool SSLdone );
250
250
static void processCancelRequest (Port * port ,void * pkt );
251
251
static int initMasks (fd_set * rmask ,fd_set * wmask );
252
+ static void report_fork_failure_to_client (Port * port ,int errnum );
252
253
enum CAC_state
253
254
{
254
255
CAC_OK ,CAC_STARTUP ,CAC_SHUTDOWN ,CAC_RECOVERY ,CAC_TOOMANY
@@ -1864,11 +1865,11 @@ BackendStartup(Port *port)
1864
1865
{
1865
1866
int status ;
1866
1867
1867
- free (bn );
1868
1868
#ifdef __BEOS__
1869
1869
/* Specific beos backend startup actions */
1870
1870
beos_backend_startup ();
1871
1871
#endif
1872
+ free (bn );
1872
1873
1873
1874
status = DoBackend (port );
1874
1875
if (status != 0 )
@@ -1883,13 +1884,16 @@ BackendStartup(Port *port)
1883
1884
/* in parent, error */
1884
1885
if (pid < 0 )
1885
1886
{
1886
- free (bn );
1887
+ int save_errno = errno ;
1888
+
1887
1889
#ifdef __BEOS__
1888
1890
/* Specific beos backend startup actions */
1889
1891
beos_backend_startup_failed ();
1890
1892
#endif
1893
+ free (bn );
1891
1894
elog (DEBUG ,"connection startup failed (fork failure): %s" ,
1892
- strerror (errno ));
1895
+ strerror (save_errno ));
1896
+ report_fork_failure_to_client (port ,save_errno );
1893
1897
return STATUS_ERROR ;
1894
1898
}
1895
1899
@@ -1910,6 +1914,40 @@ BackendStartup(Port *port)
1910
1914
}
1911
1915
1912
1916
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
+
1913
1951
/*
1914
1952
* split_opts -- split a string of options and append it to an argv array
1915
1953
*