Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit76fd342

Browse files
Provide a better error message for misplaced dispatch options.
Before this patch, misplacing a special must-be-first option fordispatching to a subprogram (e.g., postgres -D . --single) wouldfail with an error likeFATAL: --single requires a valueThis patch adjusts this error to more accurately complain that thespecial option wasn't listed first. The aforementioned errormessage now looks likeFATAL: --single must be first argumentThe dispatch option parsing code has been refactored for usewherever ParseLongOption() is called. Beyond the obvious advantageof avoiding code duplication, this should prevent similar problemswhen new dispatch options are added. Note that we assume that noneof the dispatch option names match another valid command-lineargument, such as the name of a configuration parameter.Ideally, we'd remove this must-be-first requirement for theseoptions, but after some investigation, we decided that wasn't worththe added complexity and behavior changes.Author: Nathan Bossart, Greg Sabino MullaneReviewed-by: Greg Sabino Mullane, Peter Eisentraut, Álvaro Herrera, Tom LaneDiscussion:https://postgr.es/m/CAKAnmmJkZtZAiSryho%3DgYpbvC7H-HNjEDAh16F3SoC9LPu8rqQ%40mail.gmail.com
1 parent24c1c63 commit76fd342

File tree

6 files changed

+133
-16
lines changed

6 files changed

+133
-16
lines changed

‎src/backend/bootstrap/bootstrap.c‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,21 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
224224
case'B':
225225
SetConfigOption("shared_buffers",optarg,PGC_POSTMASTER,PGC_S_ARGV);
226226
break;
227-
case'c':
228227
case'-':
228+
229+
/*
230+
* Error if the user misplaced a special must-be-first option
231+
* for dispatching to a subprogram. parse_dispatch_option()
232+
* returns DISPATCH_POSTMASTER if it doesn't find a match, so
233+
* error for anything else.
234+
*/
235+
if (parse_dispatch_option(optarg)!=DISPATCH_POSTMASTER)
236+
ereport(ERROR,
237+
(errcode(ERRCODE_SYNTAX_ERROR),
238+
errmsg("--%s must be first argument",optarg)));
239+
240+
/* FALLTHROUGH */
241+
case'c':
229242
{
230243
char*name,
231244
*value;

‎src/backend/main/main.c‎

Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@
4343
constchar*progname;
4444
staticboolreached_main= false;
4545

46+
/* names of special must-be-first options for dispatching to subprograms */
47+
staticconstchar*constDispatchOptionNames[]=
48+
{
49+
[DISPATCH_CHECK]="check",
50+
[DISPATCH_BOOT]="boot",
51+
[DISPATCH_FORKCHILD]="forkchild",
52+
[DISPATCH_DESCRIBE_CONFIG]="describe-config",
53+
[DISPATCH_SINGLE]="single",
54+
/* DISPATCH_POSTMASTER has no name */
55+
};
56+
57+
StaticAssertDecl(lengthof(DispatchOptionNames)==DISPATCH_POSTMASTER,
58+
"array length mismatch");
4659

4760
staticvoidstartup_hacks(constchar*progname);
4861
staticvoidinit_locale(constchar*categoryname,intcategory,constchar*locale);
@@ -57,6 +70,7 @@ int
5770
main(intargc,char*argv[])
5871
{
5972
booldo_check_root= true;
73+
DispatchOptiondispatch_option=DISPATCH_POSTMASTER;
6074

6175
reached_main= true;
6276

@@ -179,26 +193,72 @@ main(int argc, char *argv[])
179193
* Dispatch to one of various subprograms depending on first argument.
180194
*/
181195

182-
if (argc>1&&strcmp(argv[1],"--check")==0)
183-
BootstrapModeMain(argc,argv, true);
184-
elseif (argc>1&&strcmp(argv[1],"--boot")==0)
185-
BootstrapModeMain(argc,argv, false);
196+
if (argc>1&&argv[1][0]=='-'&&argv[1][1]=='-')
197+
dispatch_option=parse_dispatch_option(&argv[1][2]);
198+
199+
switch (dispatch_option)
200+
{
201+
caseDISPATCH_CHECK:
202+
BootstrapModeMain(argc,argv, true);
203+
break;
204+
caseDISPATCH_BOOT:
205+
BootstrapModeMain(argc,argv, false);
206+
break;
207+
caseDISPATCH_FORKCHILD:
186208
#ifdefEXEC_BACKEND
187-
elseif (argc>1&&strncmp(argv[1], "--forkchild",11)==0)
188-
SubPostmasterMain(argc,argv);
209+
SubPostmasterMain(argc,argv);
210+
#else
211+
Assert(false);/* should never happen */
189212
#endif
190-
elseif (argc>1&&strcmp(argv[1], "--describe-config") == 0)
191-
GucInfoMain();
192-
elseif (argc>1&&strcmp(argv[1], "--single")==0)
193-
PostgresSingleUserMain(argc,argv,
194-
strdup(get_user_name_or_exit(progname)));
195-
else
196-
PostmasterMain(argc,argv);
213+
break;
214+
caseDISPATCH_DESCRIBE_CONFIG:
215+
GucInfoMain();
216+
break;
217+
caseDISPATCH_SINGLE:
218+
PostgresSingleUserMain(argc,argv,
219+
strdup(get_user_name_or_exit(progname)));
220+
break;
221+
caseDISPATCH_POSTMASTER:
222+
PostmasterMain(argc,argv);
223+
break;
224+
}
225+
197226
/* the functions above should not return */
198227
abort();
199228
}
200229

230+
/*
231+
* Returns the matching DispatchOption value for the given option name. If no
232+
* match is found, DISPATCH_POSTMASTER is returned.
233+
*/
234+
DispatchOption
235+
parse_dispatch_option(constchar*name)
236+
{
237+
for (inti=0;i<lengthof(DispatchOptionNames);i++)
238+
{
239+
/*
240+
* Unlike the other dispatch options, "forkchild" takes an argument,
241+
* so we just look for the prefix for that one. For non-EXEC_BACKEND
242+
* builds, we never want to return DISPATCH_FORKCHILD, so skip over it
243+
* in that case.
244+
*/
245+
if (i==DISPATCH_FORKCHILD)
246+
{
247+
#ifdefEXEC_BACKEND
248+
if (strncmp(DispatchOptionNames[DISPATCH_FORKCHILD],name,
249+
strlen(DispatchOptionNames[DISPATCH_FORKCHILD]))==0)
250+
returnDISPATCH_FORKCHILD;
251+
#endif
252+
continue;
253+
}
254+
255+
if (strcmp(DispatchOptionNames[i],name)==0)
256+
return (DispatchOption)i;
257+
}
201258

259+
/* no match means this is a postmaster */
260+
returnDISPATCH_POSTMASTER;
261+
}
202262

203263
/*
204264
* Place platform-specific startup hacks here. This is the right

‎src/backend/postmaster/postmaster.c‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,21 @@ PostmasterMain(int argc, char *argv[])
589589
output_config_variable=strdup(optarg);
590590
break;
591591

592-
case'c':
593592
case'-':
593+
594+
/*
595+
* Error if the user misplaced a special must-be-first option
596+
* for dispatching to a subprogram. parse_dispatch_option()
597+
* returns DISPATCH_POSTMASTER if it doesn't find a match, so
598+
* error for anything else.
599+
*/
600+
if (parse_dispatch_option(optarg)!=DISPATCH_POSTMASTER)
601+
ereport(ERROR,
602+
(errcode(ERRCODE_SYNTAX_ERROR),
603+
errmsg("--%s must be first argument",optarg)));
604+
605+
/* FALLTHROUGH */
606+
case'c':
594607
{
595608
char*name,
596609
*value;

‎src/backend/tcop/postgres.c‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3947,8 +3947,21 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
39473947
/* ignored for consistency with the postmaster */
39483948
break;
39493949

3950-
case'c':
39513950
case'-':
3951+
3952+
/*
3953+
* Error if the user misplaced a special must-be-first option
3954+
* for dispatching to a subprogram. parse_dispatch_option()
3955+
* returns DISPATCH_POSTMASTER if it doesn't find a match, so
3956+
* error for anything else.
3957+
*/
3958+
if (parse_dispatch_option(optarg)!=DISPATCH_POSTMASTER)
3959+
ereport(ERROR,
3960+
(errcode(ERRCODE_SYNTAX_ERROR),
3961+
errmsg("--%s must be first argument",optarg)));
3962+
3963+
/* FALLTHROUGH */
3964+
case'c':
39523965
{
39533966
char*name,
39543967
*value;

‎src/include/postmaster/postmaster.h‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,21 @@ extern PMChild *FindPostmasterChildByPid(int pid);
138138
*/
139139
#defineMAX_BACKENDS0x3FFFF
140140

141+
/*
142+
* These values correspond to the special must-be-first options for dispatching
143+
* to various subprograms. parse_dispatch_option() can be used to convert an
144+
* option name to one of these values.
145+
*/
146+
typedefenumDispatchOption
147+
{
148+
DISPATCH_CHECK,
149+
DISPATCH_BOOT,
150+
DISPATCH_FORKCHILD,
151+
DISPATCH_DESCRIBE_CONFIG,
152+
DISPATCH_SINGLE,
153+
DISPATCH_POSTMASTER,/* must be last */
154+
}DispatchOption;
155+
156+
externDispatchOptionparse_dispatch_option(constchar*name);
157+
141158
#endif/* _POSTMASTER_H */

‎src/tools/pgindent/typedefs.list‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ DirectoryMethodFile
619619
DisableTimeoutParams
620620
DiscardMode
621621
DiscardStmt
622+
DispatchOption
622623
DistanceValue
623624
DistinctExpr
624625
DoState

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp