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