On Wed, 2006-09-27 at 14:26 -0700, Jeff Davis wrote: > When I have "unix_socket_directory" set to an alternate value, "pg_ctl - > D data -w start" times out. If I set it to default, it works fine. > > I'm using postgresql 8.1.4 on FreeBSD. > > Perhaps pg_ctl is waiting to see the socket file in /tmp/ before > reporting that postgresql successfully started? > I took a look at the source quickly (as usual, the postgres source is so easy to read I should have looked before I posted) and I found that the problem seems to be in test_postmaster_connection() in pg_ctl.c. The function checks for a non-default port, including scanning the configuration file, but does not look for a non-default socket directory. It seems reasonable to add a check to find the real socket directory before trying the connection. I have attached a patch. I wrote it very quickly, but it seems to work as I expect. Regards, Jeff Davis
diff -ru pgsql.orig/src/bin/pg_ctl/pg_ctl.c pgsql/src/bin/pg_ctl/pg_ctl.c --- pgsql.orig/src/bin/pg_ctl/pg_ctl.c 2006-09-27 14:57:20.000000000 -0700 +++ pgsql/src/bin/pg_ctl/pg_ctl.c 2006-09-27 14:58:02.000000000 -0700 @@ -387,9 +387,13 @@ bool success = false; int i; char portstr[32]; + char sockdirstr[256]; + char *loginhost; char *p; *portstr = '\0'; + *sockdirstr = '\0'; + loginhost = NULL; /* post_opts */ for (p = post_opts; *p;) @@ -443,6 +447,37 @@ } } } + if (!*sockdirstr) + { + char **optlines; + + optlines = readfile(conf_file); + if (optlines != NULL) + { + for (; *optlines != NULL; optlines++) + { + p = *optlines; + + while (isspace((unsigned char) *p)) + p++; + if (strncmp(p, "unix_socket_directory", strlen("unix_socket_directory")) != 0) + continue; + p += strlen("unix_socket_directory"); + while (isspace((unsigned char) *p)) + p++; + if (*p != '=') + continue; + p++; + while (isspace((unsigned char) *p)) + p++; + p++; /* skip first single quote */ + StrNCpy(sockdirstr, p, Min(strcspn(p, "'") + 1, + sizeof(sockdirstr))); + /* keep looking, maybe there is another */ + } + } + loginhost = sockdirstr; + } /* environment */ if (!*portstr && getenv("PGPORT") != NULL) @@ -454,7 +489,7 @@ for (i = 0; i < wait_seconds; i++) { - if ((conn = PQsetdbLogin(NULL, portstr, NULL, NULL, + if ((conn = PQsetdbLogin(loginhost, portstr, NULL, NULL, "postgres", NULL, NULL)) != NULL && (PQstatus(conn) == CONNECTION_OK || (strcmp(PQerrorMessage(conn), Only in pgsql/src/bin/pg_ctl: pg_ctl.c.orig