1 /*
2 * psql - the PostgreSQL interactive terminal
3 *
4 * Copyright (c) 2000-2016, PostgreSQL Global Development Group
5 *
6 * src/bin/psql/mainloop.c
7 */
8 #include "postgres_fe.h"
9 #include "mainloop.h"
10
11 #include "command.h"
12 #include "common.h"
13 #include "input.h"
14 #include "prompt.h"
15 #include "settings.h"
16
17 #include "mb/pg_wchar.h"
18
19
20 /* callback functions for our flex lexer */
21 const PsqlScanCallbacks psqlscan_callbacks = {
22 psql_get_variable,
23 psql_error
24 };
25
26
27 /*
28 * Main processing loop for reading lines of input
29 * and sending them to the backend.
30 *
31 * This loop is re-entrant. May be called by \i command
32 * which reads input from a file.
33 */
34 int
MainLoop(FILE * source)35 MainLoop(FILE *source)
36 {
37 PsqlScanState scan_state; /* lexer working state */
38 volatile PQExpBuffer query_buf; /* buffer for query being accumulated */
39 volatile PQExpBuffer previous_buf; /* if there isn't anything in the new
40 * buffer yet, use this one for \e,
41 * etc. */
42 PQExpBuffer history_buf; /* earlier lines of a multi-line command, not
43 * yet saved to readline history */
44 char *line; /* current line of input */
45 int added_nl_pos;
46 bool success;
47 bool line_saved_in_history;
48 volatile int successResult = EXIT_SUCCESS;
49 volatile backslashResult slashCmdStatus = PSQL_CMD_UNKNOWN;
50 volatile promptStatus_t prompt_status = PROMPT_READY;
51 volatile int count_eof = 0;
52 volatile bool die_on_error = false;
53
54 /* Save the prior command source */
55 FILE *prev_cmd_source;
56 bool prev_cmd_interactive;
57 uint64 prev_lineno;
58
59 /* Save old settings */
60 prev_cmd_source = pset.cur_cmd_source;
61 prev_cmd_interactive = pset.cur_cmd_interactive;
62 prev_lineno = pset.lineno;
63
64 /* Establish new source */
65 pset.cur_cmd_source = source;
66 pset.cur_cmd_interactive = ((source == stdin) && !pset.notty);
67 pset.lineno = 0;
68 pset.stmt_lineno = 1;
69
70 /* Create working state */
71 scan_state = psql_scan_create(&psqlscan_callbacks);
72
73 query_buf = createPQExpBuffer();
74 previous_buf = createPQExpBuffer();
75 history_buf = createPQExpBuffer();
76 if (PQExpBufferBroken(query_buf) ||
77 PQExpBufferBroken(previous_buf) ||
78 PQExpBufferBroken(history_buf))
79 {
80 psql_error("out of memory\n");
81 exit(EXIT_FAILURE);
82 }
83
84 /* main loop to get queries and execute them */
85 while (successResult == EXIT_SUCCESS)
86 {
87 /*
88 * Clean up after a previous Control-C
89 */
90 if (cancel_pressed)
91 {
92 if (!pset.cur_cmd_interactive)
93 {
94 /*
95 * You get here if you stopped a script with Ctrl-C.
96 */
97 successResult = EXIT_USER;
98 break;
99 }
100
101 cancel_pressed = false;
102 }
103
104 /*
105 * Establish longjmp destination for exiting from wait-for-input. We
106 * must re-do this each time through the loop for safety, since the
107 * jmpbuf might get changed during command execution.
108 */
109 if (sigsetjmp(sigint_interrupt_jmp, 1) != 0)
110 {
111 /* got here with longjmp */
112
113 /* reset parsing state */
114 psql_scan_finish(scan_state);
115 psql_scan_reset(scan_state);
116 resetPQExpBuffer(query_buf);
117 resetPQExpBuffer(history_buf);
118 count_eof = 0;
119 slashCmdStatus = PSQL_CMD_UNKNOWN;
120 prompt_status = PROMPT_READY;
121 pset.stmt_lineno = 1;
122 cancel_pressed = false;
123
124 if (pset.cur_cmd_interactive)
125 putc('\n', stdout);
126 else
127 {
128 successResult = EXIT_USER;
129 break;
130 }
131 }
132
133 fflush(stdout);
134
135 /*
136 * get another line
137 */
138 if (pset.cur_cmd_interactive)
139 {
140 /* May need to reset prompt, eg after \r command */
141 if (query_buf->len == 0)
142 prompt_status = PROMPT_READY;
143 line = gets_interactive(get_prompt(prompt_status), query_buf);
144 }
145 else
146 {
147 line = gets_fromFile(source);
148 if (!line && ferror(source))
149 successResult = EXIT_FAILURE;
150 }
151
152 /*
153 * query_buf holds query already accumulated. line is the malloc'd
154 * new line of input (note it must be freed before looping around!)
155 */
156
157 /* No more input. Time to quit, or \i done */
158 if (line == NULL)
159 {
160 if (pset.cur_cmd_interactive)
161 {
162 /* This tries to mimic bash's IGNOREEOF feature. */
163 count_eof++;
164
165 if (count_eof < GetVariableNum(pset.vars, "IGNOREEOF", 0, 10, false))
166 {
167 if (!pset.quiet)
168 printf(_("Use \"\\q\" to leave %s.\n"), pset.progname);
169 continue;
170 }
171
172 puts(pset.quiet ? "" : "\\q");
173 }
174 break;
175 }
176
177 count_eof = 0;
178
179 pset.lineno++;
180
181 /* ignore UTF-8 Unicode byte-order mark */
182 if (pset.lineno == 1 && pset.encoding == PG_UTF8 && strncmp(line, "\xef\xbb\xbf", 3) == 0)
183 memmove(line, line + 3, strlen(line + 3) + 1);
184
185 /* Detect attempts to run custom-format dumps as SQL scripts */
186 if (pset.lineno == 1 && !pset.cur_cmd_interactive &&
187 strncmp(line, "PGDMP", 5) == 0)
188 {
189 free(line);
190 puts(_("The input is a PostgreSQL custom-format dump.\n"
191 "Use the pg_restore command-line client to restore this dump to a database.\n"));
192 fflush(stdout);
193 successResult = EXIT_FAILURE;
194 break;
195 }
196
197 /* no further processing of empty lines, unless within a literal */
198 if (line[0] == '\0' && !psql_scan_in_quote(scan_state))
199 {
200 free(line);
201 continue;
202 }
203
204 /* A request for help? Be friendly and give them some guidance */
205 if (pset.cur_cmd_interactive && query_buf->len == 0 &&
206 pg_strncasecmp(line, "help", 4) == 0 &&
207 (line[4] == '\0' || line[4] == ';' || isspace((unsigned char) line[4])))
208 {
209 free(line);
210 puts(_("You are using psql, the command-line interface to PostgreSQL."));
211 printf(_("Type: \\copyright for distribution terms\n"
212 " \\h for help with SQL commands\n"
213 " \\? for help with psql commands\n"
214 " \\g or terminate with semicolon to execute query\n"
215 " \\q to quit\n"));
216
217 fflush(stdout);
218 continue;
219 }
220
221 /* echo back if flag is set, unless interactive */
222 if (pset.echo == PSQL_ECHO_ALL && !pset.cur_cmd_interactive)
223 {
224 puts(line);
225 fflush(stdout);
226 }
227
228 /* insert newlines into query buffer between source lines */
229 if (query_buf->len > 0)
230 {
231 appendPQExpBufferChar(query_buf, '\n');
232 added_nl_pos = query_buf->len;
233 }
234 else
235 added_nl_pos = -1; /* flag we didn't add one */
236
237 /* Setting this will not have effect until next line. */
238 die_on_error = pset.on_error_stop;
239
240 /*
241 * Parse line, looking for command separators.
242 */
243 psql_scan_setup(scan_state, line, strlen(line),
244 pset.encoding, standard_strings());
245 success = true;
246 line_saved_in_history = false;
247
248 while (success || !die_on_error)
249 {
250 PsqlScanResult scan_result;
251 promptStatus_t prompt_tmp = prompt_status;
252 size_t pos_in_query;
253 char *tmp_line;
254
255 pos_in_query = query_buf->len;
256 scan_result = psql_scan(scan_state, query_buf, &prompt_tmp);
257 prompt_status = prompt_tmp;
258
259 if (PQExpBufferBroken(query_buf))
260 {
261 psql_error("out of memory\n");
262 exit(EXIT_FAILURE);
263 }
264
265 /*
266 * Increase statement line number counter for each linebreak added
267 * to the query buffer by the last psql_scan() call. There only
268 * will be ones to add when navigating to a statement in
269 * readline's history containing newlines.
270 */
271 tmp_line = query_buf->data + pos_in_query;
272 while (*tmp_line != '\0')
273 {
274 if (*(tmp_line++) == '\n')
275 pset.stmt_lineno++;
276 }
277
278 if (scan_result == PSCAN_EOL)
279 pset.stmt_lineno++;
280
281 /*
282 * Send command if semicolon found, or if end of line and we're in
283 * single-line mode.
284 */
285 if (scan_result == PSCAN_SEMICOLON ||
286 (scan_result == PSCAN_EOL && pset.singleline))
287 {
288 /*
289 * Save query in history. We use history_buf to accumulate
290 * multi-line queries into a single history entry.
291 */
292 if (pset.cur_cmd_interactive && !line_saved_in_history)
293 {
294 pg_append_history(line, history_buf);
295 pg_send_history(history_buf);
296 line_saved_in_history = true;
297 }
298
299 /* execute query */
300 success = SendQuery(query_buf->data);
301 slashCmdStatus = success ? PSQL_CMD_SEND : PSQL_CMD_ERROR;
302 pset.stmt_lineno = 1;
303
304 /* transfer query to previous_buf by pointer-swapping */
305 {
306 PQExpBuffer swap_buf = previous_buf;
307
308 previous_buf = query_buf;
309 query_buf = swap_buf;
310 }
311 resetPQExpBuffer(query_buf);
312
313 added_nl_pos = -1;
314 /* we need not do psql_scan_reset() here */
315 }
316 else if (scan_result == PSCAN_BACKSLASH)
317 {
318 /* handle backslash command */
319
320 /*
321 * If we added a newline to query_buf, and nothing else has
322 * been inserted in query_buf by the lexer, then strip off the
323 * newline again. This avoids any change to query_buf when a
324 * line contains only a backslash command. Also, in this
325 * situation we force out any previous lines as a separate
326 * history entry; we don't want SQL and backslash commands
327 * intermixed in history if at all possible.
328 */
329 if (query_buf->len == added_nl_pos)
330 {
331 query_buf->data[--query_buf->len] = '\0';
332 pg_send_history(history_buf);
333 }
334 added_nl_pos = -1;
335
336 /* save backslash command in history */
337 if (pset.cur_cmd_interactive && !line_saved_in_history)
338 {
339 pg_append_history(line, history_buf);
340 pg_send_history(history_buf);
341 line_saved_in_history = true;
342 }
343
344 /* execute backslash command */
345 slashCmdStatus = HandleSlashCmds(scan_state,
346 query_buf->len > 0 ?
347 query_buf : previous_buf);
348
349 success = slashCmdStatus != PSQL_CMD_ERROR;
350 pset.stmt_lineno = 1;
351
352 if ((slashCmdStatus == PSQL_CMD_SEND || slashCmdStatus == PSQL_CMD_NEWEDIT) &&
353 query_buf->len == 0)
354 {
355 /* copy previous buffer to current for handling */
356 appendPQExpBufferStr(query_buf, previous_buf->data);
357 }
358
359 if (slashCmdStatus == PSQL_CMD_SEND)
360 {
361 success = SendQuery(query_buf->data);
362
363 /* transfer query to previous_buf by pointer-swapping */
364 {
365 PQExpBuffer swap_buf = previous_buf;
366
367 previous_buf = query_buf;
368 query_buf = swap_buf;
369 }
370 resetPQExpBuffer(query_buf);
371
372 /* flush any paren nesting info after forced send */
373 psql_scan_reset(scan_state);
374 }
375 else if (slashCmdStatus == PSQL_CMD_NEWEDIT)
376 {
377 /* rescan query_buf as new input */
378 psql_scan_finish(scan_state);
379 free(line);
380 line = pg_strdup(query_buf->data);
381 resetPQExpBuffer(query_buf);
382 /* reset parsing state since we are rescanning whole line */
383 psql_scan_reset(scan_state);
384 psql_scan_setup(scan_state, line, strlen(line),
385 pset.encoding, standard_strings());
386 line_saved_in_history = false;
387 prompt_status = PROMPT_READY;
388 }
389 else if (slashCmdStatus == PSQL_CMD_TERMINATE)
390 break;
391 }
392
393 /* fall out of loop if lexer reached EOL */
394 if (scan_result == PSCAN_INCOMPLETE ||
395 scan_result == PSCAN_EOL)
396 break;
397 }
398
399 /* Add line to pending history if we didn't execute anything yet */
400 if (pset.cur_cmd_interactive && !line_saved_in_history)
401 pg_append_history(line, history_buf);
402
403 psql_scan_finish(scan_state);
404 free(line);
405
406 if (slashCmdStatus == PSQL_CMD_TERMINATE)
407 {
408 successResult = EXIT_SUCCESS;
409 break;
410 }
411
412 if (!pset.cur_cmd_interactive)
413 {
414 if (!success && die_on_error)
415 successResult = EXIT_USER;
416 /* Have we lost the db connection? */
417 else if (!pset.db)
418 successResult = EXIT_BADCONN;
419 }
420 } /* while !endoffile/session */
421
422 /*
423 * Process query at the end of file without a semicolon
424 */
425 if (query_buf->len > 0 && !pset.cur_cmd_interactive &&
426 successResult == EXIT_SUCCESS)
427 {
428 /* save query in history */
429 if (pset.cur_cmd_interactive)
430 pg_send_history(history_buf);
431
432 /* execute query */
433 success = SendQuery(query_buf->data);
434
435 if (!success && die_on_error)
436 successResult = EXIT_USER;
437 else if (pset.db == NULL)
438 successResult = EXIT_BADCONN;
439 }
440
441 /*
442 * Let's just make real sure the SIGINT handler won't try to use
443 * sigint_interrupt_jmp after we exit this routine. If there is an outer
444 * MainLoop instance, it will reset sigint_interrupt_jmp to point to
445 * itself at the top of its loop, before any further interactive input
446 * happens.
447 */
448 sigint_interrupt_enabled = false;
449
450 destroyPQExpBuffer(query_buf);
451 destroyPQExpBuffer(previous_buf);
452 destroyPQExpBuffer(history_buf);
453
454 psql_scan_destroy(scan_state);
455
456 pset.cur_cmd_source = prev_cmd_source;
457 pset.cur_cmd_interactive = prev_cmd_interactive;
458 pset.lineno = prev_lineno;
459
460 return successResult;
461 } /* MainLoop() */
462