diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 8e9880f..3ad1d9e 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -691,7 +691,7 @@ exec_command(const char *cmd, else { expand_tilde(&fname); - success = (process_file(fname, false) == EXIT_SUCCESS); + success = (process_file((char **) fname, 1, false) == EXIT_SUCCESS); free(fname); } } @@ -1714,32 +1714,15 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, bool *edited) * MainLoop() error code. */ int -process_file(char *filename, bool single_txn) +process_file(char **filename, int num_files, bool single_txn) { - FILE *fd; - int result; + int i; + int result = EXIT_FAILURE; char *oldfilename; PGresult *res; - if (!filename) - return EXIT_FAILURE; - - if (strcmp(filename, "-") != 0) - { - canonicalize_path(filename); - fd = fopen(filename, PG_BINARY_R); - } - else - fd = stdin; - - if (!fd) - { - psql_error("%s: %s\n", filename, strerror(errno)); - return EXIT_FAILURE; - } oldfilename = pset.inputfile; - pset.inputfile = filename; if (single_txn) { @@ -1752,7 +1735,35 @@ process_file(char *filename, bool single_txn) PQclear(res); } - result = MainLoop(fd); + for (i = 0; i < num_files; i++) + { + FILE *fd; + + if (!filename[i]) + return EXIT_FAILURE; + + if (strcmp(filename[i], "-") != 0) + { + canonicalize_path(filename[i]); + fd = fopen(filename[i], PG_BINARY_R); + } + else + fd = stdin; + + if (!fd) + { + psql_error("%s: %s\n", filename[i], strerror(errno)); + return EXIT_FAILURE; + } + + pset.inputfile = filename[i]; + + result = MainLoop(fd); + if (result != EXIT_SUCCESS) + return EXIT_FAILURE; + + fclose(fd); + } if (single_txn) { @@ -1765,7 +1776,6 @@ process_file(char *filename, bool single_txn) PQclear(res); } - fclose(fd); pset.inputfile = oldfilename; return result; } diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h index 09093b3..1467190 100644 --- a/src/bin/psql/command.h +++ b/src/bin/psql/command.h @@ -27,7 +27,7 @@ typedef enum _backslashResult extern backslashResult HandleSlashCmds(PsqlScanState scan_state, PQExpBuffer query_buf); -extern int process_file(char *filename, bool single_txn); +extern int process_file(char **filename, int num_files, bool single_txn); extern bool do_pset(const char *param, const char *value, diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index 61c7f11..31969f1 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -43,6 +43,8 @@ PsqlSettings pset; #define PSQLRC "psqlrc.conf" #endif +#define FILE_ALLOC_BLOCKS 16 + /* * Structures to pass information between the option parsing routine * and the main function @@ -68,6 +70,8 @@ struct adhoc_opts bool no_readline; bool no_psqlrc; bool single_txn; + int num_files; + char **files; }; static void parse_psql_options(int argc, char *argv[], @@ -243,14 +247,16 @@ main(int argc, char *argv[]) */ /* - * process file given by -f + * process file(s) given by -f */ if (options.action == ACT_FILE) { if (!options.no_psqlrc) process_psqlrc(argv[0]); - successResult = process_file(options.action_string, options.single_txn); + successResult = process_file(options.files, options.num_files, + options.single_txn); + free(options.files); } /* @@ -398,7 +404,12 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options) break; case 'f': options->action = ACT_FILE; - options->action_string = optarg; + options->num_files++; + if (!((options->num_files - 1) % FILE_ALLOC_BLOCKS)) { + options->files = realloc(options->files, sizeof(char *) * + (options->num_files + FILE_ALLOC_BLOCKS)); + } + options->files[options->num_files - 1] = optarg; break; case 'F': pset.popt.topt.fieldSep = pg_strdup(optarg); @@ -598,9 +609,9 @@ process_psqlrc_file(char *filename) sprintf(psqlrc, "%s-%s", filename, PG_VERSION); if (access(psqlrc, R_OK) == 0) - (void) process_file(psqlrc, false); + (void) process_file((char **) psqlrc, 1, false); else if (access(filename, R_OK) == 0) - (void) process_file(filename, false); + (void) process_file((char **) filename, 1, false); free(psqlrc); }