1 /*
2 * psql - the PostgreSQL interactive terminal
3 *
4 * Copyright (c) 2000-2016, 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 *
gets_interactive(const char * prompt,PQExpBuffer query_buf)66 gets_interactive(const char *prompt, PQExpBuffer query_buf)
67 {
68 #ifdef USE_READLINE
69 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 rl_reset_screen_size();
82 #endif
83
84 /* Make current query_buf available to tab completion callback */
85 tab_completion_query_buf = query_buf;
86
87 /* Enable SIGINT to longjmp to sigint_interrupt_jmp */
88 sigint_interrupt_enabled = true;
89
90 /* On some platforms, readline is declared as readline(char *) */
91 result = readline((char *) prompt);
92
93 /* Disable SIGINT again */
94 sigint_interrupt_enabled = false;
95
96 /* Pure neatnik-ism */
97 tab_completion_query_buf = NULL;
98
99 return result;
100 }
101 #endif
102
103 fputs(prompt, stdout);
104 fflush(stdout);
105 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
pg_append_history(const char * s,PQExpBuffer history_buf)113 pg_append_history(const char *s, PQExpBuffer history_buf)
114 {
115 #ifdef USE_READLINE
116 if (useHistory && s)
117 {
118 appendPQExpBufferStr(history_buf, s);
119 if (!s[0] || s[strlen(s) - 1] != '\n')
120 appendPQExpBufferChar(history_buf, '\n');
121 }
122 #endif
123 }
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
pg_send_history(PQExpBuffer history_buf)135 pg_send_history(PQExpBuffer history_buf)
136 {
137 #ifdef USE_READLINE
138 static char *prev_hist = NULL;
139
140 char *s = history_buf->data;
141 int i;
142
143 /* Trim any trailing \n's (OK to scribble on history_buf) */
144 for (i = strlen(s) - 1; i >= 0 && s[i] == '\n'; i--)
145 ;
146 s[i + 1] = '\0';
147
148 if (useHistory && s[0])
149 {
150 if (((pset.histcontrol & hctl_ignorespace) &&
151 s[0] == ' ') ||
152 ((pset.histcontrol & hctl_ignoredups) &&
153 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 if (prev_hist)
161 free(prev_hist);
162 prev_hist = pg_strdup(s);
163 /* And send it to readline */
164 add_history(s);
165 /* Count lines added to history for use later */
166 history_lines_added++;
167 }
168 }
169
170 resetPQExpBuffer(history_buf);
171 #endif
172 }
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 *
gets_fromFile(FILE * source)187 gets_fromFile(FILE *source)
188 {
189 static PQExpBuffer buffer = NULL;
190
191 char line[1024];
192
193 if (buffer == NULL) /* first time through? */
194 buffer = createPQExpBuffer();
195 else
196 resetPQExpBuffer(buffer);
197
198 for (;;)
199 {
200 char *result;
201
202 /* Enable SIGINT to longjmp to sigint_interrupt_jmp */
203 sigint_interrupt_enabled = true;
204
205 /* Get some data */
206 result = fgets(line, sizeof(line), source);
207
208 /* Disable SIGINT again */
209 sigint_interrupt_enabled = false;
210
211 /* EOF or error? */
212 if (result == NULL)
213 {
214 if (ferror(source))
215 {
216 psql_error("could not read from input file: %s\n",
217 strerror(errno));
218 return NULL;
219 }
220 break;
221 }
222
223 appendPQExpBufferStr(buffer, line);
224
225 if (PQExpBufferBroken(buffer))
226 {
227 psql_error("out of memory\n");
228 return NULL;
229 }
230
231 /* EOL? */
232 if (buffer->len > 0 && buffer->data[buffer->len - 1] == '\n')
233 {
234 buffer->data[buffer->len - 1] = '\0';
235 return pg_strdup(buffer->data);
236 }
237 }
238
239 if (buffer->len > 0) /* EOF after reading some bufferload(s) */
240 return pg_strdup(buffer->data);
241
242 /* EOF, so return null */
243 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
encode_history(void)301 encode_history(void)
302 {
303 BEGIN_ITERATE_HISTORY(cur_hist);
304 {
305 char *cur_ptr;
306
307 /* some platforms declare HIST_ENTRY.line as const char * */
308 for (cur_ptr = (char *) cur_hist->line; *cur_ptr; cur_ptr++)
309 {
310 if (*cur_ptr == '\n')
311 *cur_ptr = NL_IN_HISTORY;
312 }
313 }
314 END_ITERATE_HISTORY();
315 }
316
317 /*
318 * Reverse the above encoding
319 */
320 static void
decode_history(void)321 decode_history(void)
322 {
323 BEGIN_ITERATE_HISTORY(cur_hist);
324 {
325 char *cur_ptr;
326
327 /* some platforms declare HIST_ENTRY.line as const char * */
328 for (cur_ptr = (char *) cur_hist->line; *cur_ptr; cur_ptr++)
329 {
330 if (*cur_ptr == NL_IN_HISTORY)
331 *cur_ptr = '\n';
332 }
333 }
334 END_ITERATE_HISTORY();
335 }
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
initializeInput(int flags)346 initializeInput(int flags)
347 {
348 #ifdef USE_READLINE
349 if (flags & 1)
350 {
351 const char *histfile;
352 char home[MAXPGPATH];
353
354 useReadline = true;
355
356 /* these two things must be done in this order: */
357 initialize_readline();
358 rl_initialize();
359
360 useHistory = true;
361 using_history();
362 history_lines_added = 0;
363
364 histfile = GetVariable(pset.vars, "HISTFILE");
365
366 if (histfile == NULL)
367 {
368 char *envhist;
369
370 envhist = getenv("PSQL_HISTORY");
371 if (envhist != NULL && strlen(envhist) > 0)
372 histfile = envhist;
373 }
374
375 if (histfile == NULL)
376 {
377 if (get_home_path(home))
378 psql_history = psprintf("%s/%s", home, PSQLHISTORY);
379 }
380 else
381 {
382 psql_history = pg_strdup(histfile);
383 expand_tilde(&psql_history);
384 }
385
386 if (psql_history)
387 {
388 read_history(psql_history);
389 decode_history();
390 }
391 }
392 #endif
393
394 atexit(finishInput);
395 }
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
saveHistory(char * fname,int max_lines)408 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. Darwin,
415 * where write_history will fail because it tries to chmod the target
416 * file.
417 */
418 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 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 if (max_lines >= 0)
442 {
443 nlines = Max(max_lines - history_lines_added, 0);
444 (void) history_truncate_file(fname, nlines);
445 }
446 /* append_history fails if file doesn't already exist :-( */
447 fd = open(fname, O_CREAT | O_WRONLY | PG_BINARY, 0600);
448 if (fd >= 0)
449 close(fd);
450 /* append the appropriate number of lines */
451 if (max_lines >= 0)
452 nlines = Min(max_lines, history_lines_added);
453 else
454 nlines = history_lines_added;
455 errnum = append_history(nlines, fname);
456 if (errnum == 0)
457 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 psql_error("could not save history to file \"%s\": %s\n",
472 fname, strerror(errnum));
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 */
489 bool
printHistory(const char * fname,unsigned short int pager)490 printHistory(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 psql_error("could not save history to file \"%s\": %s\n",
511 fname, strerror(errno));
512 return false;
513 }
514 is_pager = false;
515 }
516
517 BEGIN_ITERATE_HISTORY(cur_hist);
518 {
519 fprintf(output, "%s\n", cur_hist->line);
520 }
521 END_ITERATE_HISTORY();
522
523 if (is_pager)
524 ClosePager(output);
525 else
526 fclose(output);
527
528 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
finishInput(void)537 finishInput(void)
538 {
539 #ifdef USE_READLINE
540 if (useHistory && psql_history)
541 {
542 int hist_size;
543
544 hist_size = GetVariableNum(pset.vars, "HISTSIZE", 500, -1, true);
545 (void) saveHistory(psql_history, hist_size);
546 free(psql_history);
547 psql_history = NULL;
548 }
549 #endif
550 }
551