⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pg_ctl.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
			return;		case SERVICE_CONTROL_PAUSE:			/* Win32 config reloading */			status.dwWaitHint = 5000;			kill(postmasterPID, SIGHUP);			return;			/* FIXME: These could be used to replace other signals etc */		case SERVICE_CONTROL_CONTINUE:		case SERVICE_CONTROL_INTERROGATE:		default:			break;	}}static void WINAPIpgwin32_ServiceMain(DWORD argc, LPTSTR * argv){	STARTUPINFO si;	PROCESS_INFORMATION pi;	DWORD		ret;	/* Initialize variables */	status.dwWin32ExitCode = S_OK;	status.dwCheckPoint = 0;	status.dwWaitHint = 60000;	status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;	status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;	status.dwServiceSpecificExitCode = 0;	status.dwCurrentState = SERVICE_START_PENDING;	memset(&pi, 0, sizeof(pi));	memset(&si, 0, sizeof(si));	si.cb = sizeof(si);	/* Register the control request handler */	if ((hStatus = RegisterServiceCtrlHandler(register_servicename, pgwin32_ServiceHandler)) == (SERVICE_STATUS_HANDLE) 0)		return;	if ((shutdownEvent = CreateEvent(NULL, true, false, NULL)) == NULL)		return;	/* Start the postmaster */	pgwin32_SetServiceStatus(SERVICE_START_PENDING);	if (!CreateProcess(NULL, pgwin32_CommandLine(false), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))	{		pgwin32_SetServiceStatus(SERVICE_STOPPED);		return;	}	postmasterPID = pi.dwProcessId;	postmasterProcess = pi.hProcess;	CloseHandle(pi.hThread);	pgwin32_SetServiceStatus(SERVICE_RUNNING);	/* Wait for quit... */	ret = WaitForMultipleObjects(2, shutdownHandles, FALSE, INFINITE);	pgwin32_SetServiceStatus(SERVICE_STOP_PENDING);	switch (ret)	{		case WAIT_OBJECT_0:		/* shutdown event */			kill(postmasterPID, SIGINT);			/*			 * Increment the checkpoint and try again Abort after 12			 * checkpoints as the postmaster has probably hung			 */			while (WaitForSingleObject(postmasterProcess, 5000) == WAIT_TIMEOUT && status.dwCheckPoint < 12)				status.dwCheckPoint++;			break;		case (WAIT_OBJECT_0 + 1):		/* postmaster went down */			break;		default:			/* shouldn't get here? */			break;	}	CloseHandle(shutdownEvent);	CloseHandle(postmasterProcess);	pgwin32_SetServiceStatus(SERVICE_STOPPED);}static voidpgwin32_doRunAsService(void){	SERVICE_TABLE_ENTRY st[] = {{register_servicename, pgwin32_ServiceMain},	{NULL, NULL}};	if (StartServiceCtrlDispatcher(st) == 0)	{		write_stderr(_("%s: could not start service \"%s\": error code %d\n"), progname, register_servicename, (int) GetLastError());		exit(1);	}}#endifstatic voiddo_advice(void){	write_stderr(_("Try \"%s --help\" for more information.\n"), progname);}static voiddo_help(void){	printf(_("%s is a utility to start, stop, restart, reload configuration files,\n"			 "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n\n"), progname);	printf(_("Usage:\n"));	printf(_("  %s start   [-w] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n"), progname);	printf(_("  %s stop    [-W] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"), progname);	printf(_("  %s restart [-w] [-D DATADIR] [-s] [-m SHUTDOWN-MODE] [-o \"OPTIONS\"]\n"), progname);	printf(_("  %s reload  [-D DATADIR] [-s]\n"), progname);	printf(_("  %s status  [-D DATADIR]\n"), progname);	printf(_("  %s kill    SIGNALNAME PID\n"), progname);#if defined(WIN32) || defined(__CYGWIN__)	printf(_("  %s register   [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n"			 "                    [-w] [-o \"OPTIONS\"]\n"), progname);	printf(_("  %s unregister [-N SERVICENAME]\n"), progname);#endif	printf(_("\nCommon options:\n"));	printf(_("  -D, --pgdata DATADIR   location of the database storage area\n"));	printf(_("  -s, --silent           only print errors, no informational messages\n"));	printf(_("  -w                     wait until operation completes\n"));	printf(_("  -W                     do not wait until operation completes\n"));	printf(_("  --help                 show this help, then exit\n"));	printf(_("  --version              output version information, then exit\n"));	printf(_("(The default is to wait for shutdown, but not for start or restart.)\n\n"));	printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));	printf(_("\nOptions for start or restart:\n"));	printf(_("  -l, --log FILENAME     write (or append) server log to FILENAME\n"));	printf(_("  -o OPTIONS             command line options to pass to the postmaster\n"			 "                         (PostgreSQL server executable)\n"));	printf(_("  -p PATH-TO-POSTMASTER  normally not necessary\n"));	printf(_("\nOptions for stop or restart:\n"));	printf(_("  -m SHUTDOWN-MODE   may be \"smart\", \"fast\", or \"immediate\"\n"));	printf(_("\nShutdown modes are:\n"));	printf(_("  smart       quit after all clients have disconnected\n"));	printf(_("  fast        quit directly, with proper shutdown\n"));	printf(_("  immediate   quit without complete shutdown; will lead to recovery on restart\n"));	printf(_("\nAllowed signal names for kill:\n"));	printf("  HUP INT QUIT ABRT TERM USR1 USR2\n");#if defined(WIN32) || defined(__CYGWIN__)	printf(_("\nOptions for register and unregister:\n"));	printf(_("  -N SERVICENAME  service name with which to register PostgreSQL server\n"));	printf(_("  -P PASSWORD     password of account to register PostgreSQL server\n"));	printf(_("  -U USERNAME     user name of account to register PostgreSQL server\n"));#endif	printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));}static voidset_mode(char *modeopt){	if (strcmp(modeopt, "s") == 0 || strcmp(modeopt, "smart") == 0)	{		shutdown_mode = SMART_MODE;		sig = SIGTERM;	}	else if (strcmp(modeopt, "f") == 0 || strcmp(modeopt, "fast") == 0)	{		shutdown_mode = FAST_MODE;		sig = SIGINT;	}	else if (strcmp(modeopt, "i") == 0 || strcmp(modeopt, "immediate") == 0)	{		shutdown_mode = IMMEDIATE_MODE;		sig = SIGQUIT;	}	else	{		write_stderr(_("%s: unrecognized shutdown mode \"%s\"\n"), progname, modeopt);		do_advice();		exit(1);	}}static voidset_sig(char *signame){	if (!strcmp(signame, "HUP"))		sig = SIGHUP;	else if (!strcmp(signame, "INT"))		sig = SIGINT;	else if (!strcmp(signame, "QUIT"))		sig = SIGQUIT;	else if (!strcmp(signame, "ABRT"))		sig = SIGABRT;	/*	 * probably should NOT provide SIGKILL	 *	 * else if (!strcmp(signame,"KILL")) sig = SIGKILL;	 */	else if (!strcmp(signame, "TERM"))		sig = SIGTERM;	else if (!strcmp(signame, "USR1"))		sig = SIGUSR1;	else if (!strcmp(signame, "USR2"))		sig = SIGUSR2;	else	{		write_stderr(_("%s: unrecognized signal name \"%s\"\n"), progname, signame);		do_advice();		exit(1);	}}intmain(int argc, char **argv){	static struct option long_options[] = {		{"help", no_argument, NULL, '?'},		{"version", no_argument, NULL, 'V'},		{"log", required_argument, NULL, 'l'},		{"mode", required_argument, NULL, 'm'},		{"pgdata", required_argument, NULL, 'D'},		{"silent", no_argument, NULL, 's'},		{NULL, 0, NULL, 0}	};	int			option_index;	int			c;	pgpid_t		killproc = 0;#if defined(WIN32) || defined(__CYGWIN__)	setvbuf(stderr, NULL, _IONBF, 0);#endif	progname = get_progname(argv[0]);	set_pglocale_pgservice(argv[0], "pg_ctl");	/*	 * save argv[0] so do_start() can look for the postmaster if necessary. we	 * don't look for postmaster here because in many cases we won't need it.	 */	argv0 = argv[0];	umask(077);	/* support --help and --version even if invoked as root */	if (argc > 1)	{		if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 ||			strcmp(argv[1], "-?") == 0)		{			do_help();			exit(0);		}		else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0)		{			printf("%s (PostgreSQL) %s\n", progname, PG_VERSION);			exit(0);		}	}	/*	 * Disallow running as root, to forestall any possible security holes.	 */#ifndef WIN32#ifndef __BEOS__				/* no root check on BEOS */	if (geteuid() == 0)	{		write_stderr(_("%s: cannot be run as root\n"					   "Please log in (using, e.g., \"su\") as the "					   "(unprivileged) user that will\n"					   "own the server process.\n"),					 progname);		exit(1);	}#endif#endif	/*	 * 'Action' can be before or after args so loop over both. Some	 * getopt_long() implementations will reorder argv[] to place all flags	 * first (GNU?), but we don't rely on it. Our /port version doesn't do	 * that.	 */	optind = 1;	/* process command-line options */	while (optind < argc)	{		while ((c = getopt_long(argc, argv, "D:l:m:N:o:p:P:sU:wW", long_options, &option_index)) != -1)		{			switch (c)			{				case 'D':					{						char	   *pgdata_D;						char	   *env_var = pg_malloc(strlen(optarg) + 8);						pgdata_D = xstrdup(optarg);						canonicalize_path(pgdata_D);						snprintf(env_var, strlen(optarg) + 8, "PGDATA=%s",								 pgdata_D);						putenv(env_var);						/*						 * We could pass PGDATA just in an environment						 * variable but we do -D too for clearer postmaster						 * 'ps' display						 */						pgdata_opt = pg_malloc(strlen(pgdata_D) + 7);						snprintf(pgdata_opt, strlen(pgdata_D) + 7,								 "-D \"%s\" ",								 pgdata_D);						break;					}				case 'l':					log_file = xstrdup(optarg);					break;				case 'm':					set_mode(optarg);					break;				case 'N':					register_servicename = xstrdup(optarg);					break;				case 'o':					post_opts = xstrdup(optarg);					break;				case 'p':					postgres_path = xstrdup(optarg);					break;				case 'P':					register_password = xstrdup(optarg);					break;				case 's':					silent_mode = true;					break;				case 'U':					if (strchr(optarg, '\\'))						register_username = xstrdup(optarg);					else						/* Prepend .\ for local accounts */					{						register_username = malloc(strlen(optarg) + 3);						if (!register_username)						{							write_stderr(_("%s: out of memory\n"), progname);							exit(1);						}						strcpy(register_username, ".\\");						strcat(register_username, optarg);					}					break;				case 'w':					do_wait = true;					wait_set = true;					break;				case 'W':					do_wait = false;					wait_set = true;					break;				default:					write_stderr(_("%s: invalid option %s\n"), progname, optarg);					do_advice();					exit(1);			}		}		/* Process an action */		if (optind < argc)		{			if (ctl_command != NO_COMMAND)			{				write_stderr(_("%s: too many command-line arguments (first is \"%s\")\n"), progname, argv[optind]);				do_advice();				exit(1);			}			if (strcmp(argv[optind], "start") == 0)				ctl_command = START_COMMAND;			else if (strcmp(argv[optind], "stop") == 0)				ctl_command = STOP_COMMAND;			else if (strcmp(argv[optind], "restart") == 0)				ctl_command = RESTART_COMMAND;			else if (strcmp(argv[optind], "reload") == 0)				ctl_command = RELOAD_COMMAND;			else if (strcmp(argv[optind], "status") == 0)				ctl_command = STATUS_COMMAND;			else if (strcmp(argv[optind], "kill") == 0)			{				if (argc - optind < 3)				{					write_stderr(_("%s: missing arguments for kill mode\n"), progname);					do_advice();					exit(1);				}				ctl_command = KILL_COMMAND;				set_sig(argv[++optind]);				killproc = atol(argv[++optind]);			}#if defined(WIN32) || defined(__CYGWIN__)			else if (strcmp(argv[optind], "register") == 0)				ctl_command = REGISTER_COMMAND;			else if (strcmp(argv[optind], "unregister") == 0)				ctl_command = UNREGISTER_COMMAND;			else if (strcmp(argv[optind], "runservice") == 0)				ctl_command = RUN_AS_SERVICE_COMMAND;#endif			else			{				write_stderr(_("%s: unrecognized operation mode \"%s\"\n"), progname, argv[optind]);				do_advice();				exit(1);			}			optind++;		}	}	if (ctl_command == NO_COMMAND)	{		write_stderr(_("%s: no operation specified\n"), progname);		do_advice();		exit(1);	}	/* Note we put any -D switch into the env var above */	pg_data = getenv("PGDATA");	if (pg_data)	{		pg_data = xstrdup(pg_data);		canonicalize_path(pg_data);	}	if (pg_data == NULL &&		ctl_command != KILL_COMMAND && ctl_command != UNREGISTER_COMMAND)	{		write_stderr(_("%s: no database directory specified "					   "and environment variable PGDATA unset\n"),					 progname);		do_advice();		exit(1);	}	if (!wait_set)	{		switch (ctl_command)		{			case RESTART_COMMAND:			case START_COMMAND:				do_wait = false;				break;			case STOP_COMMAND:				do_wait = true;				break;			default:				break;		}	}	if (ctl_command == RELOAD_COMMAND)	{		sig = SIGHUP;		do_wait = false;	}	if (pg_data != NULL)	{		snprintf(def_postopts_file, MAXPGPATH, "%s/postmaster.opts.default", pg_data);		snprintf(postopts_file, MAXPGPATH, "%s/postmaster.opts", pg_data);		snprintf(pid_file, MAXPGPATH, "%s/postmaster.pid", pg_data);		snprintf(conf_file, MAXPGPATH, "%s/postgresql.conf", pg_data);	}	switch (ctl_command)	{		case STATUS_COMMAND:			do_status();			break;		case START_COMMAND:			do_start();			break;		case STOP_COMMAND:			do_stop();			break;		case RESTART_COMMAND:			do_restart();			break;		case RELOAD_COMMAND:			do_reload();			break;		case KILL_COMMAND:			do_kill(killproc);			break;#if defined(WIN32) || defined(__CYGWIN__)		case REGISTER_COMMAND:			pgwin32_doRegister();			break;		case UNREGISTER_COMMAND:			pgwin32_doUnregister();			break;		case RUN_AS_SERVICE_COMMAND:			pgwin32_doRunAsService();			break;#endif		default:			break;	}	exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -