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

📄 syslogger.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef EXEC_BACKEND	switch ((sysloggerPid = syslogger_forkexec()))#else	switch ((sysloggerPid = fork_process()))#endif	{		case -1:			ereport(LOG,					(errmsg("could not fork system logger: %m")));			return 0;#ifndef EXEC_BACKEND		case 0:			/* in postmaster child ... */			/* Close the postmaster's sockets */			ClosePostmasterPorts(true);			/* Drop our connection to postmaster's shared memory, as well */			PGSharedMemoryDetach();			/* do the work */			SysLoggerMain(0, NULL);			break;#endif		default:			/* success, in postmaster */			/* now we redirect stderr, if not done already */			if (!redirection_done)			{#ifndef WIN32				fflush(stdout);				if (dup2(syslogPipe[1], fileno(stdout)) < 0)					ereport(FATAL,							(errcode_for_file_access(),							 errmsg("could not redirect stdout: %m")));				fflush(stderr);				if (dup2(syslogPipe[1], fileno(stderr)) < 0)					ereport(FATAL,							(errcode_for_file_access(),							 errmsg("could not redirect stderr: %m")));				/* Now we are done with the write end of the pipe. */				close(syslogPipe[1]);				syslogPipe[1] = -1;#else				int			fd;				fflush(stderr);				fd = _open_osfhandle((long) syslogPipe[1],									 _O_APPEND | _O_TEXT);				if (dup2(fd, _fileno(stderr)) < 0)					ereport(FATAL,							(errcode_for_file_access(),							 errmsg("could not redirect stderr: %m")));				close(fd);				/* Now we are done with the write end of the pipe. */				CloseHandle(syslogPipe[1]);				syslogPipe[1] = 0;#endif				redirection_done = true;			}			/* postmaster will never write the file; close it */			fclose(syslogFile);			syslogFile = NULL;			return (int) sysloggerPid;	}	/* we should never reach here */	return 0;}#ifdef EXEC_BACKEND/* * syslogger_forkexec() - * * Format up the arglist for, then fork and exec, a syslogger process */static pid_tsyslogger_forkexec(void){	char	   *av[10];	int			ac = 0,				bufc = 0,				i;	char		numbuf[2][32];	av[ac++] = "postgres";	av[ac++] = "-forklog";	av[ac++] = NULL;			/* filled in by postmaster_forkexec */	/* static variables (those not passed by write_backend_variables) */#ifndef WIN32	if (syslogFile != NULL)		snprintf(numbuf[bufc++], 32, "%d", fileno(syslogFile));	else		strcpy(numbuf[bufc++], "-1");	snprintf(numbuf[bufc++], 32, "%d", (int) redirection_done);#else							/* WIN32 */	if (syslogFile != NULL)		snprintf(numbuf[bufc++], 32, "%ld",				 _get_osfhandle(_fileno(syslogFile)));	else		strcpy(numbuf[bufc++], "0");	snprintf(numbuf[bufc++], 32, "%d", (int) redirection_done);#endif   /* WIN32 */	/* Add to the arg list */	Assert(bufc <= lengthof(numbuf));	for (i = 0; i < bufc; i++)		av[ac++] = numbuf[i];	av[ac] = NULL;	Assert(ac < lengthof(av));	return postmaster_forkexec(ac, av);}/* * syslogger_parseArgs() - * * Extract data from the arglist for exec'ed syslogger process */static voidsyslogger_parseArgs(int argc, char *argv[]){	int			fd;	Assert(argc == 5);	argv += 3;#ifndef WIN32	fd = atoi(*argv++);	if (fd != -1)	{		syslogFile = fdopen(fd, "a");		setvbuf(syslogFile, NULL, LBF_MODE, 0);	}	redirection_done = (bool) atoi(*argv++);#else							/* WIN32 */	fd = atoi(*argv++);	if (fd != 0)	{		fd = _open_osfhandle(fd, _O_APPEND);		if (fd > 0)		{			syslogFile = fdopen(fd, "a");			setvbuf(syslogFile, NULL, LBF_MODE, 0);		}	}	redirection_done = (bool) atoi(*argv++);#endif   /* WIN32 */}#endif   /* EXEC_BACKEND *//* -------------------------------- *		logfile routines * -------------------------------- *//* * Write text to the currently open logfile * * This is exported so that elog.c can call it when am_syslogger is true. * This allows the syslogger process to record elog messages of its own, * even though its stderr does not point at the syslog pipe. */voidwrite_syslogger_file(const char *buffer, int count){#ifdef WIN32	/*	 * On Windows we need to do our own newline-to-CRLF translation.	 */	char		convbuf[256];	char	   *p;	int			n;	p = convbuf;	n = 0;	while (count-- > 0)	{		if (*buffer == '\n')		{			*p++ = '\r';			n++;		}		*p++ = *buffer++;		n++;		if (n >= sizeof(convbuf) - 1)		{			write_syslogger_file_binary(convbuf, n);			p = convbuf;			n = 0;		}	}	if (n > 0)		write_syslogger_file_binary(convbuf, n);#else							/* !WIN32 */	write_syslogger_file_binary(buffer, count);#endif}/* * Write binary data to the currently open logfile * * On Windows the data arriving in the pipe already has CR/LF newlines, * so we must send it to the file without further translation. */static voidwrite_syslogger_file_binary(const char *buffer, int count){	int			rc;#ifndef WIN32	rc = fwrite(buffer, 1, count, syslogFile);#else	EnterCriticalSection(&sysfileSection);	rc = fwrite(buffer, 1, count, syslogFile);	LeaveCriticalSection(&sysfileSection);#endif	/* can't use ereport here because of possible recursion */	if (rc != count)		write_stderr("could not write to log file: %s\n", strerror(errno));}#ifdef WIN32/* * Worker thread to transfer data from the pipe to the current logfile. * * We need this because on Windows, WaitForSingleObject does not work on * unnamed pipes: it always reports "signaled", so the blocking ReadFile won't * allow for SIGHUP; and select is for sockets only. */static unsigned int __stdcallpipeThread(void *arg){	DWORD		bytesRead;	char		logbuffer[1024];	for (;;)	{		if (!ReadFile(syslogPipe[0], logbuffer, sizeof(logbuffer),					  &bytesRead, 0))		{			DWORD		error = GetLastError();			if (error == ERROR_HANDLE_EOF ||				error == ERROR_BROKEN_PIPE)				break;			_dosmaperr(error);			ereport(LOG,					(errcode_for_file_access(),					 errmsg("could not read from logger pipe: %m")));		}		else if (bytesRead > 0)			write_syslogger_file_binary(logbuffer, bytesRead);	}	/* We exit the above loop only upon detecting pipe EOF */	pipe_eof_seen = true;	_endthread();	return 0;}#endif   /* WIN32 *//* * perform logfile rotation */static voidlogfile_rotate(bool time_based_rotation){	char	   *filename;	FILE	   *fh;	rotation_requested = false;	/*	 * When doing a time-based rotation, invent the new logfile name based on	 * the planned rotation time, not current time, to avoid "slippage" in the	 * file name when we don't do the rotation immediately.	 */	if (time_based_rotation)		filename = logfile_getname(next_rotation_time);	else		filename = logfile_getname(time(NULL));	/*	 * Decide whether to overwrite or append.  We can overwrite if (a)	 * Log_truncate_on_rotation is set, (b) the rotation was triggered by	 * elapsed time and not something else, and (c) the computed file name is	 * different from what we were previously logging into.	 *	 * Note: during the first rotation after forking off from the postmaster,	 * last_file_name will be NULL.  (We don't bother to set it in the	 * postmaster because it ain't gonna work in the EXEC_BACKEND case.) So we	 * will always append in that situation, even though truncating would	 * usually be safe.	 */	if (Log_truncate_on_rotation && time_based_rotation &&		last_file_name != NULL && strcmp(filename, last_file_name) != 0)		fh = fopen(filename, "w");	else		fh = fopen(filename, "a");	if (!fh)	{		int			saveerrno = errno;		ereport(LOG,				(errcode_for_file_access(),				 errmsg("could not open new log file \"%s\": %m",						filename)));		/*		 * ENFILE/EMFILE are not too surprising on a busy system; just keep		 * using the old file till we manage to get a new one. Otherwise,		 * assume something's wrong with Log_directory and stop trying to		 * create files.		 */		if (saveerrno != ENFILE && saveerrno != EMFILE)		{			ereport(LOG,					(errmsg("disabling automatic rotation (use SIGHUP to reenable)")));			Log_RotationAge = 0;			Log_RotationSize = 0;		}		pfree(filename);		return;	}	setvbuf(fh, NULL, LBF_MODE, 0);	/* On Windows, need to interlock against data-transfer thread */#ifdef WIN32	EnterCriticalSection(&sysfileSection);#endif	fclose(syslogFile);	syslogFile = fh;#ifdef WIN32	LeaveCriticalSection(&sysfileSection);#endif	set_next_rotation_time();	/* instead of pfree'ing filename, remember it for next time */	if (last_file_name != NULL)		pfree(last_file_name);	last_file_name = filename;}/* * construct logfile name using timestamp information * * Result is palloc'd. */static char *logfile_getname(pg_time_t timestamp){	char	   *filename;	int			len;	struct pg_tm *tm;	filename = palloc(MAXPGPATH);	snprintf(filename, MAXPGPATH, "%s/", Log_directory);	len = strlen(filename);	if (strchr(Log_filename, '%'))	{		/* treat it as a strftime pattern */		tm = pg_localtime(&timestamp, global_timezone);		pg_strftime(filename + len, MAXPGPATH - len, Log_filename, tm);	}	else	{		/* no strftime escapes, so append timestamp to new filename */		snprintf(filename + len, MAXPGPATH - len, "%s.%lu",				 Log_filename, (unsigned long) timestamp);	}	return filename;}/* * Determine the next planned rotation time, and store in next_rotation_time. */static voidset_next_rotation_time(void){	pg_time_t	now;	struct pg_tm *tm;	int			rotinterval;	/* nothing to do if time-based rotation is disabled */	if (Log_RotationAge <= 0)		return;	/*	 * The requirements here are to choose the next time > now that is a	 * "multiple" of the log rotation interval.  "Multiple" can be interpreted	 * fairly loosely.	In this version we align to local time rather than	 * GMT.	 */	rotinterval = Log_RotationAge * SECS_PER_MINUTE;	/* convert to seconds */	now = time(NULL);	tm = pg_localtime(&now, global_timezone);	now += tm->tm_gmtoff;	now -= now % rotinterval;	now += rotinterval;	now -= tm->tm_gmtoff;	next_rotation_time = now;}/* -------------------------------- *		signal handler routines * -------------------------------- *//* SIGHUP: set flag to reload config file */static voidsigHupHandler(SIGNAL_ARGS){	got_SIGHUP = true;}/* SIGUSR1: set flag to rotate logfile */static voidsigUsr1Handler(SIGNAL_ARGS){	rotation_requested = true;}

⌨️ 快捷键说明

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