pg_ctl: Minor patch to implement option checking to prevent silently
ignoring options and continuing with defaults.

All of the following now cause errors:

pg_ctl -D test -m logfile start
pg_ctl -D test -U foo start
pg_ctl -D test -W start
pg_ctl -D test -w stop
pg_ctl -D test -l fast stop
etc.. (16 possible error combinations in total now checked)

The following also fails, following the --help, though I think we might
want to change this so that it does actually work:

pg_ctl -D test -l logfile restart

Patch against cvstip, make check, tested on long and short options.

-- 
  Simon Riggs             
  EnterpriseDB   http://www.enterprisedb.com
Index: src/bin/pg_ctl/pg_ctl.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_ctl/pg_ctl.c,v
retrieving revision 1.67
diff -c -r1.67 pg_ctl.c
*** src/bin/pg_ctl/pg_ctl.c	5 Mar 2006 15:58:50 -0000	1.67
--- src/bin/pg_ctl/pg_ctl.c	13 Apr 2006 17:44:26 -0000
***************
*** 90,95 ****
--- 90,96 ----
  static char *register_username = NULL;
  static char *register_password = NULL;
  static char *argv0 = NULL;
+ static uint32 ctl_command_invalid_options = 0;
  
  static void
  write_stderr(const char *fmt,...)
***************
*** 109,114 ****
--- 110,118 ----
  static void do_status(void);
  static void do_kill(pgpid_t pid);
  static void print_msg(const char *msg);
+ static uint32 opt2bit(CtlCommand ctlcmd);
+ static bool command_options_valid(CtlCommand ctlcmd);
+ static void declare_option_validity(uint32 option_bitmask);
  
  #if defined(WIN32) || defined(__CYGWIN__)
  static bool pgwin32_IsInstalled(SC_HANDLE);
***************
*** 1564,1584 ****
--- 1568,1593 ----
  					}
  				case 'l':
  					log_file = xstrdup(optarg);
+                     declare_option_validity(opt2bit(START_COMMAND));
  					break;
  				case 'm':
  					set_mode(optarg);
+                     declare_option_validity(opt2bit(STOP_COMMAND) | opt2bit(RESTART_COMMAND));
  					break;
  				case 'N':
  					register_servicename = xstrdup(optarg);
+                     declare_option_validity(opt2bit(REGISTER_COMMAND) | opt2bit(UNREGISTER_COMMAND));
  					break;
  				case 'o':
  					post_opts = xstrdup(optarg);
+                     declare_option_validity(opt2bit(START_COMMAND) | opt2bit(RESTART_COMMAND));
  					break;
  				case 'p':
  					postgres_path = xstrdup(optarg);
  					break;
  				case 'P':
  					register_password = xstrdup(optarg);
+                     declare_option_validity(opt2bit(REGISTER_COMMAND) | opt2bit(UNREGISTER_COMMAND));
  					break;
  				case 's':
  					silent_mode = true;
***************
*** 1598,1611 ****
--- 1607,1623 ----
  						strcpy(register_username, ".\\");
  						strcat(register_username, optarg);
  					}
+                     declare_option_validity(opt2bit(REGISTER_COMMAND) | opt2bit(UNREGISTER_COMMAND));
  					break;
  				case 'w':
  					do_wait = true;
  					wait_set = true;
+                     declare_option_validity(opt2bit(START_COMMAND) | opt2bit(RESTART_COMMAND));
  					break;
  				case 'W':
  					do_wait = false;
  					wait_set = true;
+                     declare_option_validity(opt2bit(STOP_COMMAND));
  					break;
  				default:
  					write_stderr(_("%s: invalid option %s\n"), progname, optarg);
***************
*** 1671,1676 ****
--- 1683,1696 ----
  		exit(1);
  	}
  
+     /* Check command and option restrictions */
+ 	if (!command_options_valid(ctl_command))
+ 	{
+ 		write_stderr(_("%s: invalid options specified for command\n"), progname);
+ 		do_advice();
+ 		exit(1);
+ 	}
+ 
  	/* Note we put any -D switch into the env var above */
  	pg_data = getenv("PGDATA");
  	if (pg_data)
***************
*** 1756,1758 ****
--- 1776,1796 ----
  
  	exit(0);
  }
+ 
+ static uint32 opt2bit(CtlCommand ctlcmd)
+ {
+     return (uint32) 1 << ctlcmd;
+ }
+ 
+ static bool command_options_valid(CtlCommand ctlcmd)
+ {
+     if ((ctl_command_invalid_options & opt2bit(ctlcmd)) == 0)
+         return true;
+     else
+         return false;
+ }
+ 
+ static void declare_option_validity(uint32 option_bitmask)
+ {
+     ctl_command_invalid_options |= ~option_bitmask;
+ }
---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Reply via email to