Line data Source code
1 : /*
2 : * psql - the PostgreSQL interactive terminal
3 : *
4 : * Copyright (c) 2000-2017, PostgreSQL Global Development Group
5 : *
6 : * src/bin/psql/input.c
7 : */
8 : #include "postgres_fe.h"
9 :
10 : #ifndef WIN32
11 : #include <unistd.h>
12 : #endif
13 : #include <fcntl.h>
14 : #include <limits.h>
15 :
16 : #include "input.h"
17 : #include "settings.h"
18 : #include "tab-complete.h"
19 : #include "common.h"
20 :
21 : #ifndef WIN32
22 : #define PSQLHISTORY ".psql_history"
23 : #else
24 : #define PSQLHISTORY "psql_history"
25 : #endif
26 :
27 : /* Runtime options for turning off readline and history */
28 : /* (of course there is no runtime command for doing that :) */
29 : #ifdef USE_READLINE
30 : static bool useReadline;
31 : static bool useHistory;
32 :
33 : static char *psql_history;
34 :
35 : static int history_lines_added;
36 :
37 :
38 : /*
39 : * Preserve newlines in saved queries by mapping '\n' to NL_IN_HISTORY
40 : *
41 : * It is assumed NL_IN_HISTORY will never be entered by the user
42 : * nor appear inside a multi-byte string. 0x00 is not properly
43 : * handled by the readline routines so it can not be used
44 : * for this purpose.
45 : */
46 : #define NL_IN_HISTORY 0x01
47 : #endif
48 :
49 : static void finishInput(void);
50 :
51 :
52 : /*
53 : * gets_interactive()
54 : *
55 : * Gets a line of interactive input, using readline if desired.
56 : *
57 : * prompt: the prompt string to be used
58 : * query_buf: buffer containing lines already read in the current command
59 : * (query_buf is not modified here, but may be consulted for tab completion)
60 : *
61 : * The result is a malloc'd string.
62 : *
63 : * Caller *must* have set up sigint_interrupt_jmp before calling.
64 : */
65 : char *
66 0 : gets_interactive(const char *prompt, PQExpBuffer query_buf)
67 : {
68 : #ifdef USE_READLINE
69 0 : if (useReadline)
70 : {
71 : char *result;
72 :
73 : /*
74 : * Some versions of readline don't notice SIGWINCH signals that arrive
75 : * when not actively reading input. The simplest fix is to always
76 : * re-read the terminal size. This leaves a window for SIGWINCH to be
77 : * missed between here and where readline() enables libreadline's
78 : * signal handler, but that's probably short enough to be ignored.
79 : */
80 : #ifdef HAVE_RL_RESET_SCREEN_SIZE
81 0 : rl_reset_screen_size();
82 : #endif
83 :
84 : /* Make current query_buf available to tab completion callback */
85 0 : tab_completion_query_buf = query_buf;
86 :
87 : /* Enable SIGINT to longjmp to sigint_interrupt_jmp */
88 0 : sigint_interrupt_enabled = true;
89 :
90 : /* On some platforms, readline is declared as readline(char *) */
91 0 : result = readline((char *) prompt);
92 :
93 : /* Disable SIGINT again */
94 0 : sigint_interrupt_enabled = false;
95 :
96 : /* Pure neatnik-ism */
97 0 : tab_completion_query_buf = NULL;
98 :
99 0 : return result;
100 : }
101 : #endif
102 :
103 0 : fputs(prompt, stdout);
104 0 : fflush(stdout);
105 0 : return gets_fromFile(stdin);
106 : }
107 :
108 :
109 : /*
110 : * Append the line to the history buffer, making sure there is a trailing '\n'
111 : */
112 : void
113 0 : pg_append_history(const char *s, PQExpBuffer history_buf)
114 : {
115 : #ifdef USE_READLINE
116 0 : if (useHistory && s)
117 : {
118 0 : appendPQExpBufferStr(history_buf, s);
119 0 : if (!s[0] || s[strlen(s) - 1] != '\n')
120 0 : appendPQExpBufferChar(history_buf, '\n');
121 : }
122 : #endif
123 0 : }
124 :
125 :
126 : /*
127 : * Emit accumulated history entry to readline's history mechanism,
128 : * then reset the buffer to empty.
129 : *
130 : * Note: we write nothing if history_buf is empty, so extra calls to this
131 : * function don't hurt. There must have been at least one line added by
132 : * pg_append_history before we'll do anything.
133 : */
134 : void
135 12 : pg_send_history(PQExpBuffer history_buf)
136 : {
137 : #ifdef USE_READLINE
138 : static char *prev_hist = NULL;
139 :
140 12 : char *s = history_buf->data;
141 : int i;
142 :
143 : /* Trim any trailing \n's (OK to scribble on history_buf) */
144 12 : for (i = strlen(s) - 1; i >= 0 && s[i] == '\n'; i--)
145 : ;
146 12 : s[i + 1] = '\0';
147 :
148 12 : if (useHistory && s[0])
149 : {
150 0 : if (((pset.histcontrol & hctl_ignorespace) &&
151 0 : s[0] == ' ') ||
152 0 : ((pset.histcontrol & hctl_ignoredups) &&
153 0 : prev_hist && strcmp(s, prev_hist) == 0))
154 : {
155 : /* Ignore this line as far as history is concerned */
156 : }
157 : else
158 : {
159 : /* Save each previous line for ignoredups processing */
160 0 : if (prev_hist)
161 0 : free(prev_hist);
162 0 : prev_hist = pg_strdup(s);
163 : /* And send it to readline */
164 0 : add_history(s);
165 : /* Count lines added to history for use later */
166 0 : history_lines_added++;
167 : }
168 : }
169 :
170 12 : resetPQExpBuffer(history_buf);
171 : #endif
172 12 : }
173 :
174 :
175 : /*
176 : * gets_fromFile
177 : *
178 : * Gets a line of noninteractive input from a file (which could be stdin).
179 : * The result is a malloc'd string, or NULL on EOF or input error.
180 : *
181 : * Caller *must* have set up sigint_interrupt_jmp before calling.
182 : *
183 : * Note: we re-use a static PQExpBuffer for each call. This is to avoid
184 : * leaking memory if interrupted by SIGINT.
185 : */
186 : char *
187 58507 : gets_fromFile(FILE *source)
188 : {
189 : static PQExpBuffer buffer = NULL;
190 :
191 : char line[1024];
192 :
193 58507 : if (buffer == NULL) /* first time through? */
194 180 : buffer = createPQExpBuffer();
195 : else
196 58327 : resetPQExpBuffer(buffer);
197 :
198 : for (;;)
199 : {
200 : char *result;
201 :
202 : /* Enable SIGINT to longjmp to sigint_interrupt_jmp */
203 58507 : sigint_interrupt_enabled = true;
204 :
205 : /* Get some data */
206 58507 : result = fgets(line, sizeof(line), source);
207 :
208 : /* Disable SIGINT again */
209 58507 : sigint_interrupt_enabled = false;
210 :
211 : /* EOF or error? */
212 58507 : if (result == NULL)
213 : {
214 180 : if (ferror(source))
215 : {
216 0 : psql_error("could not read from input file: %s\n",
217 0 : strerror(errno));
218 0 : return NULL;
219 : }
220 180 : break;
221 : }
222 :
223 58327 : appendPQExpBufferStr(buffer, line);
224 :
225 58327 : if (PQExpBufferBroken(buffer))
226 : {
227 0 : psql_error("out of memory\n");
228 0 : return NULL;
229 : }
230 :
231 : /* EOL? */
232 58327 : if (buffer->len > 0 && buffer->data[buffer->len - 1] == '\n')
233 : {
234 58327 : buffer->data[buffer->len - 1] = '\0';
235 58327 : return pg_strdup(buffer->data);
236 : }
237 0 : }
238 :
239 180 : if (buffer->len > 0) /* EOF after reading some bufferload(s) */
240 0 : return pg_strdup(buffer->data);
241 :
242 : /* EOF, so return null */
243 180 : return NULL;
244 : }
245 :
246 :
247 : #ifdef USE_READLINE
248 :
249 : /*
250 : * Macros to iterate over each element of the history list in order
251 : *
252 : * You would think this would be simple enough, but in its inimitable fashion
253 : * libedit has managed to break it: in libreadline we must use next_history()
254 : * to go from oldest to newest, but in libedit we must use previous_history().
255 : * To detect what to do, we make a trial call of previous_history(): if it
256 : * fails, then either next_history() is what to use, or there's zero or one
257 : * history entry so that it doesn't matter which direction we go.
258 : *
259 : * In case that wasn't disgusting enough: the code below is not as obvious as
260 : * it might appear. In some libedit releases history_set_pos(0) fails until
261 : * at least one add_history() call has been done. This is not an issue for
262 : * printHistory() or encode_history(), which cannot be invoked before that has
263 : * happened. In decode_history(), that's not so, and what actually happens is
264 : * that we are sitting on the newest entry to start with, previous_history()
265 : * fails, and we iterate over all the entries using next_history(). So the
266 : * decode_history() loop iterates over the entries in the wrong order when
267 : * using such a libedit release, and if there were another attempt to use
268 : * BEGIN_ITERATE_HISTORY() before some add_history() call had happened, it
269 : * wouldn't work. Fortunately we don't care about either of those things.
270 : *
271 : * Usage pattern is:
272 : *
273 : * BEGIN_ITERATE_HISTORY(varname);
274 : * {
275 : * loop body referencing varname->line;
276 : * }
277 : * END_ITERATE_HISTORY();
278 : */
279 : #define BEGIN_ITERATE_HISTORY(VARNAME) \
280 : do { \
281 : HIST_ENTRY *VARNAME; \
282 : bool use_prev_; \
283 : \
284 : history_set_pos(0); \
285 : use_prev_ = (previous_history() != NULL); \
286 : history_set_pos(0); \
287 : for (VARNAME = current_history(); VARNAME != NULL; \
288 : VARNAME = use_prev_ ? previous_history() : next_history()) \
289 : { \
290 : (void) 0
291 :
292 : #define END_ITERATE_HISTORY() \
293 : } \
294 : } while(0)
295 :
296 :
297 : /*
298 : * Convert newlines to NL_IN_HISTORY for safe saving in readline history file
299 : */
300 : static void
301 0 : encode_history(void)
302 : {
303 0 : BEGIN_ITERATE_HISTORY(cur_hist);
304 : {
305 : char *cur_ptr;
306 :
307 : /* some platforms declare HIST_ENTRY.line as const char * */
308 0 : for (cur_ptr = (char *) cur_hist->line; *cur_ptr; cur_ptr++)
309 : {
310 0 : if (*cur_ptr == '\n')
311 0 : *cur_ptr = NL_IN_HISTORY;
312 : }
313 : }
314 : END_ITERATE_HISTORY();
315 0 : }
316 :
317 : /*
318 : * Reverse the above encoding
319 : */
320 : static void
321 0 : decode_history(void)
322 : {
323 0 : BEGIN_ITERATE_HISTORY(cur_hist);
324 : {
325 : char *cur_ptr;
326 :
327 : /* some platforms declare HIST_ENTRY.line as const char * */
328 0 : for (cur_ptr = (char *) cur_hist->line; *cur_ptr; cur_ptr++)
329 : {
330 0 : if (*cur_ptr == NL_IN_HISTORY)
331 0 : *cur_ptr = '\n';
332 : }
333 : }
334 : END_ITERATE_HISTORY();
335 0 : }
336 : #endif /* USE_READLINE */
337 :
338 :
339 : /*
340 : * Put any startup stuff related to input in here. It's good to maintain
341 : * abstraction this way.
342 : *
343 : * The only "flag" right now is 1 for use readline & history.
344 : */
345 : void
346 0 : initializeInput(int flags)
347 : {
348 : #ifdef USE_READLINE
349 0 : if (flags & 1)
350 : {
351 : const char *histfile;
352 : char home[MAXPGPATH];
353 :
354 0 : useReadline = true;
355 :
356 : /* these two things must be done in this order: */
357 0 : initialize_readline();
358 0 : rl_initialize();
359 :
360 0 : useHistory = true;
361 0 : using_history();
362 0 : history_lines_added = 0;
363 :
364 0 : histfile = GetVariable(pset.vars, "HISTFILE");
365 :
366 0 : if (histfile == NULL)
367 : {
368 : char *envhist;
369 :
370 0 : envhist = getenv("PSQL_HISTORY");
371 0 : if (envhist != NULL && strlen(envhist) > 0)
372 0 : histfile = envhist;
373 : }
374 :
375 0 : if (histfile == NULL)
376 : {
377 0 : if (get_home_path(home))
378 0 : psql_history = psprintf("%s/%s", home, PSQLHISTORY);
379 : }
380 : else
381 : {
382 0 : psql_history = pg_strdup(histfile);
383 0 : expand_tilde(&psql_history);
384 : }
385 :
386 0 : if (psql_history)
387 : {
388 0 : read_history(psql_history);
389 0 : decode_history();
390 : }
391 : }
392 : #endif
393 :
394 0 : atexit(finishInput);
395 0 : }
396 :
397 :
398 : /*
399 : * This function saves the readline history when psql exits.
400 : *
401 : * fname: pathname of history file. (Should really be "const char *",
402 : * but some ancient versions of readline omit the const-decoration.)
403 : *
404 : * max_lines: if >= 0, limit history file to that many entries.
405 : */
406 : #ifdef USE_READLINE
407 : static bool
408 0 : saveHistory(char *fname, int max_lines)
409 : {
410 : int errnum;
411 :
412 : /*
413 : * Suppressing the write attempt when HISTFILE is set to /dev/null may
414 : * look like a negligible optimization, but it's necessary on e.g. macOS,
415 : * where write_history will fail because it tries to chmod the target
416 : * file.
417 : */
418 0 : if (strcmp(fname, DEVNULL) != 0)
419 : {
420 : /*
421 : * Encode \n, since otherwise readline will reload multiline history
422 : * entries as separate lines. (libedit doesn't really need this, but
423 : * we do it anyway since it's too hard to tell which implementation we
424 : * are using.)
425 : */
426 0 : encode_history();
427 :
428 : /*
429 : * On newer versions of libreadline, truncate the history file as
430 : * needed and then append what we've added. This avoids overwriting
431 : * history from other concurrent sessions (although there are still
432 : * race conditions when two sessions exit at about the same time). If
433 : * we don't have those functions, fall back to write_history().
434 : */
435 : #if defined(HAVE_HISTORY_TRUNCATE_FILE) && defined(HAVE_APPEND_HISTORY)
436 : {
437 : int nlines;
438 : int fd;
439 :
440 : /* truncate previous entries if needed */
441 0 : if (max_lines >= 0)
442 : {
443 0 : nlines = Max(max_lines - history_lines_added, 0);
444 0 : (void) history_truncate_file(fname, nlines);
445 : }
446 : /* append_history fails if file doesn't already exist :-( */
447 0 : fd = open(fname, O_CREAT | O_WRONLY | PG_BINARY, 0600);
448 0 : if (fd >= 0)
449 0 : close(fd);
450 : /* append the appropriate number of lines */
451 0 : if (max_lines >= 0)
452 0 : nlines = Min(max_lines, history_lines_added);
453 : else
454 0 : nlines = history_lines_added;
455 0 : errnum = append_history(nlines, fname);
456 0 : if (errnum == 0)
457 0 : return true;
458 : }
459 : #else /* don't have append support */
460 : {
461 : /* truncate what we have ... */
462 : if (max_lines >= 0)
463 : stifle_history(max_lines);
464 : /* ... and overwrite file. Tough luck for concurrent sessions. */
465 : errnum = write_history(fname);
466 : if (errnum == 0)
467 : return true;
468 : }
469 : #endif
470 :
471 0 : psql_error("could not save history to file \"%s\": %s\n",
472 : fname, strerror(errnum));
473 : }
474 0 : return false;
475 : }
476 : #endif
477 :
478 :
479 :
480 : /*
481 : * Print history to the specified file, or to the console if fname is NULL
482 : * (psql \s command)
483 : *
484 : * We used to use saveHistory() for this purpose, but that doesn't permit
485 : * use of a pager; moreover libedit's implementation behaves incompatibly
486 : * (preferring to encode its output) and may fail outright when the target
487 : * file is specified as /dev/tty.
488 : */
489 : bool
490 0 : printHistory(const char *fname, unsigned short int pager)
491 : {
492 : #ifdef USE_READLINE
493 : FILE *output;
494 : bool is_pager;
495 :
496 0 : if (!useHistory)
497 0 : return false;
498 :
499 0 : if (fname == NULL)
500 : {
501 : /* use pager, if enabled, when printing to console */
502 0 : output = PageOutput(INT_MAX, pager ? &(pset.popt.topt) : NULL);
503 0 : is_pager = true;
504 : }
505 : else
506 : {
507 0 : output = fopen(fname, "w");
508 0 : if (output == NULL)
509 : {
510 0 : psql_error("could not save history to file \"%s\": %s\n",
511 0 : fname, strerror(errno));
512 0 : return false;
513 : }
514 0 : is_pager = false;
515 : }
516 :
517 0 : BEGIN_ITERATE_HISTORY(cur_hist);
518 : {
519 0 : fprintf(output, "%s\n", cur_hist->line);
520 : }
521 : END_ITERATE_HISTORY();
522 :
523 0 : if (is_pager)
524 0 : ClosePager(output);
525 : else
526 0 : fclose(output);
527 :
528 0 : return true;
529 : #else
530 : psql_error("history is not supported by this installation\n");
531 : return false;
532 : #endif
533 : }
534 :
535 :
536 : static void
537 0 : finishInput(void)
538 : {
539 : #ifdef USE_READLINE
540 0 : if (useHistory && psql_history)
541 : {
542 0 : (void) saveHistory(psql_history, pset.histsize);
543 0 : free(psql_history);
544 0 : psql_history = NULL;
545 : }
546 : #endif
547 0 : }
|