Replace direct fprintf(stderr) calls by write_stderr(), and cause this
routine to do something appropriate on Win32. Also, add a security check on Win32 that parallels the can't-run-as-root check on Unix. Magnus Hagander
This commit is contained in:
parent
b5b9e33564
commit
b15f9b08ef
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.184 2004/06/06 00:41:26 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.185 2004/06/24 21:02:24 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -328,12 +328,11 @@ BootstrapMain(int argc, char *argv[])
|
||||
{
|
||||
if (!potential_DataDir)
|
||||
{
|
||||
fprintf(stderr,
|
||||
gettext("%s does not know where to find the database system data.\n"
|
||||
"You must specify the directory that contains the database system\n"
|
||||
"either by specifying the -D invocation option or by setting the\n"
|
||||
"PGDATA environment variable.\n"),
|
||||
argv[0]);
|
||||
write_stderr("%s does not know where to find the database system data.\n"
|
||||
"You must specify the directory that contains the database system\n"
|
||||
"either by specifying the -D invocation option or by setting the\n"
|
||||
"PGDATA environment variable.\n",
|
||||
argv[0]);
|
||||
proc_exit(1);
|
||||
}
|
||||
SetDataDir(potential_DataDir);
|
||||
@ -503,15 +502,14 @@ BootstrapMain(int argc, char *argv[])
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
gettext("Usage:\n"
|
||||
write_stderr("Usage:\n"
|
||||
" postgres -boot [OPTION]... DBNAME\n"
|
||||
" -c NAME=VALUE set run-time parameter\n"
|
||||
" -d 1-5 debug level\n"
|
||||
" -D datadir data directory\n"
|
||||
" -F turn off fsync\n"
|
||||
" -o file send debug output to file\n"
|
||||
" -x num internal use\n"));
|
||||
" -x num internal use\n");
|
||||
|
||||
proc_exit(1);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.86 2004/06/03 00:07:36 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.87 2004/06/24 21:02:33 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -91,8 +91,8 @@ main(int argc, char *argv[])
|
||||
#if defined(__alpha) /* no __alpha__ ? */
|
||||
if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
|
||||
(unsigned long) NULL) < 0)
|
||||
fprintf(stderr, gettext("%s: setsysinfo failed: %s\n"),
|
||||
argv[0], strerror(errno));
|
||||
write_stderr("%s: setsysinfo failed: %s\n",
|
||||
argv[0], strerror(errno));
|
||||
#endif
|
||||
#endif /* NOFIXADE || NOPRINTADE */
|
||||
|
||||
@ -109,7 +109,7 @@ main(int argc, char *argv[])
|
||||
err = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (err != 0)
|
||||
{
|
||||
fprintf(stderr, "%s: WSAStartup failed: %d\n",
|
||||
write_stderr("%s: WSAStartup failed: %d\n",
|
||||
argv[0], err);
|
||||
exit(1);
|
||||
}
|
||||
@ -212,12 +212,10 @@ main(int argc, char *argv[])
|
||||
*/
|
||||
if (geteuid() == 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
gettext("\"root\" execution of the PostgreSQL server is not permitted.\n"
|
||||
"The server must be started under an unprivileged user ID to prevent\n"
|
||||
"possible system security compromise. See the documentation for\n"
|
||||
"more information on how to properly start the server.\n"
|
||||
));
|
||||
write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n"
|
||||
"The server must be started under an unprivileged user ID to prevent\n"
|
||||
"possible system security compromise. See the documentation for\n"
|
||||
"more information on how to properly start the server.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* !__BEOS__ */
|
||||
@ -233,9 +231,17 @@ main(int argc, char *argv[])
|
||||
*/
|
||||
if (getuid() != geteuid())
|
||||
{
|
||||
fprintf(stderr,
|
||||
gettext("%s: real and effective user IDs must match\n"),
|
||||
argv[0]);
|
||||
write_stderr("%s: real and effective user IDs must match\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
#else /* WIN32 */
|
||||
if (pgwin32_is_admin())
|
||||
{
|
||||
write_stderr("execution of PostgreSQL by a user with administrative permissions is not permitted.\n"
|
||||
"The server must be started under an unprivileged user ID to prevent\n"
|
||||
"possible system security compromise. See the documentation for\n"
|
||||
"more information on how to properly start the server.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif /* !WIN32 */
|
||||
@ -292,8 +298,8 @@ main(int argc, char *argv[])
|
||||
pw = getpwuid(geteuid());
|
||||
if (pw == NULL)
|
||||
{
|
||||
fprintf(stderr, gettext("%s: invalid effective UID: %d\n"),
|
||||
argv[0], (int) geteuid());
|
||||
write_stderr("%s: invalid effective UID: %d\n",
|
||||
argv[0], (int) geteuid());
|
||||
exit(1);
|
||||
}
|
||||
/* Allocate new memory because later getpwuid() calls can overwrite it */
|
||||
@ -305,7 +311,7 @@ main(int argc, char *argv[])
|
||||
pw_name_persist = malloc(namesize);
|
||||
if (!GetUserName(pw_name_persist, &namesize))
|
||||
{
|
||||
fprintf(stderr, gettext("%s: could not determine user name (GetUserName failed)\n"),
|
||||
write_stderr("%s: could not determine user name (GetUserName failed)\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
# $PostgreSQL: pgsql/src/backend/nls.mk,v 1.12 2004/06/10 17:10:24 petere Exp $
|
||||
# $PostgreSQL: pgsql/src/backend/nls.mk,v 1.13 2004/06/24 21:02:40 tgl Exp $
|
||||
CATALOG_NAME := postgres
|
||||
AVAIL_LANGUAGES := af cs de es hr hu it nb pt_BR ru sv tr zh_CN zh_TW
|
||||
GETTEXT_FILES := + gettext-files
|
||||
# you can add "elog:2" and "errmsg_internal" to this list if you want to
|
||||
# include internal messages in the translation list.
|
||||
GETTEXT_TRIGGERS:= errmsg errdetail errhint errcontext postmaster_error yyerror
|
||||
GETTEXT_TRIGGERS:= errmsg errdetail errhint errcontext write_stderr yyerror
|
||||
|
||||
gettext-files: distprep
|
||||
find $(srcdir)/ -name '*.c' -print >$@
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Makefile for port/win32
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $PostgreSQL: pgsql/src/backend/port/win32/Makefile,v 1.4 2004/04/12 16:19:18 momjian Exp $
|
||||
# $PostgreSQL: pgsql/src/backend/port/win32/Makefile,v 1.5 2004/06/24 21:02:42 tgl Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -12,7 +12,7 @@ subdir = src/backend/port/win32
|
||||
top_builddir = ../../../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
|
||||
OBJS = sema.o shmem.o timer.o socket.o signal.o
|
||||
OBJS = sema.o shmem.o timer.o socket.o signal.o security.o
|
||||
|
||||
all: SUBSYS.o
|
||||
|
||||
|
184
src/backend/port/win32/security.c
Normal file
184
src/backend/port/win32/security.c
Normal file
@ -0,0 +1,184 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* security.c
|
||||
* Microsoft Windows Win32 Security Support Functions
|
||||
*
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/port/win32/security.c,v 1.1 2004/06/24 21:02:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
|
||||
/*
|
||||
* Returns nonzero if the current user has administrative privileges,
|
||||
* or zero if not.
|
||||
*
|
||||
* Note: this cannot use ereport() because it's called too early during
|
||||
* startup.
|
||||
*/
|
||||
int
|
||||
pgwin32_is_admin(void)
|
||||
{
|
||||
HANDLE AccessToken;
|
||||
UCHAR InfoBuffer[1024];
|
||||
PTOKEN_GROUPS Groups = (PTOKEN_GROUPS)InfoBuffer;
|
||||
DWORD InfoBufferSize;
|
||||
PSID AdministratorsSid;
|
||||
PSID PowerUsersSid;
|
||||
SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
|
||||
UINT x;
|
||||
BOOL success;
|
||||
|
||||
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_READ,&AccessToken))
|
||||
{
|
||||
write_stderr("failed to open process token: %d\n",
|
||||
(int)GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!GetTokenInformation(AccessToken,TokenGroups,InfoBuffer,
|
||||
1024, &InfoBufferSize))
|
||||
{
|
||||
write_stderr("failed to get token information: %d\n",
|
||||
(int)GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
CloseHandle(AccessToken);
|
||||
|
||||
if(!AllocateAndInitializeSid(&NtAuthority, 2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
|
||||
0,&AdministratorsSid))
|
||||
{
|
||||
write_stderr("failed to get SID for Administrators group: %d\n",
|
||||
(int)GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!AllocateAndInitializeSid(&NtAuthority, 2,
|
||||
SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
|
||||
0, &PowerUsersSid))
|
||||
{
|
||||
write_stderr("failed to get SID for PowerUsers group: %d\n",
|
||||
(int)GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
success = FALSE;
|
||||
|
||||
for (x=0; x<Groups->GroupCount; x++)
|
||||
{
|
||||
if (EqualSid(AdministratorsSid, Groups->Groups[x].Sid) ||
|
||||
EqualSid(PowerUsersSid, Groups->Groups[x].Sid))
|
||||
{
|
||||
success = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FreeSid(AdministratorsSid);
|
||||
FreeSid(PowerUsersSid);
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* We consider ourselves running as a service if one of the following is
|
||||
* true:
|
||||
*
|
||||
* 1) We are running as Local System (only used by services)
|
||||
* 2) Our token contains SECURITY_SERVICE_RID (automatically added to the
|
||||
* process token by the SCM when starting a service)
|
||||
*
|
||||
* Return values:
|
||||
* 0 = Not service
|
||||
* 1 = Service
|
||||
* -1 = Error
|
||||
*
|
||||
* Note: we can't report errors via either ereport (we're called too early)
|
||||
* or write_stderr (because that calls this). We are therefore reduced to
|
||||
* writing directly on stderr, which sucks, but we have few alternatives.
|
||||
*/
|
||||
int
|
||||
pgwin32_is_service(void)
|
||||
{
|
||||
static int _is_service = -1;
|
||||
HANDLE AccessToken;
|
||||
UCHAR InfoBuffer[1024];
|
||||
PTOKEN_GROUPS Groups = (PTOKEN_GROUPS)InfoBuffer;
|
||||
PTOKEN_USER User = (PTOKEN_USER)InfoBuffer;
|
||||
DWORD InfoBufferSize;
|
||||
PSID ServiceSid;
|
||||
PSID LocalSystemSid;
|
||||
SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
|
||||
UINT x;
|
||||
|
||||
/* Only check the first time */
|
||||
if (_is_service != -1)
|
||||
return _is_service;
|
||||
|
||||
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_READ,&AccessToken)) {
|
||||
fprintf(stderr,"failed to open process token: %d\n",
|
||||
(int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* First check for local system */
|
||||
if (!GetTokenInformation(AccessToken,TokenUser,InfoBuffer,1024,&InfoBufferSize)) {
|
||||
fprintf(stderr,"failed to get token information: %d\n",
|
||||
(int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!AllocateAndInitializeSid(&NtAuthority,1,
|
||||
SECURITY_LOCAL_SYSTEM_RID,0,0,0,0,0,0,0,
|
||||
&LocalSystemSid)) {
|
||||
fprintf(stderr,"failed to get SID for local system account\n");
|
||||
CloseHandle(AccessToken);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (EqualSid(LocalSystemSid, User->User.Sid)) {
|
||||
FreeSid(LocalSystemSid);
|
||||
CloseHandle(AccessToken);
|
||||
_is_service = 1;
|
||||
return _is_service;
|
||||
}
|
||||
|
||||
FreeSid(LocalSystemSid);
|
||||
|
||||
/* Now check for group SID */
|
||||
if (!GetTokenInformation(AccessToken,TokenGroups,InfoBuffer,1024,&InfoBufferSize)) {
|
||||
fprintf(stderr,"failed to get token information: %d\n",
|
||||
(int)GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!AllocateAndInitializeSid(&NtAuthority,1,
|
||||
SECURITY_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0,
|
||||
&ServiceSid)) {
|
||||
fprintf(stderr,"failed to get SID for service group\n");
|
||||
CloseHandle(AccessToken);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_is_service = 0;
|
||||
for (x = 0; x < Groups->GroupCount; x++)
|
||||
{
|
||||
if (EqualSid(ServiceSid, Groups->Groups[x].Sid))
|
||||
{
|
||||
_is_service = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FreeSid(ServiceSid);
|
||||
|
||||
CloseHandle(AccessToken);
|
||||
|
||||
return _is_service;
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.3 2004/05/27 14:39:29 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/port/win32/signal.c,v 1.4 2004/06/24 21:02:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -63,18 +63,18 @@ pgwin32_signal_initialize(void)
|
||||
pgwin32_signal_event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (pgwin32_signal_event == NULL)
|
||||
ereport(FATAL,
|
||||
(errmsg_internal("Failed to create signal event: %i!",(int)GetLastError())));
|
||||
(errmsg_internal("failed to create signal event: %d", (int)GetLastError())));
|
||||
|
||||
/* Create thread for handling signals */
|
||||
signal_thread_handle = CreateThread(NULL, 0, pg_signal_thread, NULL, 0, NULL);
|
||||
if (signal_thread_handle == NULL)
|
||||
ereport(FATAL,
|
||||
(errmsg_internal("Failed to create signal handler thread!")));
|
||||
(errmsg_internal("failed to create signal handler thread")));
|
||||
|
||||
/* Create console control handle to pick up Ctrl-C etc */
|
||||
if (!SetConsoleCtrlHandler(pg_console_handler, TRUE))
|
||||
ereport(FATAL,
|
||||
(errmsg_internal("Failed to set console control handler!")));
|
||||
(errmsg_internal("failed to set console control handler")));
|
||||
}
|
||||
|
||||
|
||||
@ -209,7 +209,7 @@ pg_signal_thread(LPVOID param)
|
||||
char pipename[128];
|
||||
HANDLE pipe = INVALID_HANDLE_VALUE;
|
||||
|
||||
wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%i", GetCurrentProcessId());
|
||||
wsprintf(pipename, "\\\\.\\pipe\\pgsignal_%d", GetCurrentProcessId());
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -221,7 +221,7 @@ pg_signal_thread(LPVOID param)
|
||||
PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
|
||||
if (pipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fprintf(stderr, gettext("Failed to create signal listener pipe: %i. Retrying.\n"), (int) GetLastError());
|
||||
write_stderr("failed to create signal listener pipe: %d. Retrying.\n", (int) GetLastError());
|
||||
SleepEx(500, FALSE);
|
||||
continue;
|
||||
}
|
||||
@ -233,7 +233,8 @@ pg_signal_thread(LPVOID param)
|
||||
(LPTHREAD_START_ROUTINE) pg_signal_dispatch_thread,
|
||||
(LPVOID) pipe, 0, NULL);
|
||||
if (hThread == INVALID_HANDLE_VALUE)
|
||||
fprintf(stderr, gettext("Failed to create signal dispatch thread: %i\n"), (int) GetLastError());
|
||||
write_stderr("failed to create signal dispatch thread: %d\n",
|
||||
(int) GetLastError());
|
||||
else
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.404 2004/06/14 18:08:19 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.405 2004/06/24 21:02:55 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
@ -55,6 +55,12 @@
|
||||
* The Postmaster cleans up after backends if they have an emergency
|
||||
* exit and/or core dump.
|
||||
*
|
||||
* Error Reporting:
|
||||
* Use write_stderr() only for reporting "interactive" errors
|
||||
* (essentially, bogus arguments on the command line). Once the
|
||||
* postmaster is launched, use ereport(). In particular, don't use
|
||||
* write_stderr() for anything that occurs after pmdaemonize.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -260,10 +266,6 @@ static void SignalChildren(int signal);
|
||||
static int CountChildren(void);
|
||||
static bool CreateOptsFile(int argc, char *argv[], char *fullprogname);
|
||||
static pid_t StartChildProcess(int xlop);
|
||||
static void
|
||||
postmaster_error(const char *fmt,...)
|
||||
/* This lets gcc check the format string for consistency. */
|
||||
__attribute__((format(printf, 1, 2)));
|
||||
|
||||
#ifdef EXEC_BACKEND
|
||||
|
||||
@ -380,7 +382,7 @@ PostmasterMain(int argc, char *argv[])
|
||||
#ifdef USE_ASSERT_CHECKING
|
||||
SetConfigOption("debug_assertions", optarg, PGC_POSTMASTER, PGC_S_ARGV);
|
||||
#else
|
||||
postmaster_error("assert checking is not compiled in");
|
||||
write_stderr("%s: assert checking is not compiled in\n", progname);
|
||||
#endif
|
||||
break;
|
||||
case 'a':
|
||||
@ -503,9 +505,8 @@ PostmasterMain(int argc, char *argv[])
|
||||
}
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
gettext("Try \"%s --help\" for more information.\n"),
|
||||
progname);
|
||||
write_stderr("Try \"%s --help\" for more information.\n",
|
||||
progname);
|
||||
ExitPostmaster(1);
|
||||
}
|
||||
}
|
||||
@ -515,10 +516,10 @@ PostmasterMain(int argc, char *argv[])
|
||||
*/
|
||||
if (optind < argc)
|
||||
{
|
||||
postmaster_error("invalid argument: \"%s\"", argv[optind]);
|
||||
fprintf(stderr,
|
||||
gettext("Try \"%s --help\" for more information.\n"),
|
||||
progname);
|
||||
write_stderr("%s: invalid argument: \"%s\"\n",
|
||||
progname, argv[optind]);
|
||||
write_stderr("Try \"%s --help\" for more information.\n",
|
||||
progname);
|
||||
ExitPostmaster(1);
|
||||
}
|
||||
|
||||
@ -547,13 +548,13 @@ PostmasterMain(int argc, char *argv[])
|
||||
* for lack of buffers. The specific choices here are somewhat
|
||||
* arbitrary.
|
||||
*/
|
||||
postmaster_error("the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16");
|
||||
write_stderr("%s: the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16\n", progname);
|
||||
ExitPostmaster(1);
|
||||
}
|
||||
|
||||
if (ReservedBackends >= MaxBackends)
|
||||
{
|
||||
postmaster_error("superuser_reserved_connections must be less than max_connections");
|
||||
write_stderr("%s: superuser_reserved_connections must be less than max_connections\n", progname);
|
||||
ExitPostmaster(1);
|
||||
}
|
||||
|
||||
@ -562,7 +563,7 @@ PostmasterMain(int argc, char *argv[])
|
||||
*/
|
||||
if (!CheckDateTokenTables())
|
||||
{
|
||||
postmaster_error("invalid datetoken tables, please fix");
|
||||
write_stderr("%s: invalid datetoken tables, please fix\n", progname);
|
||||
ExitPostmaster(1);
|
||||
}
|
||||
|
||||
@ -858,12 +859,11 @@ checkDataDir(const char *checkdir)
|
||||
|
||||
if (checkdir == NULL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
gettext("%s does not know where to find the database system data.\n"
|
||||
"You must specify the directory that contains the database system\n"
|
||||
"either by specifying the -D invocation option or by setting the\n"
|
||||
"PGDATA environment variable.\n"),
|
||||
progname);
|
||||
write_stderr("%s does not know where to find the database system data.\n"
|
||||
"You must specify the directory that contains the database system\n"
|
||||
"either by specifying the -D invocation option or by setting the\n"
|
||||
"PGDATA environment variable.\n",
|
||||
progname);
|
||||
ExitPostmaster(2);
|
||||
}
|
||||
|
||||
@ -905,11 +905,10 @@ checkDataDir(const char *checkdir)
|
||||
fp = AllocateFile(path, PG_BINARY_R);
|
||||
if (fp == NULL)
|
||||
{
|
||||
fprintf(stderr,
|
||||
gettext("%s: could not find the database system\n"
|
||||
"Expected to find it in the directory \"%s\",\n"
|
||||
"but could not open file \"%s\": %s\n"),
|
||||
progname, checkdir, path, strerror(errno));
|
||||
write_stderr("%s: could not find the database system\n"
|
||||
"Expected to find it in the directory \"%s\",\n"
|
||||
"but could not open file \"%s\": %s\n",
|
||||
progname, checkdir, path, strerror(errno));
|
||||
ExitPostmaster(2);
|
||||
}
|
||||
FreeFile(fp);
|
||||
@ -952,8 +951,8 @@ pmdaemonize(void)
|
||||
pid = fork();
|
||||
if (pid == (pid_t) -1)
|
||||
{
|
||||
postmaster_error("could not fork background process: %s",
|
||||
strerror(errno));
|
||||
write_stderr("%s: could not fork background process: %s\n",
|
||||
progname, strerror(errno));
|
||||
ExitPostmaster(1);
|
||||
}
|
||||
else if (pid)
|
||||
@ -974,8 +973,8 @@ pmdaemonize(void)
|
||||
#ifdef HAVE_SETSID
|
||||
if (setsid() < 0)
|
||||
{
|
||||
postmaster_error("could not dissociate from controlling TTY: %s",
|
||||
strerror(errno));
|
||||
write_stderr("%s: could not dissociate from controlling TTY: %s\n",
|
||||
progname, strerror(errno));
|
||||
ExitPostmaster(1);
|
||||
}
|
||||
#endif
|
||||
@ -3152,24 +3151,6 @@ CreateOptsFile(int argc, char *argv[], char *fullprogname)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* This should be used only for reporting "interactive" errors (essentially,
|
||||
* bogus arguments on the command line). Once the postmaster is launched,
|
||||
* use ereport. In particular, don't use this for anything that occurs
|
||||
* after pmdaemonize.
|
||||
*/
|
||||
static void
|
||||
postmaster_error(const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "%s: ", progname);
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, gettext(fmt), ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
#ifdef EXEC_BACKEND
|
||||
|
||||
@ -3609,7 +3590,7 @@ win32_sigchld_waiter(LPVOID param)
|
||||
if (r == WAIT_OBJECT_0)
|
||||
pg_queue_signal(SIGCHLD);
|
||||
else
|
||||
fprintf(stderr, "ERROR: failed to wait on child process handle: %d\n",
|
||||
write_stderr("ERROR: failed to wait on child process handle: %d\n",
|
||||
(int) GetLastError());
|
||||
CloseHandle(procHandle);
|
||||
return 0;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.420 2004/06/11 01:09:00 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.421 2004/06/24 21:03:08 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* this is the "main" module of the postgres backend and
|
||||
@ -2578,12 +2578,11 @@ PostgresMain(int argc, char *argv[], const char *username)
|
||||
{
|
||||
if (!potential_DataDir)
|
||||
{
|
||||
fprintf(stderr,
|
||||
gettext("%s does not know where to find the database system data.\n"
|
||||
"You must specify the directory that contains the database system\n"
|
||||
"either by specifying the -D invocation option or by setting the\n"
|
||||
"PGDATA environment variable.\n"),
|
||||
argv[0]);
|
||||
write_stderr("%s does not know where to find the database system data.\n"
|
||||
"You must specify the directory that contains the database system\n"
|
||||
"either by specifying the -D invocation option or by setting the\n"
|
||||
"PGDATA environment variable.\n",
|
||||
argv[0]);
|
||||
proc_exit(1);
|
||||
}
|
||||
SetDataDir(potential_DataDir);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/error/assert.c,v 1.26 2004/04/19 17:42:58 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/error/assert.c,v 1.27 2004/06/24 21:03:13 tgl Exp $
|
||||
*
|
||||
* NOTE
|
||||
* This should eventually work with elog()
|
||||
@ -31,10 +31,10 @@ ExceptionalCondition(char *conditionName,
|
||||
if (!PointerIsValid(conditionName)
|
||||
|| !PointerIsValid(fileName)
|
||||
|| !PointerIsValid(errorType))
|
||||
fprintf(stderr, "TRAP: ExceptionalCondition: bad arguments\n");
|
||||
write_stderr("TRAP: ExceptionalCondition: bad arguments\n");
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n",
|
||||
write_stderr("TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n",
|
||||
errorType, conditionName,
|
||||
fileName, lineNumber);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.141 2004/06/21 14:12:38 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.142 2004/06/24 21:03:13 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1765,3 +1765,37 @@ append_with_tabs(StringInfo buf, const char *str)
|
||||
appendStringInfoCharMacro(buf, '\t');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write errors to stderr (or by equal means when stderr is
|
||||
* not available). Used before ereport/elog can be used
|
||||
* safely (memory context, GUC load etc)
|
||||
*/
|
||||
void
|
||||
write_stderr(const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
fmt = gettext(fmt);
|
||||
|
||||
va_start(ap, fmt);
|
||||
#ifndef WIN32
|
||||
/* On Unix, we just fprintf to stderr */
|
||||
vfprintf(stderr, fmt, ap);
|
||||
#else
|
||||
/* On Win32, we print to stderr if running on a console, or write to
|
||||
* eventlog if running as a service */
|
||||
if (pgwin32_is_service()) /* Running as a service */
|
||||
{
|
||||
char errbuf[2048]; /* Arbitrary size? */
|
||||
|
||||
vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
|
||||
|
||||
write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
|
||||
}
|
||||
else /* Not running as service, write to stderr */
|
||||
vfprintf(stderr, fmt, ap);
|
||||
#endif
|
||||
va_end(ap);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/help_config.c,v 1.11 2004/06/02 18:09:32 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/help_config.c,v 1.12 2004/06/24 21:03:22 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -122,7 +122,7 @@ printMixedStruct(mixedStruct *structToPrint)
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "internal error: unrecognized run-time parameter type\n");
|
||||
write_stderr("internal error: unrecognized run-time parameter type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.25 2004/05/27 14:39:33 momjian Exp $ */
|
||||
/* $PostgreSQL: pgsql/src/include/port/win32.h,v 1.26 2004/06/24 21:03:33 tgl Exp $ */
|
||||
|
||||
/* undefine and redefine after #include */
|
||||
#undef mkdir
|
||||
@ -138,6 +138,10 @@ int pgwin32_recv(SOCKET s, char* buf, int len, int flags);
|
||||
int pgwin32_send(SOCKET s, char* buf, int len, int flags);
|
||||
|
||||
const char *pgwin32_socket_strerror(int err);
|
||||
|
||||
/* in backend/port/win32/security.c */
|
||||
extern int pgwin32_is_admin(void);
|
||||
extern int pgwin32_is_service(void);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.68 2004/04/05 03:02:10 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.69 2004/06/24 21:03:42 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -186,4 +186,14 @@ extern unsigned int Log_destination;
|
||||
/* Other exported functions */
|
||||
extern void DebugFileOpen(void);
|
||||
|
||||
/*
|
||||
* Write errors to stderr (or by equal means when stderr is
|
||||
* not available). Used before ereport/elog can be used
|
||||
* safely (memory context, GUC load etc)
|
||||
*/
|
||||
extern void write_stderr(const char *fmt,...)
|
||||
/* This extension allows gcc to check the format string for consistency with
|
||||
the supplied arguments. */
|
||||
__attribute__((format(printf, 1, 2)));
|
||||
|
||||
#endif /* ELOG_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user