Itagaki Takahiro wrote:
> I think the patch is almost ready for committer except the following
> three issues:
> 
> 2010/7/13 Fujii Masao <masao.fu...@gmail.com>:
>>> +     if (!*value || *endptr || file_mode < 0 || file_mode > 0777)
>> The sticky bit cannot be set via log_file_mode. Is this intentional? 

Yes -- I don't think there is a use case for sticky or setuid bits on log
files, even allowing execute is questionable.

> We should also check the value not to be something like 0699.
> How about checking it with (file_mode & ~0666) != 0 ?

Aha, that would ensure that the execute bit is not specified. Works for me.
The 0699 and other invalid octal values are caught by strtol()

>>> +#ifndef WIN32
>>> +             chmod(filename, Log_file_mode);
>>> +#endif
>> Don't we need to check the return value of chmod()?
> 
> I prefer umask() rather than chmod() here.
> 

Converted to umask()

>>> +const char *show_log_file_mode(void);
>> You forgot to write the show_log_file_mode()? I was not able to find that
>> in the patch.
> 
> I want show_log_file_mode to print the setting value in octal format.
> 

I've now (re)added the show_log_file_mode(). It used to be there, but then
at some point I decided to display the value "as-is".

While going through it, I moved the _setmode() call for win32 to logfile_open().

regards,
Martin

*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
***************
*** 2789,2794 **** local0.*    /var/log/postgresql
--- 2789,2815 ----
        </listitem>
       </varlistentry>
  
+      <varlistentry id="guc-log-file-mode" xreflabel="log_file_mode">
+       <term><varname>log_file_mode</varname> (<type>integer</type>)</term>
+       <indexterm>
+        <primary><varname>log_file_mode</> configuration parameter</primary>
+       </indexterm>
+       <listitem>
+        <para>
+         On Unix systems this parameter sets the permissions for log files
+         when <varname>logging_collector</varname> is enabled. On Microsoft
+         Windows the file mode will be ignored. The value is an octal number
+         consisting of 3 digits signifying the permissions for the user, group
+         and others. Specifying execute permissions for log files results in
+         an error.
+        </para>
+        <para>
+         This parameter can only be set in the <filename>postgresql.conf</>
+         file or on the server command line.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
       <varlistentry id="guc-log-rotation-age" xreflabel="log_rotation_age">
        <term><varname>log_rotation_age</varname> (<type>integer</type>)</term>
        <indexterm>
*** a/src/backend/commands/variable.c
--- b/src/backend/commands/variable.c
***************
*** 914,916 **** show_role(void)
--- 914,956 ----
  
  	return endptr + 1;
  }
+ 
+ 
+ /*
+  * LOG_FILE_MODE
+  */
+ 
+ extern int Log_file_mode;		/* in guc.c */
+ 
+ /*
+  * assign_log_file_mode: GUC assign_hook for log_file_mode
+  */
+ const char *
+ assign_log_file_mode(const char *value, bool doit, GucSource source)
+ {
+ 	char *endptr;
+ 	long file_mode = strtol(value, &endptr, 8);
+ 
+ 	if (!*value || *endptr || file_mode < 0 || (file_mode & ~0666) != 0)
+ 	{
+ 		ereport(GUC_complaint_elevel(source),
+ 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 				 errmsg("invalid value for parameter \"log_file_mode\""),
+ 				 errhint("value must be a 3 digit octal number, with the execute bit not set")));
+ 		return NULL;
+ 	}
+ 
+ 	if (doit)
+ 		Log_file_mode = (int) file_mode;
+ 
+ 	return value;
+ }
+ 
+ const char *
+ show_log_file_mode(void)
+ {
+ 	static char buf[5];
+ 
+ 	snprintf(buf, sizeof(buf), "%04o", Log_file_mode);
+ 	return buf;
+ }
*** a/src/backend/postmaster/syslogger.c
--- b/src/backend/postmaster/syslogger.c
***************
*** 73,78 **** int			Log_RotationSize = 10 * 1024;
--- 73,79 ----
  char	   *Log_directory = NULL;
  char	   *Log_filename = NULL;
  bool		Log_truncate_on_rotation = false;
+ int			Log_file_mode = 0600;
  
  /*
   * Globally visible state (used by elog.c)
***************
*** 135,140 **** static void syslogger_parseArgs(int argc, char *argv[]);
--- 136,142 ----
  static void process_pipe_input(char *logbuffer, int *bytes_in_logbuffer);
  static void flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer);
  static void open_csvlogfile(void);
+ static FILE *logfile_open(const char *filename, const char *mode, bool am_rotating);
  
  #ifdef WIN32
  static unsigned int __stdcall pipeThread(void *arg);
***************
*** 516,530 **** SysLogger_Start(void)
  	 */
  	filename = logfile_getname(time(NULL), NULL);
  
! 	syslogFile = fopen(filename, "a");
! 
! 	if (!syslogFile)
! 		ereport(FATAL,
! 				(errcode_for_file_access(),
! 				 (errmsg("could not create log file \"%s\": %m",
! 						 filename))));
! 
! 	setvbuf(syslogFile, NULL, LBF_MODE, 0);
  
  	pfree(filename);
  
--- 518,524 ----
  	 */
  	filename = logfile_getname(time(NULL), NULL);
  
! 	syslogFile = logfile_open(filename, "a", false);
  
  	pfree(filename);
  
***************
*** 1004,1027 **** open_csvlogfile(void)
  
  	filename = logfile_getname(time(NULL), ".csv");
  
! 	fh = fopen(filename, "a");
  
! 	if (!fh)
! 		ereport(FATAL,
! 				(errcode_for_file_access(),
! 				 (errmsg("could not create log file \"%s\": %m",
! 						 filename))));
  
! 	setvbuf(fh, NULL, LBF_MODE, 0);
  
! #ifdef WIN32
! 	_setmode(_fileno(fh), _O_TEXT);		/* use CRLF line endings on Windows */
! #endif
  
! 	csvlogFile = fh;
  
! 	pfree(filename);
  
  }
  
  /*
--- 998,1050 ----
  
  	filename = logfile_getname(time(NULL), ".csv");
  
! 	fh = logfile_open(filename, "a", false);
  
! 	csvlogFile = fh;
  
! 	pfree(filename);
  
! }
  
! /*
!  * Open the logfile with proper permissions and buffering options.
!  *
!  * We ignore any errors if the logfile is opened as part of log rotation. In
!  * other cases the errors are treated as fatal.
!  */
! static FILE *
! logfile_open(const char *filename, const char *mode, bool am_rotating)
! {
! 	mode_t	oumask;
! 	FILE   *fh;
  
! 	oumask = umask((mode_t) (~Log_file_mode & 0777));
! 	fh = fopen(filename, mode);
! 	umask(oumask);
! 
! 	if (fh)
! 	{
! 		setvbuf(fh, NULL, LBF_MODE, 0);
  
+ #ifdef WIN32
+ 		_setmode(_fileno(fh), _O_TEXT); /* use CRLF line endings on Windows */
+ #endif
+ 	}
+ 	else
+ 	{
+ 		if (am_rotating)
+ 			ereport(LOG,
+ 					(errcode_for_file_access(),
+ 					 errmsg("could not create new log file \"%s\": %m",
+ 					 		filename)));
+ 		else
+ 			ereport(FATAL,
+ 					(errcode_for_file_access(),
+ 					 errmsg("could not create log file \"%s\": %m",
+ 					 		filename)));
+ 	}
+ 
+ 	return fh;
  }
  
  /*
***************
*** 1070,1088 **** logfile_rotate(bool time_based_rotation, int size_rotation_for)
  		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.
--- 1093,1106 ----
  		if (Log_truncate_on_rotation && time_based_rotation &&
  			last_file_name != NULL &&
  			strcmp(filename, last_file_name) != 0)
! 			fh = logfile_open(filename, "w", true);
  		else
! 			fh = logfile_open(filename, "a", true);
  
  		if (!fh)
  		{
  			int			saveerrno = errno;
  
  			/*
  			 * ENFILE/EMFILE are not too surprising on a busy system; just
  			 * keep using the old file till we manage to get a new one.
***************
*** 1104,1115 **** logfile_rotate(bool time_based_rotation, int size_rotation_for)
  			return;
  		}
  
- 		setvbuf(fh, NULL, LBF_MODE, 0);
- 
- #ifdef WIN32
- 		_setmode(_fileno(fh), _O_TEXT); /* use CRLF line endings on Windows */
- #endif
- 
  		fclose(syslogFile);
  		syslogFile = fh;
  
--- 1122,1127 ----
***************
*** 1128,1146 **** logfile_rotate(bool time_based_rotation, int size_rotation_for)
  		if (Log_truncate_on_rotation && time_based_rotation &&
  			last_csv_file_name != NULL &&
  			strcmp(csvfilename, last_csv_file_name) != 0)
! 			fh = fopen(csvfilename, "w");
  		else
! 			fh = fopen(csvfilename, "a");
  
  		if (!fh)
  		{
  			int			saveerrno = errno;
  
- 			ereport(LOG,
- 					(errcode_for_file_access(),
- 					 errmsg("could not open new log file \"%s\": %m",
- 							csvfilename)));
- 
  			/*
  			 * ENFILE/EMFILE are not too surprising on a busy system; just
  			 * keep using the old file till we manage to get a new one.
--- 1140,1153 ----
  		if (Log_truncate_on_rotation && time_based_rotation &&
  			last_csv_file_name != NULL &&
  			strcmp(csvfilename, last_csv_file_name) != 0)
! 			fh = logfile_open(csvfilename, "w", true);
  		else
! 			fh = logfile_open(csvfilename, "a", true);
  
  		if (!fh)
  		{
  			int			saveerrno = errno;
  
  			/*
  			 * ENFILE/EMFILE are not too surprising on a busy system; just
  			 * keep using the old file till we manage to get a new one.
***************
*** 1162,1173 **** logfile_rotate(bool time_based_rotation, int size_rotation_for)
  			return;
  		}
  
- 		setvbuf(fh, NULL, LBF_MODE, 0);
- 
- #ifdef WIN32
- 		_setmode(_fileno(fh), _O_TEXT); /* use CRLF line endings on Windows */
- #endif
- 
  		fclose(csvlogFile);
  		csvlogFile = fh;
  
--- 1169,1174 ----
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 412,417 **** static char *server_version_string;
--- 412,418 ----
  static int	server_version_num;
  static char *timezone_string;
  static char *log_timezone_string;
+ static char *log_file_mode_string;
  static char *timezone_abbreviations_string;
  static char *XactIsoLevel_string;
  static char *data_directory;
***************
*** 2243,2248 **** static struct config_string ConfigureNamesString[] =
--- 2244,2258 ----
  	},
  
  	{
+ 		{"log_file_mode", PGC_SIGHUP, LOGGING_WHERE,
+ 			gettext_noop("Sets the file permissions for log files."),
+ 			NULL
+ 		},
+ 		&log_file_mode_string,
+ 		"0600", assign_log_file_mode, show_log_file_mode
+ 	},
+ 
+ 	{
  		{"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE,
  			gettext_noop("Sets the display format for date and time values."),
  			gettext_noop("Also controls interpretation of ambiguous "
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 265,270 ****
--- 265,271 ----
  					# can be absolute or relative to PGDATA
  #log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'	# log file name pattern,
  					# can include strftime() escapes
+ #log_file_mode = 0600			# creation mode for log files, octal
  #log_truncate_on_rotation = off		# If on, an existing log file of the
  					# same name as the new log file will be
  					# truncated rather than appended to.
*** a/src/include/commands/variable.h
--- b/src/include/commands/variable.h
***************
*** 35,39 **** extern const char *show_role(void);
--- 35,42 ----
  extern const char *assign_session_authorization(const char *value,
  							 bool doit, GucSource source);
  extern const char *show_session_authorization(void);
+ const char *assign_log_file_mode(const char *value,
+ 							bool doit, GucSource source);
+ const char *show_log_file_mode(void);
  
  #endif   /* VARIABLE_H */
*** a/src/include/postmaster/syslogger.h
--- b/src/include/postmaster/syslogger.h
***************
*** 68,73 **** extern int	Log_RotationSize;
--- 68,74 ----
  extern PGDLLIMPORT char *Log_directory;
  extern PGDLLIMPORT char *Log_filename;
  extern bool Log_truncate_on_rotation;
+ extern int Log_file_mode;
  
  extern bool am_syslogger;
  
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to