Use extensible buffers to assemble command lines

This makes use of StringInfo to assemble command lines, instead of
using fixed-size buffers and the (remote) possibility of "command too
long" errors.  Also makes the code a bit simpler.

This covers the test driver programs pg_regress and
pg_isolation_regress.

Similar to the changes done for pg_rewind in a33e17f210.

Discussion: https://www.postgresql.org/message-id/2be4fee5-738f-4749-b9f8-b452032c7ade%40eisentraut.org
This commit is contained in:
Peter Eisentraut 2024-02-11 09:08:35 +01:00
parent 4697454686
commit e70abd67c3
2 changed files with 31 additions and 49 deletions

View File

@ -12,6 +12,7 @@
#include "postgres_fe.h" #include "postgres_fe.h"
#include "lib/stringinfo.h"
#include "pg_regress.h" #include "pg_regress.h"
char saved_argv0[MAXPGPATH]; char saved_argv0[MAXPGPATH];
@ -34,8 +35,7 @@ isolation_start_test(const char *testname,
char infile[MAXPGPATH]; char infile[MAXPGPATH];
char outfile[MAXPGPATH]; char outfile[MAXPGPATH];
char expectfile[MAXPGPATH]; char expectfile[MAXPGPATH];
char psql_cmd[MAXPGPATH * 3]; StringInfoData psql_cmd;
size_t offset = 0;
char *appnameenv; char *appnameenv;
/* need to do the path lookup here, check isolation_init() for details */ /* need to do the path lookup here, check isolation_init() for details */
@ -75,34 +75,23 @@ isolation_start_test(const char *testname,
add_stringlist_item(resultfiles, outfile); add_stringlist_item(resultfiles, outfile);
add_stringlist_item(expectfiles, expectfile); add_stringlist_item(expectfiles, expectfile);
if (launcher) initStringInfo(&psql_cmd);
{
offset += snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset,
"%s ", launcher);
if (offset >= sizeof(psql_cmd))
{
fprintf(stderr, _("command too long\n"));
exit(2);
}
}
offset += snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, if (launcher)
"\"%s\" \"dbname=%s\" < \"%s\" > \"%s\" 2>&1", appendStringInfo(&psql_cmd, "%s ", launcher);
isolation_exec,
dblist->str, appendStringInfo(&psql_cmd,
infile, "\"%s\" \"dbname=%s\" < \"%s\" > \"%s\" 2>&1",
outfile); isolation_exec,
if (offset >= sizeof(psql_cmd)) dblist->str,
{ infile,
fprintf(stderr, _("command too long\n")); outfile);
exit(2);
}
appnameenv = psprintf("isolation/%s", testname); appnameenv = psprintf("isolation/%s", testname);
setenv("PGAPPNAME", appnameenv, 1); setenv("PGAPPNAME", appnameenv, 1);
free(appnameenv); free(appnameenv);
pid = spawn_process(psql_cmd); pid = spawn_process(psql_cmd.data);
if (pid == INVALID_PID) if (pid == INVALID_PID)
{ {
@ -113,6 +102,8 @@ isolation_start_test(const char *testname,
unsetenv("PGAPPNAME"); unsetenv("PGAPPNAME");
pfree(psql_cmd.data);
return pid; return pid;
} }

View File

@ -18,6 +18,7 @@
#include "postgres_fe.h" #include "postgres_fe.h"
#include "lib/stringinfo.h"
#include "pg_regress.h" #include "pg_regress.h"
/* /*
@ -34,8 +35,7 @@ psql_start_test(const char *testname,
char infile[MAXPGPATH]; char infile[MAXPGPATH];
char outfile[MAXPGPATH]; char outfile[MAXPGPATH];
char expectfile[MAXPGPATH]; char expectfile[MAXPGPATH];
char psql_cmd[MAXPGPATH * 3]; StringInfoData psql_cmd;
size_t offset = 0;
char *appnameenv; char *appnameenv;
/* /*
@ -62,40 +62,29 @@ psql_start_test(const char *testname,
add_stringlist_item(resultfiles, outfile); add_stringlist_item(resultfiles, outfile);
add_stringlist_item(expectfiles, expectfile); add_stringlist_item(expectfiles, expectfile);
initStringInfo(&psql_cmd);
if (launcher) if (launcher)
{ appendStringInfo(&psql_cmd, "%s ", launcher);
offset += snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset,
"%s ", launcher);
if (offset >= sizeof(psql_cmd))
{
fprintf(stderr, _("command too long\n"));
exit(2);
}
}
/* /*
* Use HIDE_TABLEAM to hide different AMs to allow to use regression tests * Use HIDE_TABLEAM to hide different AMs to allow to use regression tests
* against different AMs without unnecessary differences. * against different AMs without unnecessary differences.
*/ */
offset += snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, appendStringInfo(&psql_cmd,
"\"%s%spsql\" -X -a -q -d \"%s\" %s < \"%s\" > \"%s\" 2>&1", "\"%s%spsql\" -X -a -q -d \"%s\" %s < \"%s\" > \"%s\" 2>&1",
bindir ? bindir : "", bindir ? bindir : "",
bindir ? "/" : "", bindir ? "/" : "",
dblist->str, dblist->str,
"-v HIDE_TABLEAM=on -v HIDE_TOAST_COMPRESSION=on", "-v HIDE_TABLEAM=on -v HIDE_TOAST_COMPRESSION=on",
infile, infile,
outfile); outfile);
if (offset >= sizeof(psql_cmd))
{
fprintf(stderr, _("command too long\n"));
exit(2);
}
appnameenv = psprintf("pg_regress/%s", testname); appnameenv = psprintf("pg_regress/%s", testname);
setenv("PGAPPNAME", appnameenv, 1); setenv("PGAPPNAME", appnameenv, 1);
free(appnameenv); free(appnameenv);
pid = spawn_process(psql_cmd); pid = spawn_process(psql_cmd.data);
if (pid == INVALID_PID) if (pid == INVALID_PID)
{ {
@ -106,6 +95,8 @@ psql_start_test(const char *testname,
unsetenv("PGAPPNAME"); unsetenv("PGAPPNAME");
pfree(psql_cmd.data);
return pid; return pid;
} }