xref: /illumos-gate/usr/src/lib/libtecla/common/getline.c (revision ce326879a41b052db3abafb44e551f9d9c40cdba)
1 /*
2  * Copyright (c) 2000, 2001, 2002, 2003, 2004 by Martin C. Shepherd.
3  *
4  * All rights reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, and/or sell copies of the Software, and to permit persons
11  * to whom the Software is furnished to do so, provided that the above
12  * copyright notice(s) and this permission notice appear in all copies of
13  * the Software and that both the above copyright notice(s) and this
14  * permission notice appear in supporting documentation.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
19  * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20  * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
21  * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
22  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
23  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
24  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25  *
26  * Except as contained in this notice, the name of a copyright holder
27  * shall not be used in advertising or otherwise to promote the sale, use
28  * or other dealings in this Software without prior written authorization
29  * of the copyright holder.
30  */
31 
32 /*
33  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
34  * Use is subject to license terms.
35  * Copyright (c) 2016 by Delphix. All rights reserved.
36  */
37 
38 #pragma ident	"%Z%%M%	%I%	%E% SMI"
39 
40 /*
41  * Standard headers.
42  */
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <signal.h>
46 #include <string.h>
47 #include <errno.h>
48 #include <ctype.h>
49 #include <setjmp.h>
50 #include <stdarg.h>
51 
52 /*
53  * UNIX headers.
54  */
55 #include <sys/ioctl.h>
56 #ifdef HAVE_SELECT
57 #ifdef HAVE_SYS_SELECT_H
58 #include <sys/select.h>
59 #endif
60 #include <sys/time.h>
61 #include <sys/types.h>
62 #endif
63 
64 /*
65  * Handle the different sources of terminal control string and size
66  * information. Note that if no terminal information database is available,
67  * ANSI VT100 control sequences are used.
68  */
69 #if defined(USE_TERMINFO) || defined(USE_TERMCAP)
70 /*
71  * Include curses.h or ncurses/curses.h depending on which is available.
72  */
73 #ifdef HAVE_CURSES_H
74 #include <curses.h>
75 #elif defined(HAVE_NCURSES_CURSES_H)
76 #include <ncurses/curses.h>
77 #endif
78 /*
79  * Include term.h where available.
80  */
81 #if defined(HAVE_TERM_H)
82 #include <term.h>
83 #elif defined(HAVE_NCURSES_TERM_H)
84 #include <ncurses/term.h>
85 #endif
86 /*
87  * When using termcap, include termcap.h on systems that have it.
88  * Otherwise assume that all prototypes are provided by curses.h.
89  */
90 #if defined(USE_TERMCAP) && defined(HAVE_TERMCAP_H)
91 #include <termcap.h>
92 #endif
93 
94 /*
95  * Under Solaris default Curses the output function that tputs takes is
96  * declared to have a char argument. On all other systems and on Solaris
97  * X/Open Curses (Issue 4, Version 2) it expects an int argument (using
98  * c89 or options -I /usr/xpg4/include -L /usr/xpg4/lib -R /usr/xpg4/lib
99  * selects XPG4v2 Curses on Solaris 2.6 and later).
100  *
101  * Similarly, under Mac OS X, the return value of the tputs output
102  * function is declared as void, whereas it is declared as int on
103  * other systems.
104  */
105 #if defined __sun && defined __SVR4 && !defined _XOPEN_CURSES
106 typedef int TputsRetType;
107 typedef char TputsArgType;              /* int tputs(char c, FILE *fp) */
108 #define TPUTS_RETURNS_VALUE 1
109 #elif defined(__APPLE__) && defined(__MACH__)
110 typedef void TputsRetType;
111 typedef int TputsArgType;               /* void tputs(int c, FILE *fp) */
112 #define TPUTS_RETURNS_VALUE 0
113 #else
114 typedef int TputsRetType;
115 typedef int TputsArgType;               /* int tputs(int c, FILE *fp) */
116 #define TPUTS_RETURNS_VALUE 1
117 #endif
118 
119 /*
120  * Use the above specifications to prototype our tputs callback function.
121  */
122 static TputsRetType gl_tputs_putchar(TputsArgType c);
123 
124 #endif  /* defined(USE_TERMINFO) || defined(USE_TERMCAP) */
125 
126 /*
127  * If the library is being compiled without filesystem access facilities,
128  * ensure that none of the action functions that normally do access the
129  * filesystem are bound by default, and that it they do get bound, that
130  * they don't do anything.
131  */
132 #if WITHOUT_FILE_SYSTEM
133 #define HIDE_FILE_SYSTEM
134 #endif
135 
136 /*
137  * POSIX headers.
138  */
139 #include <unistd.h>
140 #include <fcntl.h>
141 #include <termios.h>
142 
143 /*
144  * Provide typedefs for standard POSIX structures.
145  */
146 typedef struct sigaction SigAction;
147 typedef struct termios Termios;
148 
149 /*
150  * Which flag is used to select non-blocking I/O with fcntl()?
151  */
152 #undef NON_BLOCKING_FLAG
153 #if defined(O_NONBLOCK)
154 #define NON_BLOCKING_FLAG (O_NONBLOCK)
155 #elif defined(O_NDELAY)
156 #define NON_BLOCKING_FLAG (O_NDELAY)
157 #endif
158 
159 /*
160  * What value should we give errno if I/O blocks when it shouldn't.
161  */
162 #undef BLOCKED_ERRNO
163 #if defined(EAGAIN)
164 #define BLOCKED_ERRNO (EAGAIN)
165 #elif defined(EWOULDBLOCK)
166 #define BLOCKED_ERRNO (EWOULDBLOCK)
167 #elif defined(EIO)
168 #define BLOCKED_ERRNO (EIO)
169 #else
170 #define BLOCKED_ERRNO 0
171 #endif
172 
173 /*
174  * Local headers.
175  */
176 #ifndef WITHOUT_FILE_SYSTEM
177 #include "pathutil.h"
178 #endif
179 #include "libtecla.h"
180 #include "keytab.h"
181 #include "getline.h"
182 #include "ioutil.h"
183 #include "history.h"
184 #include "freelist.h"
185 #include "stringrp.h"
186 #include "chrqueue.h"
187 #include "cplmatch.h"
188 #ifndef WITHOUT_FILE_SYSTEM
189 #include "expand.h"
190 #endif
191 #include "errmsg.h"
192 
193 /*
194  * Enumerate the available editing styles.
195  */
196 typedef enum {
197   GL_EMACS_MODE,   /* Emacs style editing */
198   GL_VI_MODE,      /* Vi style editing */
199   GL_NO_EDITOR     /* Fall back to the basic OS-provided editing */
200 } GlEditor;
201 
202 /*
203  * Set the largest key-sequence that can be handled.
204  */
205 #define GL_KEY_MAX 64
206 
207 /*
208  * In vi mode, the following datatype is used to implement the
209  * undo command. It records a copy of the input line from before
210  * the command-mode action which edited the input line.
211  */
212 typedef struct {
213   char *line;        /* A historical copy of the input line */
214   int buff_curpos;   /* The historical location of the cursor in */
215                      /*  line[] when the line was modified. */
216   int ntotal;        /* The number of characters in line[] */
217   int saved;         /* True once a line has been saved after the */
218                      /*  last call to gl_interpret_char(). */
219 } ViUndo;
220 
221 /*
222  * In vi mode, the following datatype is used to record information
223  * needed by the vi-repeat-change command.
224  */
225 typedef struct {
226   KtAction action;           /* The last action function that made a */
227                              /*  change to the line. */
228   int count;                 /* The repeat count that was passed to the */
229                              /*  above command. */
230   int input_curpos;          /* Whenever vi command mode is entered, the */
231                              /*  the position at which it was first left */
232                              /*  is recorded here. */
233   int command_curpos;        /* Whenever vi command mode is entered, the */
234                              /*  the location of the cursor is recorded */
235                              /*  here. */
236   char input_char;           /* Commands that call gl_read_terminal() */
237                              /*  record the character here, so that it can */
238                              /*  used on repeating the function. */
239   int saved;                 /* True if a function has been saved since the */
240                              /*  last call to gl_interpret_char(). */
241   int active;                /* True while a function is being repeated. */
242 } ViRepeat;
243 
244 /*
245  * The following datatype is used to encapsulate information specific
246  * to vi mode.
247  */
248 typedef struct {
249   ViUndo undo;               /* Information needed to implement the vi */
250                              /*  undo command. */
251   ViRepeat repeat;           /* Information needed to implement the vi */
252                              /*  repeat command. */
253   int command;               /* True in vi command-mode */
254   int find_forward;          /* True if the last character search was in the */
255                              /*  forward direction. */
256   int find_onto;             /* True if the last character search left the */
257                              /*  on top of the located character, as opposed */
258                              /*  to just before or after it. */
259   char find_char;            /* The last character sought, or '\0' if no */
260                              /*  searches have been performed yet. */
261 } ViMode;
262 
263 #ifdef HAVE_SELECT
264 /*
265  * Define a type for recording a file-descriptor callback and its associated
266  * data.
267  */
268 typedef struct {
269   GlFdEventFn *fn;   /* The callback function */
270   void *data;        /* Anonymous data to pass to the callback function */
271 } GlFdHandler;
272 
273 /*
274  * A list of nodes of the following type is used to record file-activity
275  * event handlers, but only on systems that have the select() system call.
276  */
277 typedef struct GlFdNode GlFdNode;
278 struct GlFdNode {
279   GlFdNode *next;    /* The next in the list of nodes */
280   int fd;            /* The file descriptor being watched */
281   GlFdHandler rd;    /* The callback to call when fd is readable */
282   GlFdHandler wr;    /* The callback to call when fd is writable */
283   GlFdHandler ur;    /* The callback to call when fd has urgent data */
284 };
285 
286 /*
287  * Set the number of the above structures to allocate every time that
288  * the freelist of GlFdNode's becomes exhausted.
289  */
290 #define GLFD_FREELIST_BLOCKING 10
291 
292 
293 static int gl_call_fd_handler(GetLine *gl, GlFdHandler *gfh, int fd,
294 			      GlFdEvent event);
295 
296 static int gl_call_timeout_handler(GetLine *gl);
297 
298 #endif
299 
300 /*
301  * Each signal that gl_get_line() traps is described by a list node
302  * of the following type.
303  */
304 typedef struct GlSignalNode GlSignalNode;
305 struct GlSignalNode {
306   GlSignalNode *next;  /* The next signal in the list */
307   int signo;           /* The number of the signal */
308   sigset_t proc_mask;  /* A process mask which only includes signo */
309   SigAction original;  /* The signal disposition of the calling program */
310                        /*  for this signal. */
311   unsigned flags;      /* A bitwise union of GlSignalFlags enumerators */
312   GlAfterSignal after; /* What to do after the signal has been handled */
313   int errno_value;     /* What to set errno to */
314 };
315 
316 /*
317  * Set the number of the above structures to allocate every time that
318  * the freelist of GlSignalNode's becomes exhausted.
319  */
320 #define GLS_FREELIST_BLOCKING 30
321 
322 /*
323  * Completion handlers and their callback data are recorded in
324  * nodes of the following type.
325  */
326 typedef struct GlCplCallback GlCplCallback;
327 struct GlCplCallback {
328   CplMatchFn *fn;            /* The completion callback function */
329   void *data;                /* Arbitrary callback data */
330 };
331 
332 /*
333  * The following function is used as the default completion handler when
334  * the filesystem is to be hidden. It simply reports no completions.
335  */
336 #ifdef HIDE_FILE_SYSTEM
337 static CPL_MATCH_FN(gl_no_completions);
338 #endif
339 
340 /*
341  * Specify how many GlCplCallback nodes are added to the GlCplCallback freelist
342  * whenever it becomes exhausted.
343  */
344 #define GL_CPL_FREELIST_BLOCKING 10
345 
346 /*
347  * External action functions and their callback data are recorded in
348  * nodes of the following type.
349  */
350 typedef struct GlExternalAction GlExternalAction;
351 struct GlExternalAction {
352   GlActionFn *fn;          /* The function which implements the action */
353   void *data;              /* Arbitrary callback data */
354 };
355 
356 /*
357  * Specify how many GlExternalAction nodes are added to the
358  * GlExternalAction freelist whenever it becomes exhausted.
359  */
360 #define GL_EXT_ACT_FREELIST_BLOCKING 10
361 
362 /*
363  * Define the contents of the GetLine object.
364  * Note that the typedef for this object can be found in libtecla.h.
365  */
366 struct GetLine {
367   ErrMsg *err;               /* The error-reporting buffer */
368   GlHistory *glh;            /* The line-history buffer */
369   WordCompletion *cpl;       /* String completion resource object */
370   GlCplCallback cplfn;       /* The completion callback */
371 #ifndef WITHOUT_FILE_SYSTEM
372   ExpandFile *ef;            /* ~user/, $envvar and wildcard expansion */
373                              /*  resource object. */
374 #endif
375   StringGroup *capmem;       /* Memory for recording terminal capability */
376                              /*  strings. */
377   GlCharQueue *cq;           /* The terminal output character queue */
378   int input_fd;              /* The file descriptor to read on */
379   int output_fd;             /* The file descriptor to write to */
380   FILE *input_fp;            /* A stream wrapper around input_fd */
381   FILE *output_fp;           /* A stream wrapper around output_fd */
382   FILE *file_fp;             /* When input is being temporarily taken from */
383                              /*  a file, this is its file-pointer. Otherwise */
384                              /*  it is NULL. */
385   char *term;                /* The terminal type specified on the last call */
386                              /*  to gl_change_terminal(). */
387   int is_term;               /* True if stdin is a terminal */
388   GlWriteFn *flush_fn;       /* The function to call to write to the terminal */
389   GlIOMode io_mode;          /* The I/O mode established by gl_io_mode() */
390   int raw_mode;              /* True while the terminal is in raw mode */
391   GlPendingIO pending_io;    /* The type of I/O that is currently pending */
392   GlReturnStatus rtn_status; /* The reason why gl_get_line() returned */
393   int rtn_errno;             /* THe value of errno associated with rtn_status */
394   size_t linelen;            /* The max number of characters per line */
395   char *line;                /* A line-input buffer of allocated size */
396                              /*  linelen+2. The extra 2 characters are */
397                              /*  reserved for "\n\0". */
398   char *cutbuf;              /* A cut-buffer of the same size as line[] */
399   char *prompt;              /* The current prompt string */
400   int prompt_len;            /* The length of the prompt string */
401   int prompt_changed;        /* True after a callback changes the prompt */
402   int prompt_style;          /* How the prompt string is displayed */
403   FreeList *cpl_mem;         /* Memory for GlCplCallback objects */
404   FreeList *ext_act_mem;     /* Memory for GlExternalAction objects */
405   FreeList *sig_mem;         /* Memory for nodes of the signal list */
406   GlSignalNode *sigs;        /* The head of the list of signals */
407   int signals_masked;        /* True between calls to gl_mask_signals() and */
408                              /*  gl_unmask_signals() */
409   int signals_overriden;     /* True between calls to gl_override_signals() */
410                              /*  and gl_restore_signals() */
411   sigset_t all_signal_set;   /* The set of all signals that we are trapping */
412   sigset_t old_signal_set;   /* The set of blocked signals on entry to */
413                              /*  gl_get_line(). */
414   sigset_t use_signal_set;   /* The subset of all_signal_set to unblock */
415                              /*  while waiting for key-strokes */
416   Termios oldattr;           /* Saved terminal attributes. */
417   KeyTab *bindings;          /* A table of key-bindings */
418   int ntotal;                /* The number of characters in gl->line[] */
419   int buff_curpos;           /* The cursor position within gl->line[] */
420   int term_curpos;           /* The cursor position on the terminal */
421   int term_len;              /* The number of terminal characters used to */
422                              /*  display the current input line. */
423   int buff_mark;             /* A marker location in the buffer */
424   int insert_curpos;         /* The cursor position at start of insert */
425   int insert;                /* True in insert mode */
426   int number;                /* If >= 0, a numeric argument is being read */
427   int endline;               /* True to tell gl_get_input_line() to return */
428                              /*  the current contents of gl->line[] */
429   int displayed;             /* True if an input line is currently displayed */
430   int redisplay;             /* If true, the input line will be redrawn */
431                              /*  either after the current action function */
432                              /*  returns, or when gl_get_input_line() */
433                              /*  is next called. */
434   int postpone;              /* _gl_normal_io() sets this flag, to */
435                              /*  postpone any redisplays until */
436                              /*  is next called, to resume line editing. */
437   char keybuf[GL_KEY_MAX+1]; /* A buffer of currently unprocessed key presses */
438   int nbuf;                  /* The number of characters in keybuf[] */
439   int nread;                 /* The number of characters read from keybuf[] */
440   KtAction current_action;   /* The action function that is being invoked */
441   int current_count;         /* The repeat count passed to */
442                              /*  current_acction.fn() */
443   GlhLineID preload_id;      /* When not zero, this should be the ID of a */
444                              /*  line in the history buffer for potential */
445                              /*  recall. */
446   int preload_history;       /* If true, preload the above history line when */
447                              /*  gl_get_input_line() is next called. */
448   long keyseq_count;         /* The number of key sequences entered by the */
449                              /*  the user since new_GetLine() was called. */
450   long last_search;          /* The value of keyseq_count during the last */
451                              /*  history search operation. */
452   GlEditor editor;           /* The style of editing, (eg. vi or emacs) */
453   int silence_bell;          /* True if gl_ring_bell() should do nothing. */
454   int automatic_history;     /* True to automatically archive entered lines */
455                              /*  in the history list. */
456   ViMode vi;                 /* Parameters used when editing in vi mode */
457   const char *left;          /* The string that moves the cursor 1 character */
458                              /*  left. */
459   const char *right;         /* The string that moves the cursor 1 character */
460                              /*  right. */
461   const char *up;            /* The string that moves the cursor 1 character */
462                              /*  up. */
463   const char *down;          /* The string that moves the cursor 1 character */
464                              /*  down. */
465   const char *home;          /* The string that moves the cursor home */
466   const char *bol;           /* Move cursor to beginning of line */
467   const char *clear_eol;     /* The string that clears from the cursor to */
468                              /*  the end of the line. */
469   const char *clear_eod;     /* The string that clears from the cursor to */
470                              /*  the end of the display. */
471   const char *u_arrow;       /* The string returned by the up-arrow key */
472   const char *d_arrow;       /* The string returned by the down-arrow key */
473   const char *l_arrow;       /* The string returned by the left-arrow key */
474   const char *r_arrow;       /* The string returned by the right-arrow key */
475   const char *sound_bell;    /* The string needed to ring the terminal bell */
476   const char *bold;          /* Switch to the bold font */
477   const char *underline;     /* Underline subsequent characters */
478   const char *standout;      /* Turn on standout mode */
479   const char *dim;           /* Switch to a dim font */
480   const char *reverse;       /* Turn on reverse video */
481   const char *blink;         /* Switch to a blinking font */
482   const char *text_attr_off; /* Turn off all text attributes */
483   int nline;                 /* The height of the terminal in lines */
484   int ncolumn;               /* The width of the terminal in columns */
485 #ifdef USE_TERMCAP
486   char *tgetent_buf;         /* The buffer that is used by tgetent() to */
487                              /*  store a terminal description. */
488   char *tgetstr_buf;         /* The buffer that is used by tgetstr() to */
489                              /*  store terminal capabilities. */
490 #endif
491 #ifdef USE_TERMINFO
492   const char *left_n;        /* The parameter string that moves the cursor */
493                              /*  n characters left. */
494   const char *right_n;       /* The parameter string that moves the cursor */
495                              /*  n characters right. */
496 #endif
497   char *app_file;            /* The pathname of the application-specific */
498                              /*  .teclarc configuration file, or NULL. */
499   char *user_file;           /* The pathname of the user-specific */
500                              /*  .teclarc configuration file, or NULL. */
501   int configured;            /* True as soon as any teclarc configuration */
502                              /*  file has been read. */
503   int echo;                  /* True to display the line as it is being */
504                              /*  entered. If 0, only the prompt will be */
505                              /*  displayed, and the line will not be */
506                              /*  archived in the history list. */
507   int last_signal;           /* The last signal that was caught by */
508                              /*  the last call to gl_get_line(), or -1 */
509                              /*  if no signal has been caught yet. */
510 #ifdef HAVE_SELECT
511   FreeList *fd_node_mem;     /* A freelist of GlFdNode structures */
512   GlFdNode *fd_nodes;        /* The list of fd event descriptions */
513   fd_set rfds;               /* The set of fds to watch for readability */
514   fd_set wfds;               /* The set of fds to watch for writability */
515   fd_set ufds;               /* The set of fds to watch for urgent data */
516   int max_fd;                /* The maximum file-descriptor being watched */
517   struct {                   /* Inactivity timeout related data */
518     struct timeval dt;       /* The inactivity timeout when timer.fn() */
519                              /*  isn't 0 */
520     GlTimeoutFn *fn;         /* The application callback to call when */
521                              /*  the inactivity timer expires, or 0 if */
522                              /*  timeouts are not required. */
523     void *data;              /* Application provided data to be passed to */
524                              /*  timer.fn(). */
525   } timer;
526 #endif
527 };
528 
529 /*
530  * Define the max amount of space needed to store a termcap terminal
531  * description. Unfortunately this has to be done by guesswork, so
532  * there is the potential for buffer overflows if we guess too small.
533  * Fortunately termcap has been replaced by terminfo on most
534  * platforms, and with terminfo this isn't an issue. The value that I
535  * am using here is the conventional value, as recommended by certain
536  * web references.
537  */
538 #ifdef USE_TERMCAP
539 #define TERMCAP_BUF_SIZE 2048
540 #endif
541 
542 /*
543  * Set the size of the string segments used to store terminal capability
544  * strings.
545  */
546 #define CAPMEM_SEGMENT_SIZE 512
547 
548 /*
549  * If no terminal size information is available, substitute the
550  * following vt100 default sizes.
551  */
552 #define GL_DEF_NLINE 24
553 #define GL_DEF_NCOLUMN 80
554 
555 /*
556  * Enumerate the attributes needed to classify different types of
557  * signals. These attributes reflect the standard default
558  * characteristics of these signals (according to Richard Steven's
559  * Advanced Programming in the UNIX Environment). Note that these values
560  * are all powers of 2, so that they can be combined in a bitwise union.
561  */
562 typedef enum {
563   GLSA_TERM=1,   /* A signal that terminates processes */
564   GLSA_SUSP=2,   /* A signal that suspends processes */
565   GLSA_CONT=4,   /* A signal that is sent when suspended processes resume */
566   GLSA_IGN=8,    /* A signal that is ignored */
567   GLSA_CORE=16,  /* A signal that generates a core dump */
568   GLSA_HARD=32,  /* A signal generated by a hardware exception */
569   GLSA_SIZE=64   /* A signal indicating terminal size changes */
570 } GlSigAttr;
571 
572 /*
573  * List the signals that we need to catch. In general these are
574  * those that by default terminate or suspend the process, since
575  * in such cases we need to restore terminal settings.
576  */
577 static const struct GlDefSignal {
578   int signo;            /* The number of the signal */
579   unsigned flags;       /* A bitwise union of GlSignalFlags enumerators */
580   GlAfterSignal after;  /* What to do after the signal has been delivered */
581   int attr;             /* The default attributes of this signal, expressed */
582                         /* as a bitwise union of GlSigAttr enumerators */
583   int errno_value;      /* What to set errno to */
584 } gl_signal_list[] = {
585   {SIGABRT,   GLS_SUSPEND_INPUT,    GLS_ABORT, GLSA_TERM|GLSA_CORE, EINTR},
586   {SIGALRM,   GLS_RESTORE_ENV,   GLS_CONTINUE, GLSA_TERM,           0},
587   {SIGCONT,   GLS_RESTORE_ENV,   GLS_CONTINUE, GLSA_CONT|GLSA_IGN,  0},
588 #if defined(SIGHUP)
589 #ifdef ENOTTY
590   {SIGHUP,    GLS_SUSPEND_INPUT,    GLS_ABORT, GLSA_TERM,           ENOTTY},
591 #else
592   {SIGHUP,    GLS_SUSPEND_INPUT,    GLS_ABORT, GLSA_TERM,           EINTR},
593 #endif
594 #endif
595   {SIGINT,    GLS_SUSPEND_INPUT,    GLS_ABORT, GLSA_TERM,           EINTR},
596 #if defined(SIGPIPE)
597 #ifdef EPIPE
598   {SIGPIPE,   GLS_SUSPEND_INPUT,    GLS_ABORT, GLSA_TERM,           EPIPE},
599 #else
600   {SIGPIPE,   GLS_SUSPEND_INPUT,    GLS_ABORT, GLSA_TERM,           EINTR},
601 #endif
602 #endif
603 #ifdef SIGPOLL
604   {SIGPOLL,   GLS_SUSPEND_INPUT,    GLS_ABORT, GLSA_TERM,           EINTR},
605 #endif
606 #ifdef SIGPWR
607   {SIGPWR,    GLS_RESTORE_ENV,   GLS_CONTINUE, GLSA_IGN,            0},
608 #endif
609 #ifdef SIGQUIT
610   {SIGQUIT,   GLS_SUSPEND_INPUT,    GLS_ABORT, GLSA_TERM|GLSA_CORE, EINTR},
611 #endif
612   {SIGTERM,   GLS_SUSPEND_INPUT,    GLS_ABORT, GLSA_TERM,           EINTR},
613 #ifdef SIGTSTP
614   {SIGTSTP,   GLS_SUSPEND_INPUT, GLS_CONTINUE, GLSA_SUSP,           0},
615 #endif
616 #ifdef SIGTTIN
617   {SIGTTIN,   GLS_SUSPEND_INPUT, GLS_CONTINUE, GLSA_SUSP,           0},
618 #endif
619 #ifdef SIGTTOU
620   {SIGTTOU,   GLS_SUSPEND_INPUT, GLS_CONTINUE, GLSA_SUSP,           0},
621 #endif
622 #ifdef SIGUSR1
623   {SIGUSR1,   GLS_RESTORE_ENV,   GLS_CONTINUE, GLSA_TERM,           0},
624 #endif
625 #ifdef SIGUSR2
626   {SIGUSR2,   GLS_RESTORE_ENV,   GLS_CONTINUE, GLSA_TERM,           0},
627 #endif
628 #ifdef SIGVTALRM
629   {SIGVTALRM, GLS_RESTORE_ENV,   GLS_CONTINUE, GLSA_TERM,           0},
630 #endif
631 #ifdef SIGWINCH
632   {SIGWINCH,  GLS_RESTORE_ENV,   GLS_CONTINUE, GLSA_SIZE|GLSA_IGN,  0},
633 #endif
634 #ifdef SIGXCPU
635   {SIGXCPU,   GLS_RESTORE_ENV,   GLS_CONTINUE, GLSA_TERM|GLSA_CORE, 0},
636 #endif
637 #ifdef SIGXFSZ
638   {SIGXFSZ,   GLS_RESTORE_ENV,   GLS_CONTINUE, GLSA_TERM|GLSA_CORE, 0},
639 #endif
640 };
641 
642 /*
643  * Define file-scope variables for use in signal handlers.
644  */
645 static volatile sig_atomic_t gl_pending_signal = -1;
646 static sigjmp_buf gl_setjmp_buffer;
647 
648 static void gl_signal_handler(int signo);
649 
650 static int gl_check_caught_signal(GetLine *gl);
651 
652 /*
653  * Respond to an externally caught process suspension or
654  * termination signal.
655  */
656 static void gl_suspend_process(int signo, GetLine *gl, int ngl);
657 
658 /* Return the default attributes of a given signal */
659 
660 static int gl_classify_signal(int signo);
661 
662 /*
663  * Unfortunately both terminfo and termcap require one to use the tputs()
664  * function to output terminal control characters, and this function
665  * doesn't allow one to specify a file stream. As a result, the following
666  * file-scope variable is used to pass the current output file stream.
667  * This is bad, but there doesn't seem to be any alternative.
668  */
669 static GetLine *tputs_gl = NULL;
670 
671 /*
672  * Define a tab to be a string of 8 spaces.
673  */
674 #define TAB_WIDTH 8
675 
676 /*
677  * Lookup the current size of the terminal.
678  */
679 static void gl_query_size(GetLine *gl, int *ncolumn, int *nline);
680 
681 /*
682  * Getline calls this to temporarily override certain signal handlers
683  * of the calling program.
684  */
685 static int gl_override_signal_handlers(GetLine *gl);
686 
687 /*
688  * Getline calls this to restore the signal handlers of the calling
689  * program.
690  */
691 static int gl_restore_signal_handlers(GetLine *gl);
692 
693 /*
694  * Temporarily block the delivery of all signals that gl_get_line()
695  * is currently configured to trap.
696  */
697 static int gl_mask_signals(GetLine *gl, sigset_t *oldset);
698 
699 /*
700  * Restore the process signal mask that was overriden by a previous
701  * call to gl_mask_signals().
702  */
703 static int gl_unmask_signals(GetLine *gl, sigset_t *oldset);
704 
705 /*
706  * Unblock the signals that gl_get_line() has been configured to catch.
707  */
708 static int gl_catch_signals(GetLine *gl);
709 
710 /*
711  * Return the set of all trappable signals.
712  */
713 static void gl_list_trappable_signals(sigset_t *signals);
714 
715 /*
716  * Put the terminal into raw input mode, after saving the original
717  * terminal attributes in gl->oldattr.
718  */
719 static int gl_raw_terminal_mode(GetLine *gl);
720 
721 /*
722  * Restore the terminal attributes from gl->oldattr.
723  */
724 static int gl_restore_terminal_attributes(GetLine *gl);
725 
726 /*
727  * Switch to non-blocking I/O if possible.
728  */
729 static int gl_nonblocking_io(GetLine *gl, int fd);
730 
731 /*
732  * Switch to blocking I/O if possible.
733  */
734 static int gl_blocking_io(GetLine *gl, int fd);
735 
736 /*
737  * Read a line from the user in raw mode.
738  */
739 static int gl_get_input_line(GetLine *gl, const char *prompt,
740 			     const char *start_line, int start_pos);
741 
742 /*
743  * Query the user for a single character.
744  */
745 static int gl_get_query_char(GetLine *gl, const char *prompt, int defchar);
746 
747 /*
748  * Read input from a non-interactive input stream.
749  */
750 static int gl_read_stream_line(GetLine *gl);
751 
752 /*
753  * Read a single character from a non-interactive input stream.
754  */
755 static int gl_read_stream_char(GetLine *gl);
756 
757 /*
758  * Prepare to edit a new line.
759  */
760 static int gl_present_line(GetLine *gl, const char *prompt,
761 			   const char *start_line, int start_pos);
762 
763 /*
764  * Reset all line input parameters for a new input line.
765  */
766 static void gl_reset_input_line(GetLine *gl);
767 
768 /*
769  * Handle the receipt of the potential start of a new key-sequence from
770  * the user.
771  */
772 static int gl_interpret_char(GetLine *gl, char c);
773 
774 /*
775  * Bind a single control or meta character to an action.
776  */
777 static int gl_bind_control_char(GetLine *gl, KtBinder binder,
778 				char c, const char *action);
779 
780 /*
781  * Set up terminal-specific key bindings.
782  */
783 static int gl_bind_terminal_keys(GetLine *gl);
784 
785 /*
786  * Lookup terminal control string and size information.
787  */
788 static int gl_control_strings(GetLine *gl, const char *term);
789 
790 /*
791  * Wrappers around the terminfo and termcap functions that lookup
792  * strings in the terminal information databases.
793  */
794 #ifdef USE_TERMINFO
795 static const char *gl_tigetstr(GetLine *gl, const char *name);
796 #elif defined(USE_TERMCAP)
797 static const char *gl_tgetstr(GetLine *gl, const char *name, char **bufptr);
798 #endif
799 
800 /*
801  * Output a binary string directly to the terminal.
802  */
803 static int gl_print_raw_string(GetLine *gl, int buffered,
804 			       const char *string, int n);
805 
806 /*
807  * Print an informational message, starting and finishing on new lines.
808  * After the list of strings to be printed, the last argument MUST be
809  * GL_END_INFO.
810  */
811 static int gl_print_info(GetLine *gl, ...);
812 #define GL_END_INFO ((const char *)0)
813 
814 /*
815  * Start a newline and place the cursor at its start.
816  */
817 static int gl_start_newline(GetLine *gl, int buffered);
818 
819 /*
820  * Output a terminal control sequence.
821  */
822 static int gl_print_control_sequence(GetLine *gl, int nline,
823 				     const char *string);
824 
825 /*
826  * Output a character or string to the terminal after converting tabs
827  * to spaces and control characters to a caret followed by the modified
828  * character.
829  */
830 static int gl_print_char(GetLine *gl, char c, char pad);
831 static int gl_print_string(GetLine *gl, const char *string, char pad);
832 
833 /*
834  * Delete nc characters starting from the one under the cursor.
835  * Optionally copy the deleted characters to the cut buffer.
836  */
837 static int gl_delete_chars(GetLine *gl, int nc, int cut);
838 
839 /*
840  * Add a character to the line buffer at the current cursor position,
841  * inserting or overwriting according the current mode.
842  */
843 static int gl_add_char_to_line(GetLine *gl, char c);
844 
845 /*
846  * Insert/append a string to the line buffer and terminal at the current
847  * cursor position.
848  */
849 static int gl_add_string_to_line(GetLine *gl, const char *s);
850 
851 /*
852  * Record a new character in the input-line buffer.
853  */
854 static int gl_buffer_char(GetLine *gl, char c, int bufpos);
855 
856 /*
857  * Record a string in the input-line buffer.
858  */
859 static int gl_buffer_string(GetLine *gl, const char *s, int n, int bufpos);
860 
861 /*
862  * Make way to insert a string in the input-line buffer.
863  */
864 static int gl_make_gap_in_buffer(GetLine *gl, int start, int n);
865 
866 /*
867  * Remove characters from the input-line buffer, and move any characters
868  * that followed them to the start of the vacated space.
869  */
870 static void gl_remove_from_buffer(GetLine *gl, int start, int n);
871 
872 /*
873  * Terminate the input-line buffer after a specified number of characters.
874  */
875 static int gl_truncate_buffer(GetLine *gl, int n);
876 
877 /*
878  * Delete the displayed part of the input line that follows the current
879  * terminal cursor position.
880  */
881 static int gl_truncate_display(GetLine *gl);
882 
883 /*
884  * Accomodate changes to the contents of the input line buffer
885  * that weren't made by the above gl_*buffer functions.
886  */
887 static void gl_update_buffer(GetLine *gl);
888 
889 /*
890  * Read a single character from the terminal.
891  */
892 static int gl_read_terminal(GetLine *gl, int keep, char *c);
893 
894 /*
895  * Discard processed characters from the key-press lookahead buffer.
896  */
897 static void gl_discard_chars(GetLine *gl, int nused);
898 
899 /*
900  * Move the terminal cursor n positions to the left or right.
901  */
902 static int gl_terminal_move_cursor(GetLine *gl, int n);
903 
904 /*
905  * Move the terminal cursor to a given position.
906  */
907 static int gl_set_term_curpos(GetLine *gl, int term_curpos);
908 
909 /*
910  * Set the position of the cursor both in the line input buffer and on the
911  * terminal.
912  */
913 static int gl_place_cursor(GetLine *gl, int buff_curpos);
914 
915 /*
916  * How many characters are needed to write a number as an octal string?
917  */
918 static int gl_octal_width(unsigned num);
919 
920 /*
921  * Return the number of spaces needed to display a tab character at
922  * a given location of the terminal.
923  */
924 static int gl_displayed_tab_width(GetLine *gl, int term_curpos);
925 
926 /*
927  * Return the number of terminal characters needed to display a
928  * given raw character.
929  */
930 static int gl_displayed_char_width(GetLine *gl, char c, int term_curpos);
931 
932 /*
933  * Return the number of terminal characters needed to display a
934  * given substring.
935  */
936 static int gl_displayed_string_width(GetLine *gl, const char *string, int nc,
937 				     int term_curpos);
938 
939 /*
940  * Return non-zero if 'c' is to be considered part of a word.
941  */
942 static int gl_is_word_char(int c);
943 
944 /*
945  * Read a tecla configuration file.
946  */
947 static int _gl_read_config_file(GetLine *gl, const char *filename, KtBinder who);
948 
949 /*
950  * Read a tecla configuration string.
951  */
952 static int _gl_read_config_string(GetLine *gl, const char *buffer, KtBinder who);
953 
954 /*
955  * Define the callback function used by _gl_parse_config_line() to
956  * read the next character of a configuration stream.
957  */
958 #define GLC_GETC_FN(fn) int (fn)(void *stream)
959 typedef GLC_GETC_FN(GlcGetcFn);
960 
961 static GLC_GETC_FN(glc_file_getc);  /* Read from a file */
962 static GLC_GETC_FN(glc_buff_getc);  /* Read from a string */
963 
964 /*
965  * Parse a single configuration command line.
966  */
967 static int _gl_parse_config_line(GetLine *gl, void *stream, GlcGetcFn *getc_fn,
968 				 const char *origin, KtBinder who, int *lineno);
969 static int gl_report_config_error(GetLine *gl, const char *origin, int lineno,
970 				  const char *errmsg);
971 
972 /*
973  * Bind the actual arrow key bindings to match those of the symbolic
974  * arrow-key bindings.
975  */
976 static int _gl_bind_arrow_keys(GetLine *gl);
977 
978 /*
979  * Copy the binding of the specified symbolic arrow-key binding to
980  * the terminal specific, and default arrow-key key-sequences.
981  */
982 static int _gl_rebind_arrow_key(GetLine *gl, const char *name,
983 				const char *term_seq,
984 				const char *def_seq1,
985 				const char *def_seq2);
986 
987 /*
988  * After the gl_read_from_file() action has been used to tell gl_get_line()
989  * to temporarily read input from a file, gl_revert_input() arranges
990  * for input to be reverted to the input stream last registered with
991  * gl_change_terminal().
992  */
993 static void gl_revert_input(GetLine *gl);
994 
995 /*
996  * Flush unwritten characters to the terminal.
997  */
998 static int gl_flush_output(GetLine *gl);
999 
1000 /*
1001  * The callback through which all terminal output is routed.
1002  * This simply appends characters to a queue buffer, which is
1003  * subsequently flushed to the output channel by gl_flush_output().
1004  */
1005 static GL_WRITE_FN(gl_write_fn);
1006 
1007 /*
1008  * The callback function which the output character queue object
1009  * calls to transfer characters to the output channel.
1010  */
1011 static GL_WRITE_FN(gl_flush_terminal);
1012 
1013 /*
1014  * Enumerate the possible return statuses of gl_read_input().
1015  */
1016 typedef enum {
1017   GL_READ_OK,      /* A character was read successfully */
1018   GL_READ_ERROR,   /* A read-error occurred */
1019   GL_READ_BLOCKED, /* The read would have blocked the caller */
1020   GL_READ_EOF      /* The end of the current input file was reached */
1021 } GlReadStatus;
1022 
1023 static GlReadStatus gl_read_input(GetLine *gl, char *c);
1024 /*
1025  * Private functions of gl_read_input().
1026  */
1027 static int gl_event_handler(GetLine *gl, int fd);
1028 static int gl_read_unmasked(GetLine *gl, int fd, char *c);
1029 
1030 
1031 /*
1032  * A private function of gl_tty_signals().
1033  */
1034 static int gl_set_tty_signal(int signo, void (*handler)(int));
1035 
1036 /*
1037  * Change the editor style being emulated.
1038  */
1039 static int gl_change_editor(GetLine *gl, GlEditor editor);
1040 
1041 /*
1042  * Searching in a given direction, return the index of a given (or
1043  * read) character in the input line, or the character that precedes
1044  * it in the specified search direction. Return -1 if not found.
1045  */
1046 static int gl_find_char(GetLine *gl, int count, int forward, int onto, char c);
1047 
1048 /*
1049  * Return the buffer index of the nth word ending after the cursor.
1050  */
1051 static int gl_nth_word_end_forward(GetLine *gl, int n);
1052 
1053 /*
1054  * Return the buffer index of the nth word start after the cursor.
1055  */
1056 static int gl_nth_word_start_forward(GetLine *gl, int n);
1057 
1058 /*
1059  * Return the buffer index of the nth word start before the cursor.
1060  */
1061 static int gl_nth_word_start_backward(GetLine *gl, int n);
1062 
1063 /*
1064  * When called when vi command mode is enabled, this function saves the
1065  * current line and cursor position for potential restoration later
1066  * by the vi undo command.
1067  */
1068 static void gl_save_for_undo(GetLine *gl);
1069 
1070 /*
1071  * If in vi mode, switch to vi command mode.
1072  */
1073 static void gl_vi_command_mode(GetLine *gl);
1074 
1075 /*
1076  * In vi mode this is used to delete up to or onto a given or read
1077  * character in the input line. Also switch to insert mode if requested
1078  * after the deletion.
1079  */
1080 static int gl_delete_find(GetLine *gl, int count, char c, int forward,
1081 			  int onto, int change);
1082 
1083 /*
1084  * Copy the characters between the cursor and the count'th instance of
1085  * a specified (or read) character in the input line, into the cut buffer.
1086  */
1087 static int gl_copy_find(GetLine *gl, int count, char c, int forward, int onto);
1088 
1089 /*
1090  * Return the line index of the parenthesis that either matches the one under
1091  * the cursor, or not over a parenthesis character, the index of the next
1092  * close parenthesis. Return -1 if not found.
1093  */
1094 static int gl_index_of_matching_paren(GetLine *gl);
1095 
1096 /*
1097  * Replace a malloc'd string (or NULL), with another malloc'd copy of
1098  * a string (or NULL).
1099  */
1100 static int gl_record_string(char **sptr, const char *string);
1101 
1102 /*
1103  * Enumerate text display attributes as powers of two, suitable for
1104  * use in a bit-mask.
1105  */
1106 typedef enum {
1107   GL_TXT_STANDOUT=1,   /* Display text highlighted */
1108   GL_TXT_UNDERLINE=2,  /* Display text underlined */
1109   GL_TXT_REVERSE=4,    /* Display text with reverse video */
1110   GL_TXT_BLINK=8,      /* Display blinking text */
1111   GL_TXT_DIM=16,       /* Display text in a dim font */
1112   GL_TXT_BOLD=32       /* Display text using a bold font */
1113 } GlTextAttr;
1114 
1115 /*
1116  * Display the prompt regardless of the current visibility mode.
1117  */
1118 static int gl_display_prompt(GetLine *gl);
1119 
1120 /*
1121  * Return the number of characters used by the prompt on the terminal.
1122  */
1123 static int gl_displayed_prompt_width(GetLine *gl);
1124 
1125 /*
1126  * Prepare to return the current input line to the caller of gl_get_line().
1127  */
1128 static int gl_line_ended(GetLine *gl, int newline_char);
1129 
1130 /*
1131  * Arrange for the input line to be redisplayed when the current contents
1132  * of the output queue have been flushed.
1133  */
1134 static void gl_queue_redisplay(GetLine *gl);
1135 
1136 /*
1137  * Erase the displayed representation of the input line, without
1138  * touching the buffered copy.
1139  */
1140 static int gl_erase_line(GetLine *gl);
1141 
1142 /*
1143  * This function is called whenever the input line has been erased.
1144  */
1145 static void gl_line_erased(GetLine *gl);
1146 
1147 /*
1148  * Arrange for the current input line to be discarded.
1149  */
1150 void _gl_abandon_line(GetLine *gl);
1151 
1152 /*
1153  * The following are private internally callable versions of pertinent
1154  * public functions. Unlike their public wrapper functions, they don't
1155  * block signals while running, and assume that their arguments are valid.
1156  * They are designed to be called from places where signals are already
1157  * blocked, and where simple sanity checks have already been applied to
1158  * their arguments.
1159  */
1160 static char *_gl_get_line(GetLine *gl, const char *prompt,
1161 			  const char *start_line, int start_pos);
1162 static int _gl_query_char(GetLine *gl, const char *prompt, char defchar);
1163 static int _gl_read_char(GetLine *gl);
1164 static int _gl_update_size(GetLine *gl);
1165 /*
1166  * Redraw the current input line to account for a change in the terminal
1167  * size. Also install the new size in gl.
1168  */
1169 static int gl_handle_tty_resize(GetLine *gl, int ncolumn, int nline);
1170 
1171 static int _gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp,
1172 			       const char *term);
1173 static int _gl_configure_getline(GetLine *gl, const char *app_string,
1174 				 const char *app_file, const char *user_file);
1175 static int _gl_save_history(GetLine *gl, const char *filename,
1176 			    const char *comment, int max_lines);
1177 static int _gl_load_history(GetLine *gl, const char *filename,
1178 			    const char *comment);
1179 static int _gl_watch_fd(GetLine *gl, int fd, GlFdEvent event,
1180 			GlFdEventFn *callback, void *data);
1181 static void _gl_terminal_size(GetLine *gl, int def_ncolumn, int def_nline,
1182 			      GlTerminalSize *size);
1183 static void _gl_replace_prompt(GetLine *gl, const char *prompt);
1184 static int _gl_trap_signal(GetLine *gl, int signo, unsigned flags,
1185 			   GlAfterSignal after, int errno_value);
1186 static int _gl_raw_io(GetLine *gl, int redisplay);
1187 static int _gl_normal_io(GetLine *gl);
1188 static int _gl_completion_action(GetLine *gl, void *data, CplMatchFn *match_fn,
1189 				 int list_only, const char *name,
1190 				 const char *keyseq);
1191 static int _gl_register_action(GetLine *gl, void *data, GlActionFn *fn,
1192 			       const char *name, const char *keyseq);
1193 static int _gl_io_mode(GetLine *gl, GlIOMode mode);
1194 static int _gl_set_term_size(GetLine *gl, int ncolumn, int nline);
1195 static int _gl_append_history(GetLine *gl, const char *line);
1196 
1197 /*
1198  * Reset the completion status and associated errno value in
1199  * gl->rtn_status and gl->rtn_errno.
1200  */
1201 static void gl_clear_status(GetLine *gl);
1202 
1203 /*
1204  * Record a completion status, unless a previous abnormal completion
1205  * status has already been recorded for the current call.
1206  */
1207 static void gl_record_status(GetLine *gl, GlReturnStatus rtn_status,
1208 			     int rtn_errno);
1209 
1210 /*
1211  * Set the maximum length of a line in a user's tecla configuration
1212  * file (not counting comments).
1213  */
1214 #define GL_CONF_BUFLEN 100
1215 
1216 /*
1217  * Set the maximum number of arguments supported by individual commands
1218  * in tecla configuration files.
1219  */
1220 #define GL_CONF_MAXARG 10
1221 
1222 /*
1223  * Prototype the available action functions.
1224  */
1225 static KT_KEY_FN(gl_user_interrupt);
1226 static KT_KEY_FN(gl_abort);
1227 static KT_KEY_FN(gl_suspend);
1228 static KT_KEY_FN(gl_stop_output);
1229 static KT_KEY_FN(gl_start_output);
1230 static KT_KEY_FN(gl_literal_next);
1231 static KT_KEY_FN(gl_cursor_left);
1232 static KT_KEY_FN(gl_cursor_right);
1233 static KT_KEY_FN(gl_insert_mode);
1234 static KT_KEY_FN(gl_beginning_of_line);
1235 static KT_KEY_FN(gl_end_of_line);
1236 static KT_KEY_FN(gl_delete_line);
1237 static KT_KEY_FN(gl_kill_line);
1238 static KT_KEY_FN(gl_forward_word);
1239 static KT_KEY_FN(gl_backward_word);
1240 static KT_KEY_FN(gl_forward_delete_char);
1241 static KT_KEY_FN(gl_backward_delete_char);
1242 static KT_KEY_FN(gl_forward_delete_word);
1243 static KT_KEY_FN(gl_backward_delete_word);
1244 static KT_KEY_FN(gl_delete_refind);
1245 static KT_KEY_FN(gl_delete_invert_refind);
1246 static KT_KEY_FN(gl_delete_to_column);
1247 static KT_KEY_FN(gl_delete_to_parenthesis);
1248 static KT_KEY_FN(gl_forward_delete_find);
1249 static KT_KEY_FN(gl_backward_delete_find);
1250 static KT_KEY_FN(gl_forward_delete_to);
1251 static KT_KEY_FN(gl_backward_delete_to);
1252 static KT_KEY_FN(gl_upcase_word);
1253 static KT_KEY_FN(gl_downcase_word);
1254 static KT_KEY_FN(gl_capitalize_word);
1255 static KT_KEY_FN(gl_redisplay);
1256 static KT_KEY_FN(gl_clear_screen);
1257 static KT_KEY_FN(gl_transpose_chars);
1258 static KT_KEY_FN(gl_set_mark);
1259 static KT_KEY_FN(gl_exchange_point_and_mark);
1260 static KT_KEY_FN(gl_kill_region);
1261 static KT_KEY_FN(gl_copy_region_as_kill);
1262 static KT_KEY_FN(gl_yank);
1263 static KT_KEY_FN(gl_up_history);
1264 static KT_KEY_FN(gl_down_history);
1265 static KT_KEY_FN(gl_history_search_backward);
1266 static KT_KEY_FN(gl_history_re_search_backward);
1267 static KT_KEY_FN(gl_history_search_forward);
1268 static KT_KEY_FN(gl_history_re_search_forward);
1269 static KT_KEY_FN(gl_complete_word);
1270 #ifndef HIDE_FILE_SYSTEM
1271 static KT_KEY_FN(gl_expand_filename);
1272 static KT_KEY_FN(gl_read_from_file);
1273 static KT_KEY_FN(gl_read_init_files);
1274 static KT_KEY_FN(gl_list_glob);
1275 #endif
1276 static KT_KEY_FN(gl_del_char_or_list_or_eof);
1277 static KT_KEY_FN(gl_list_or_eof);
1278 static KT_KEY_FN(gl_beginning_of_history);
1279 static KT_KEY_FN(gl_end_of_history);
1280 static KT_KEY_FN(gl_digit_argument);
1281 static KT_KEY_FN(gl_newline);
1282 static KT_KEY_FN(gl_repeat_history);
1283 static KT_KEY_FN(gl_vi_insert);
1284 static KT_KEY_FN(gl_vi_overwrite);
1285 static KT_KEY_FN(gl_change_case);
1286 static KT_KEY_FN(gl_vi_insert_at_bol);
1287 static KT_KEY_FN(gl_vi_append_at_eol);
1288 static KT_KEY_FN(gl_vi_append);
1289 static KT_KEY_FN(gl_backward_kill_line);
1290 static KT_KEY_FN(gl_goto_column);
1291 static KT_KEY_FN(gl_forward_to_word);
1292 static KT_KEY_FN(gl_vi_replace_char);
1293 static KT_KEY_FN(gl_vi_change_rest_of_line);
1294 static KT_KEY_FN(gl_vi_change_line);
1295 static KT_KEY_FN(gl_vi_change_to_bol);
1296 static KT_KEY_FN(gl_vi_change_refind);
1297 static KT_KEY_FN(gl_vi_change_invert_refind);
1298 static KT_KEY_FN(gl_vi_change_to_column);
1299 static KT_KEY_FN(gl_vi_change_to_parenthesis);
1300 static KT_KEY_FN(gl_vi_forward_change_word);
1301 static KT_KEY_FN(gl_vi_backward_change_word);
1302 static KT_KEY_FN(gl_vi_forward_change_find);
1303 static KT_KEY_FN(gl_vi_backward_change_find);
1304 static KT_KEY_FN(gl_vi_forward_change_to);
1305 static KT_KEY_FN(gl_vi_backward_change_to);
1306 static KT_KEY_FN(gl_vi_forward_change_char);
1307 static KT_KEY_FN(gl_vi_backward_change_char);
1308 static KT_KEY_FN(gl_forward_copy_char);
1309 static KT_KEY_FN(gl_backward_copy_char);
1310 static KT_KEY_FN(gl_forward_find_char);
1311 static KT_KEY_FN(gl_backward_find_char);
1312 static KT_KEY_FN(gl_forward_to_char);
1313 static KT_KEY_FN(gl_backward_to_char);
1314 static KT_KEY_FN(gl_repeat_find_char);
1315 static KT_KEY_FN(gl_invert_refind_char);
1316 static KT_KEY_FN(gl_append_yank);
1317 static KT_KEY_FN(gl_backward_copy_word);
1318 static KT_KEY_FN(gl_forward_copy_word);
1319 static KT_KEY_FN(gl_copy_to_bol);
1320 static KT_KEY_FN(gl_copy_refind);
1321 static KT_KEY_FN(gl_copy_invert_refind);
1322 static KT_KEY_FN(gl_copy_to_column);
1323 static KT_KEY_FN(gl_copy_to_parenthesis);
1324 static KT_KEY_FN(gl_copy_rest_of_line);
1325 static KT_KEY_FN(gl_copy_line);
1326 static KT_KEY_FN(gl_backward_copy_find);
1327 static KT_KEY_FN(gl_forward_copy_find);
1328 static KT_KEY_FN(gl_backward_copy_to);
1329 static KT_KEY_FN(gl_forward_copy_to);
1330 static KT_KEY_FN(gl_vi_undo);
1331 static KT_KEY_FN(gl_emacs_editing_mode);
1332 static KT_KEY_FN(gl_vi_editing_mode);
1333 static KT_KEY_FN(gl_ring_bell);
1334 static KT_KEY_FN(gl_vi_repeat_change);
1335 static KT_KEY_FN(gl_find_parenthesis);
1336 static KT_KEY_FN(gl_list_history);
1337 static KT_KEY_FN(gl_list_completions);
1338 static KT_KEY_FN(gl_run_external_action);
1339 
1340 /*
1341  * Name the available action functions.
1342  */
1343 static const struct {const char *name; KT_KEY_FN(*fn);} gl_actions[] = {
1344   {"user-interrupt",             gl_user_interrupt},
1345   {"abort",                      gl_abort},
1346   {"suspend",                    gl_suspend},
1347   {"stop-output",                gl_stop_output},
1348   {"start-output",               gl_start_output},
1349   {"literal-next",               gl_literal_next},
1350   {"cursor-right",               gl_cursor_right},
1351   {"cursor-left",                gl_cursor_left},
1352   {"insert-mode",                gl_insert_mode},
1353   {"beginning-of-line",          gl_beginning_of_line},
1354   {"end-of-line",                gl_end_of_line},
1355   {"delete-line",                gl_delete_line},
1356   {"kill-line",                  gl_kill_line},
1357   {"forward-word",               gl_forward_word},
1358   {"backward-word",              gl_backward_word},
1359   {"forward-delete-char",        gl_forward_delete_char},
1360   {"backward-delete-char",       gl_backward_delete_char},
1361   {"forward-delete-word",        gl_forward_delete_word},
1362   {"backward-delete-word",       gl_backward_delete_word},
1363   {"delete-refind",              gl_delete_refind},
1364   {"delete-invert-refind",       gl_delete_invert_refind},
1365   {"delete-to-column",           gl_delete_to_column},
1366   {"delete-to-parenthesis",      gl_delete_to_parenthesis},
1367   {"forward-delete-find",        gl_forward_delete_find},
1368   {"backward-delete-find",       gl_backward_delete_find},
1369   {"forward-delete-to",          gl_forward_delete_to},
1370   {"backward-delete-to",         gl_backward_delete_to},
1371   {"upcase-word",                gl_upcase_word},
1372   {"downcase-word",              gl_downcase_word},
1373   {"capitalize-word",            gl_capitalize_word},
1374   {"redisplay",                  gl_redisplay},
1375   {"clear-screen",               gl_clear_screen},
1376   {"transpose-chars",            gl_transpose_chars},
1377   {"set-mark",                   gl_set_mark},
1378   {"exchange-point-and-mark",    gl_exchange_point_and_mark},
1379   {"kill-region",                gl_kill_region},
1380   {"copy-region-as-kill",        gl_copy_region_as_kill},
1381   {"yank",                       gl_yank},
1382   {"up-history",                 gl_up_history},
1383   {"down-history",               gl_down_history},
1384   {"history-search-backward",    gl_history_search_backward},
1385   {"history-re-search-backward", gl_history_re_search_backward},
1386   {"history-search-forward",     gl_history_search_forward},
1387   {"history-re-search-forward",  gl_history_re_search_forward},
1388   {"complete-word",              gl_complete_word},
1389 #ifndef HIDE_FILE_SYSTEM
1390   {"expand-filename",            gl_expand_filename},
1391   {"read-from-file",             gl_read_from_file},
1392   {"read-init-files",            gl_read_init_files},
1393   {"list-glob",                  gl_list_glob},
1394 #endif
1395   {"del-char-or-list-or-eof",    gl_del_char_or_list_or_eof},
1396   {"beginning-of-history",       gl_beginning_of_history},
1397   {"end-of-history",             gl_end_of_history},
1398   {"digit-argument",             gl_digit_argument},
1399   {"newline",                    gl_newline},
1400   {"repeat-history",             gl_repeat_history},
1401   {"vi-insert",                  gl_vi_insert},
1402   {"vi-overwrite",               gl_vi_overwrite},
1403   {"vi-insert-at-bol",           gl_vi_insert_at_bol},
1404   {"vi-append-at-eol",           gl_vi_append_at_eol},
1405   {"vi-append",                  gl_vi_append},
1406   {"change-case",                gl_change_case},
1407   {"backward-kill-line",         gl_backward_kill_line},
1408   {"goto-column",                gl_goto_column},
1409   {"forward-to-word",            gl_forward_to_word},
1410   {"vi-replace-char",            gl_vi_replace_char},
1411   {"vi-change-rest-of-line",     gl_vi_change_rest_of_line},
1412   {"vi-change-line",             gl_vi_change_line},
1413   {"vi-change-to-bol",           gl_vi_change_to_bol},
1414   {"vi-change-refind",           gl_vi_change_refind},
1415   {"vi-change-invert-refind",    gl_vi_change_invert_refind},
1416   {"vi-change-to-column",        gl_vi_change_to_column},
1417   {"vi-change-to-parenthesis",   gl_vi_change_to_parenthesis},
1418   {"forward-copy-char",          gl_forward_copy_char},
1419   {"backward-copy-char",         gl_backward_copy_char},
1420   {"forward-find-char",          gl_forward_find_char},
1421   {"backward-find-char",         gl_backward_find_char},
1422   {"forward-to-char",            gl_forward_to_char},
1423   {"backward-to-char",           gl_backward_to_char},
1424   {"repeat-find-char",           gl_repeat_find_char},
1425   {"invert-refind-char",         gl_invert_refind_char},
1426   {"append-yank",                gl_append_yank},
1427   {"backward-copy-word",         gl_backward_copy_word},
1428   {"forward-copy-word",          gl_forward_copy_word},
1429   {"copy-to-bol",                gl_copy_to_bol},
1430   {"copy-refind",                gl_copy_refind},
1431   {"copy-invert-refind",         gl_copy_invert_refind},
1432   {"copy-to-column",             gl_copy_to_column},
1433   {"copy-to-parenthesis",        gl_copy_to_parenthesis},
1434   {"copy-rest-of-line",          gl_copy_rest_of_line},
1435   {"copy-line",                  gl_copy_line},
1436   {"backward-copy-find",         gl_backward_copy_find},
1437   {"forward-copy-find",          gl_forward_copy_find},
1438   {"backward-copy-to",           gl_backward_copy_to},
1439   {"forward-copy-to",            gl_forward_copy_to},
1440   {"list-or-eof",                gl_list_or_eof},
1441   {"vi-undo",                    gl_vi_undo},
1442   {"vi-backward-change-word",    gl_vi_backward_change_word},
1443   {"vi-forward-change-word",     gl_vi_forward_change_word},
1444   {"vi-backward-change-find",    gl_vi_backward_change_find},
1445   {"vi-forward-change-find",     gl_vi_forward_change_find},
1446   {"vi-backward-change-to",      gl_vi_backward_change_to},
1447   {"vi-forward-change-to",       gl_vi_forward_change_to},
1448   {"vi-backward-change-char",    gl_vi_backward_change_char},
1449   {"vi-forward-change-char",     gl_vi_forward_change_char},
1450   {"emacs-mode",                 gl_emacs_editing_mode},
1451   {"vi-mode",                    gl_vi_editing_mode},
1452   {"ring-bell",                  gl_ring_bell},
1453   {"vi-repeat-change",           gl_vi_repeat_change},
1454   {"find-parenthesis",           gl_find_parenthesis},
1455   {"list-history",               gl_list_history},
1456 };
1457 
1458 /*
1459  * Define the default key-bindings in emacs mode.
1460  */
1461 static const KtKeyBinding gl_emacs_bindings[] = {
1462   {"right",        "cursor-right"},
1463   {"^F",           "cursor-right"},
1464   {"left",         "cursor-left"},
1465   {"^B",           "cursor-left"},
1466   {"M-i",          "insert-mode"},
1467   {"M-I",          "insert-mode"},
1468   {"^A",           "beginning-of-line"},
1469   {"^E",           "end-of-line"},
1470   {"^U",           "delete-line"},
1471   {"^K",           "kill-line"},
1472   {"M-f",          "forward-word"},
1473   {"M-F",          "forward-word"},
1474   {"M-b",          "backward-word"},
1475   {"M-B",          "backward-word"},
1476   {"^D",           "del-char-or-list-or-eof"},
1477   {"^H",           "backward-delete-char"},
1478   {"^?",           "backward-delete-char"},
1479   {"M-d",          "forward-delete-word"},
1480   {"M-D",          "forward-delete-word"},
1481   {"M-^H",         "backward-delete-word"},
1482   {"M-^?",         "backward-delete-word"},
1483   {"M-u",          "upcase-word"},
1484   {"M-U",          "upcase-word"},
1485   {"M-l",          "downcase-word"},
1486   {"M-L",          "downcase-word"},
1487   {"M-c",          "capitalize-word"},
1488   {"M-C",          "capitalize-word"},
1489   {"^R",           "redisplay"},
1490   {"^L",           "clear-screen"},
1491   {"^T",           "transpose-chars"},
1492   {"^@",           "set-mark"},
1493   {"^X^X",         "exchange-point-and-mark"},
1494   {"^W",           "kill-region"},
1495   {"M-w",          "copy-region-as-kill"},
1496   {"M-W",          "copy-region-as-kill"},
1497   {"^Y",           "yank"},
1498   {"^P",           "up-history"},
1499   {"up",           "up-history"},
1500   {"^N",           "down-history"},
1501   {"down",         "down-history"},
1502   {"M-p",          "history-search-backward"},
1503   {"M-P",          "history-search-backward"},
1504   {"M-n",          "history-search-forward"},
1505   {"M-N",          "history-search-forward"},
1506   {"\t",           "complete-word"},
1507 #ifndef HIDE_FILE_SYSTEM
1508   {"^X*",          "expand-filename"},
1509   {"^X^F",         "read-from-file"},
1510   {"^X^R",         "read-init-files"},
1511   {"^Xg",          "list-glob"},
1512   {"^XG",          "list-glob"},
1513 #endif
1514   {"^Xh",          "list-history"},
1515   {"^XH",          "list-history"},
1516   {"M-<",          "beginning-of-history"},
1517   {"M->",          "end-of-history"},
1518   {"M-0",          "digit-argument"},
1519   {"M-1",          "digit-argument"},
1520   {"M-2",          "digit-argument"},
1521   {"M-3",          "digit-argument"},
1522   {"M-4",          "digit-argument"},
1523   {"M-5",          "digit-argument"},
1524   {"M-6",          "digit-argument"},
1525   {"M-7",          "digit-argument"},
1526   {"M-8",          "digit-argument"},
1527   {"M-9",          "digit-argument"},
1528   {"\r",           "newline"},
1529   {"\n",           "newline"},
1530   {"M-o",          "repeat-history"},
1531   {"M-C-v",        "vi-mode"},
1532 };
1533 
1534 /*
1535  * Define the default key-bindings in vi mode. Note that in vi-mode
1536  * meta-key bindings are command-mode bindings. For example M-i first
1537  * switches to command mode if not already in that mode, then moves
1538  * the cursor one position right, as in vi.
1539  */
1540 static const KtKeyBinding gl_vi_bindings[] = {
1541   {"^D",           "list-or-eof"},
1542 #ifndef HIDE_FILE_SYSTEM
1543   {"^G",           "list-glob"},
1544 #endif
1545   {"^H",           "backward-delete-char"},
1546   {"\t",           "complete-word"},
1547   {"\r",           "newline"},
1548   {"\n",           "newline"},
1549   {"^L",           "clear-screen"},
1550   {"^N",           "down-history"},
1551   {"^P",           "up-history"},
1552   {"^R",           "redisplay"},
1553   {"^U",           "backward-kill-line"},
1554   {"^W",           "backward-delete-word"},
1555 #ifndef HIDE_FILE_SYSTEM
1556   {"^X^F",         "read-from-file"},
1557   {"^X^R",         "read-init-files"},
1558   {"^X*",          "expand-filename"},
1559 #endif
1560   {"^?",           "backward-delete-char"},
1561   {"M- ",          "cursor-right"},
1562   {"M-$",          "end-of-line"},
1563 #ifndef HIDE_FILE_SYSTEM
1564   {"M-*",          "expand-filename"},
1565 #endif
1566   {"M-+",          "down-history"},
1567   {"M--",          "up-history"},
1568   {"M-<",          "beginning-of-history"},
1569   {"M->",          "end-of-history"},
1570   {"M-^",          "beginning-of-line"},
1571   {"M-;",          "repeat-find-char"},
1572   {"M-,",          "invert-refind-char"},
1573   {"M-|",          "goto-column"},
1574   {"M-~",          "change-case"},
1575   {"M-.",          "vi-repeat-change"},
1576   {"M-%",          "find-parenthesis"},
1577   {"M-0",          "digit-argument"},
1578   {"M-1",          "digit-argument"},
1579   {"M-2",          "digit-argument"},
1580   {"M-3",          "digit-argument"},
1581   {"M-4",          "digit-argument"},
1582   {"M-5",          "digit-argument"},
1583   {"M-6",          "digit-argument"},
1584   {"M-7",          "digit-argument"},
1585   {"M-8",          "digit-argument"},
1586   {"M-9",          "digit-argument"},
1587   {"M-a",          "vi-append"},
1588   {"M-A",          "vi-append-at-eol"},
1589   {"M-b",          "backward-word"},
1590   {"M-B",          "backward-word"},
1591   {"M-C",          "vi-change-rest-of-line"},
1592   {"M-cb",         "vi-backward-change-word"},
1593   {"M-cB",         "vi-backward-change-word"},
1594   {"M-cc",         "vi-change-line"},
1595   {"M-ce",         "vi-forward-change-word"},
1596   {"M-cE",         "vi-forward-change-word"},
1597   {"M-cw",         "vi-forward-change-word"},
1598   {"M-cW",         "vi-forward-change-word"},
1599   {"M-cF",         "vi-backward-change-find"},
1600   {"M-cf",         "vi-forward-change-find"},
1601   {"M-cT",         "vi-backward-change-to"},
1602   {"M-ct",         "vi-forward-change-to"},
1603   {"M-c;",         "vi-change-refind"},
1604   {"M-c,",         "vi-change-invert-refind"},
1605   {"M-ch",         "vi-backward-change-char"},
1606   {"M-c^H",        "vi-backward-change-char"},
1607   {"M-c^?",        "vi-backward-change-char"},
1608   {"M-cl",         "vi-forward-change-char"},
1609   {"M-c ",         "vi-forward-change-char"},
1610   {"M-c^",         "vi-change-to-bol"},
1611   {"M-c0",         "vi-change-to-bol"},
1612   {"M-c$",         "vi-change-rest-of-line"},
1613   {"M-c|",         "vi-change-to-column"},
1614   {"M-c%",         "vi-change-to-parenthesis"},
1615   {"M-dh",         "backward-delete-char"},
1616   {"M-d^H",        "backward-delete-char"},
1617   {"M-d^?",        "backward-delete-char"},
1618   {"M-dl",         "forward-delete-char"},
1619   {"M-d ",         "forward-delete-char"},
1620   {"M-dd",         "delete-line"},
1621   {"M-db",         "backward-delete-word"},
1622   {"M-dB",         "backward-delete-word"},
1623   {"M-de",         "forward-delete-word"},
1624   {"M-dE",         "forward-delete-word"},
1625   {"M-dw",         "forward-delete-word"},
1626   {"M-dW",         "forward-delete-word"},
1627   {"M-dF",         "backward-delete-find"},
1628   {"M-df",         "forward-delete-find"},
1629   {"M-dT",         "backward-delete-to"},
1630   {"M-dt",         "forward-delete-to"},
1631   {"M-d;",         "delete-refind"},
1632   {"M-d,",         "delete-invert-refind"},
1633   {"M-d^",         "backward-kill-line"},
1634   {"M-d0",         "backward-kill-line"},
1635   {"M-d$",         "kill-line"},
1636   {"M-D",          "kill-line"},
1637   {"M-d|",         "delete-to-column"},
1638   {"M-d%",         "delete-to-parenthesis"},
1639   {"M-e",          "forward-word"},
1640   {"M-E",          "forward-word"},
1641   {"M-f",          "forward-find-char"},
1642   {"M-F",          "backward-find-char"},
1643   {"M--",          "up-history"},
1644   {"M-h",          "cursor-left"},
1645   {"M-H",          "beginning-of-history"},
1646   {"M-i",          "vi-insert"},
1647   {"M-I",          "vi-insert-at-bol"},
1648   {"M-j",          "down-history"},
1649   {"M-J",          "history-search-forward"},
1650   {"M-k",          "up-history"},
1651   {"M-K",          "history-search-backward"},
1652   {"M-l",          "cursor-right"},
1653   {"M-L",          "end-of-history"},
1654   {"M-n",          "history-re-search-forward"},
1655   {"M-N",          "history-re-search-backward"},
1656   {"M-p",          "append-yank"},
1657   {"M-P",          "yank"},
1658   {"M-r",          "vi-replace-char"},
1659   {"M-R",          "vi-overwrite"},
1660   {"M-s",          "vi-forward-change-char"},
1661   {"M-S",          "vi-change-line"},
1662   {"M-t",          "forward-to-char"},
1663   {"M-T",          "backward-to-char"},
1664   {"M-u",          "vi-undo"},
1665   {"M-w",          "forward-to-word"},
1666   {"M-W",          "forward-to-word"},
1667   {"M-x",          "forward-delete-char"},
1668   {"M-X",          "backward-delete-char"},
1669   {"M-yh",         "backward-copy-char"},
1670   {"M-y^H",        "backward-copy-char"},
1671   {"M-y^?",        "backward-copy-char"},
1672   {"M-yl",         "forward-copy-char"},
1673   {"M-y ",         "forward-copy-char"},
1674   {"M-ye",         "forward-copy-word"},
1675   {"M-yE",         "forward-copy-word"},
1676   {"M-yw",         "forward-copy-word"},
1677   {"M-yW",         "forward-copy-word"},
1678   {"M-yb",         "backward-copy-word"},
1679   {"M-yB",         "backward-copy-word"},
1680   {"M-yf",         "forward-copy-find"},
1681   {"M-yF",         "backward-copy-find"},
1682   {"M-yt",         "forward-copy-to"},
1683   {"M-yT",         "backward-copy-to"},
1684   {"M-y;",         "copy-refind"},
1685   {"M-y,",         "copy-invert-refind"},
1686   {"M-y^",         "copy-to-bol"},
1687   {"M-y0",         "copy-to-bol"},
1688   {"M-y$",         "copy-rest-of-line"},
1689   {"M-yy",         "copy-line"},
1690   {"M-Y",          "copy-line"},
1691   {"M-y|",         "copy-to-column"},
1692   {"M-y%",         "copy-to-parenthesis"},
1693   {"M-^E",         "emacs-mode"},
1694   {"M-^H",         "cursor-left"},
1695   {"M-^?",         "cursor-left"},
1696   {"M-^L",         "clear-screen"},
1697   {"M-^N",         "down-history"},
1698   {"M-^P",         "up-history"},
1699   {"M-^R",         "redisplay"},
1700   {"M-^D",         "list-or-eof"},
1701   {"M-\r",         "newline"},
1702   {"M-\t",         "complete-word"},
1703   {"M-\n",         "newline"},
1704 #ifndef HIDE_FILE_SYSTEM
1705   {"M-^X^R",       "read-init-files"},
1706 #endif
1707   {"M-^Xh",        "list-history"},
1708   {"M-^XH",        "list-history"},
1709   {"down",         "down-history"},
1710   {"up",           "up-history"},
1711   {"left",         "cursor-left"},
1712   {"right",        "cursor-right"},
1713 };
1714 
1715 /*.......................................................................
1716  * Create a new GetLine object.
1717  *
1718  * Input:
1719  *  linelen  size_t    The maximum line length to allow for.
1720  *  histlen  size_t    The number of bytes to allocate for recording
1721  *                     a circular buffer of history lines.
1722  * Output:
1723  *  return  GetLine *  The new object, or NULL on error.
1724  */
1725 GetLine *new_GetLine(size_t linelen, size_t histlen)
1726 {
1727   GetLine *gl;  /* The object to be returned */
1728   int i;
1729 /*
1730  * Check the arguments.
1731  */
1732   if(linelen < 10) {
1733     errno = ENOMEM;
1734     return NULL;
1735   };
1736 /*
1737  * Allocate the container.
1738  */
1739   gl = (GetLine *) malloc(sizeof(GetLine));
1740   if(!gl) {
1741     errno = ENOMEM;
1742     return NULL;
1743   };
1744 /*
1745  * Before attempting any operation that might fail, initialize the
1746  * container at least up to the point at which it can safely be passed
1747  * to del_GetLine().
1748  */
1749   gl->err = NULL;
1750   gl->glh = NULL;
1751   gl->cpl = NULL;
1752 #ifndef HIDE_FILE_SYSTEM
1753   gl->cplfn.fn = cpl_file_completions;
1754 #else
1755   gl->cplfn.fn = gl_no_completions;
1756 #endif
1757   gl->cplfn.data = NULL;
1758 #ifndef WITHOUT_FILE_SYSTEM
1759   gl->ef = NULL;
1760 #endif
1761   gl->capmem = NULL;
1762   gl->cq = NULL;
1763   gl->input_fd = -1;
1764   gl->output_fd = -1;
1765   gl->input_fp = NULL;
1766   gl->output_fp = NULL;
1767   gl->file_fp = NULL;
1768   gl->term = NULL;
1769   gl->is_term = 0;
1770   gl->flush_fn = gl_flush_terminal;
1771   gl->io_mode = GL_NORMAL_MODE;
1772   gl->raw_mode = 0;
1773   gl->pending_io = GLP_WRITE;  /* We will start by writing the prompt */
1774   gl_clear_status(gl);
1775   gl->linelen = linelen;
1776   gl->line = NULL;
1777   gl->cutbuf = NULL;
1778   gl->prompt = NULL;
1779   gl->prompt_len = 0;
1780   gl->prompt_changed = 0;
1781   gl->prompt_style = GL_LITERAL_PROMPT;
1782   gl->cpl_mem = NULL;
1783   gl->ext_act_mem = NULL;
1784   gl->sig_mem = NULL;
1785   gl->sigs = NULL;
1786   gl->signals_masked = 0;
1787   gl->signals_overriden = 0;
1788   sigemptyset(&gl->all_signal_set);
1789   sigemptyset(&gl->old_signal_set);
1790   sigemptyset(&gl->use_signal_set);
1791   gl->bindings = NULL;
1792   gl->ntotal = 0;
1793   gl->buff_curpos = 0;
1794   gl->term_curpos = 0;
1795   gl->term_len = 0;
1796   gl->buff_mark = 0;
1797   gl->insert_curpos = 0;
1798   gl->insert = 1;
1799   gl->number = -1;
1800   gl->endline = 1;
1801   gl->displayed = 0;
1802   gl->redisplay = 0;
1803   gl->postpone = 0;
1804   gl->keybuf[0]='\0';
1805   gl->nbuf = 0;
1806   gl->nread = 0;
1807   gl->current_action.fn = 0;
1808   gl->current_action.data = NULL;
1809   gl->current_count = 0;
1810   gl->preload_id = 0;
1811   gl->preload_history = 0;
1812   gl->keyseq_count = 0;
1813   gl->last_search = -1;
1814   gl->editor = GL_EMACS_MODE;
1815   gl->silence_bell = 0;
1816   gl->automatic_history = 1;
1817   gl->vi.undo.line = NULL;
1818   gl->vi.undo.buff_curpos = 0;
1819   gl->vi.undo.ntotal = 0;
1820   gl->vi.undo.saved = 0;
1821   gl->vi.repeat.action.fn = 0;
1822   gl->vi.repeat.action.data = 0;
1823   gl->vi.repeat.count = 0;
1824   gl->vi.repeat.input_curpos = 0;
1825   gl->vi.repeat.command_curpos = 0;
1826   gl->vi.repeat.input_char = '\0';
1827   gl->vi.repeat.saved = 0;
1828   gl->vi.repeat.active = 0;
1829   gl->vi.command = 0;
1830   gl->vi.find_forward = 0;
1831   gl->vi.find_onto = 0;
1832   gl->vi.find_char = '\0';
1833   gl->left = NULL;
1834   gl->right = NULL;
1835   gl->up = NULL;
1836   gl->down = NULL;
1837   gl->home = NULL;
1838   gl->bol = 0;
1839   gl->clear_eol = NULL;
1840   gl->clear_eod = NULL;
1841   gl->u_arrow = NULL;
1842   gl->d_arrow = NULL;
1843   gl->l_arrow = NULL;
1844   gl->r_arrow = NULL;
1845   gl->sound_bell = NULL;
1846   gl->bold = NULL;
1847   gl->underline = NULL;
1848   gl->standout = NULL;
1849   gl->dim = NULL;
1850   gl->reverse = NULL;
1851   gl->blink = NULL;
1852   gl->text_attr_off = NULL;
1853   gl->nline = 0;
1854   gl->ncolumn = 0;
1855 #ifdef USE_TERMINFO
1856   gl->left_n = NULL;
1857   gl->right_n = NULL;
1858 #elif defined(USE_TERMCAP)
1859   gl->tgetent_buf = NULL;
1860   gl->tgetstr_buf = NULL;
1861 #endif
1862   gl->app_file = NULL;
1863   gl->user_file = NULL;
1864   gl->configured = 0;
1865   gl->echo = 1;
1866   gl->last_signal = -1;
1867 #ifdef HAVE_SELECT
1868   gl->fd_node_mem = NULL;
1869   gl->fd_nodes = NULL;
1870   FD_ZERO(&gl->rfds);
1871   FD_ZERO(&gl->wfds);
1872   FD_ZERO(&gl->ufds);
1873   gl->max_fd = 0;
1874   gl->timer.dt.tv_sec = 0;
1875   gl->timer.dt.tv_usec = 0;
1876   gl->timer.fn = 0;
1877   gl->timer.data = NULL;
1878 #endif
1879 /*
1880  * Allocate an error reporting buffer.
1881  */
1882   gl->err = _new_ErrMsg();
1883   if(!gl->err)
1884     return del_GetLine(gl);
1885 /*
1886  * Allocate the history buffer.
1887  */
1888   gl->glh = _new_GlHistory(histlen);
1889   if(!gl->glh)
1890     return del_GetLine(gl);
1891 /*
1892  * Allocate the resource object for file-completion.
1893  */
1894   gl->cpl = new_WordCompletion();
1895   if(!gl->cpl)
1896     return del_GetLine(gl);
1897 /*
1898  * Allocate the resource object for file-completion.
1899  */
1900 #ifndef WITHOUT_FILE_SYSTEM
1901   gl->ef = new_ExpandFile();
1902   if(!gl->ef)
1903     return del_GetLine(gl);
1904 #endif
1905 /*
1906  * Allocate a string-segment memory allocator for use in storing terminal
1907  * capablity strings.
1908  */
1909   gl->capmem = _new_StringGroup(CAPMEM_SEGMENT_SIZE);
1910   if(!gl->capmem)
1911     return del_GetLine(gl);
1912 /*
1913  * Allocate the character queue that is used to buffer terminal output.
1914  */
1915   gl->cq = _new_GlCharQueue();
1916   if(!gl->cq)
1917     return del_GetLine(gl);
1918 /*
1919  * Allocate a line buffer, leaving 2 extra characters for the terminating
1920  * '\n' and '\0' characters
1921  */
1922   gl->line = (char *) malloc(linelen + 2);
1923   if(!gl->line) {
1924     errno = ENOMEM;
1925     return del_GetLine(gl);
1926   };
1927 /*
1928  * Start with an empty input line.
1929  */
1930   gl_truncate_buffer(gl, 0);
1931 /*
1932  * Allocate a cut buffer.
1933  */
1934   gl->cutbuf = (char *) malloc(linelen + 2);
1935   if(!gl->cutbuf) {
1936     errno = ENOMEM;
1937     return del_GetLine(gl);
1938   };
1939   gl->cutbuf[0] = '\0';
1940 /*
1941  * Allocate an initial empty prompt.
1942  */
1943   _gl_replace_prompt(gl, NULL);
1944   if(!gl->prompt) {
1945     errno = ENOMEM;
1946     return del_GetLine(gl);
1947   };
1948 /*
1949  * Allocate a vi undo buffer.
1950  */
1951   gl->vi.undo.line = (char *) malloc(linelen + 2);
1952   if(!gl->vi.undo.line) {
1953     errno = ENOMEM;
1954     return del_GetLine(gl);
1955   };
1956   gl->vi.undo.line[0] = '\0';
1957 /*
1958  * Allocate a freelist from which to allocate nodes for the list
1959  * of completion functions.
1960  */
1961   gl->cpl_mem = _new_FreeList(sizeof(GlCplCallback), GL_CPL_FREELIST_BLOCKING);
1962   if(!gl->cpl_mem)
1963     return del_GetLine(gl);
1964 /*
1965  * Allocate a freelist from which to allocate nodes for the list
1966  * of external action functions.
1967  */
1968   gl->ext_act_mem = _new_FreeList(sizeof(GlExternalAction),
1969 				  GL_EXT_ACT_FREELIST_BLOCKING);
1970   if(!gl->ext_act_mem)
1971     return del_GetLine(gl);
1972 /*
1973  * Allocate a freelist from which to allocate nodes for the list
1974  * of signals.
1975  */
1976   gl->sig_mem = _new_FreeList(sizeof(GlSignalNode), GLS_FREELIST_BLOCKING);
1977   if(!gl->sig_mem)
1978     return del_GetLine(gl);
1979 /*
1980  * Install initial dispositions for the default list of signals that
1981  * gl_get_line() traps.
1982  */
1983   for(i=0; i<sizeof(gl_signal_list)/sizeof(gl_signal_list[0]); i++) {
1984     const struct GlDefSignal *sig = gl_signal_list + i;
1985     if(_gl_trap_signal(gl, sig->signo, sig->flags, sig->after,
1986 		       sig->errno_value))
1987       return del_GetLine(gl);
1988   };
1989 /*
1990  * Allocate an empty table of key bindings.
1991  */
1992   gl->bindings = _new_KeyTab();
1993   if(!gl->bindings)
1994     return del_GetLine(gl);
1995 /*
1996  * Define the available actions that can be bound to key sequences.
1997  */
1998   for(i=0; i<sizeof(gl_actions)/sizeof(gl_actions[0]); i++) {
1999     if(_kt_set_action(gl->bindings, gl_actions[i].name, gl_actions[i].fn, NULL))
2000       return del_GetLine(gl);
2001   };
2002 /*
2003  * Set up the default bindings.
2004  */
2005   if(gl_change_editor(gl, gl->editor))
2006     return del_GetLine(gl);
2007 /*
2008  * Allocate termcap buffers.
2009  */
2010 #ifdef USE_TERMCAP
2011   gl->tgetent_buf = (char *) malloc(TERMCAP_BUF_SIZE);
2012   gl->tgetstr_buf = (char *) malloc(TERMCAP_BUF_SIZE);
2013   if(!gl->tgetent_buf || !gl->tgetstr_buf) {
2014     errno = ENOMEM;
2015     return del_GetLine(gl);
2016   };
2017 #endif
2018 /*
2019  * Set up for I/O assuming stdin and stdout.
2020  */
2021   if(_gl_change_terminal(gl, stdin, stdout, getenv("TERM")))
2022     return del_GetLine(gl);
2023 /*
2024  * Create a freelist for use in allocating GlFdNode list nodes.
2025  */
2026 #ifdef HAVE_SELECT
2027   gl->fd_node_mem = _new_FreeList(sizeof(GlFdNode), GLFD_FREELIST_BLOCKING);
2028   if(!gl->fd_node_mem)
2029     return del_GetLine(gl);
2030 #endif
2031 /*
2032  * We are done for now.
2033  */
2034   return gl;
2035 }
2036 
2037 /*.......................................................................
2038  * Delete a GetLine object.
2039  *
2040  * Input:
2041  *  gl     GetLine *  The object to be deleted.
2042  * Output:
2043  *  return GetLine *  The deleted object (always NULL).
2044  */
2045 GetLine *del_GetLine(GetLine *gl)
2046 {
2047   if(gl) {
2048 /*
2049  * If the terminal is in raw server mode, reset it.
2050  */
2051     _gl_normal_io(gl);
2052 /*
2053  * Deallocate all objects contained by gl.
2054  */
2055     gl->err = _del_ErrMsg(gl->err);
2056     gl->glh = _del_GlHistory(gl->glh);
2057     gl->cpl = del_WordCompletion(gl->cpl);
2058 #ifndef WITHOUT_FILE_SYSTEM
2059     gl->ef = del_ExpandFile(gl->ef);
2060 #endif
2061     gl->capmem = _del_StringGroup(gl->capmem);
2062     gl->cq = _del_GlCharQueue(gl->cq);
2063     if(gl->file_fp)
2064       fclose(gl->file_fp);
2065     if(gl->term)
2066       free(gl->term);
2067     if(gl->line)
2068       free(gl->line);
2069     if(gl->cutbuf)
2070       free(gl->cutbuf);
2071     if(gl->prompt)
2072       free(gl->prompt);
2073     gl->cpl_mem = _del_FreeList(gl->cpl_mem, 1);
2074     gl->ext_act_mem = _del_FreeList(gl->ext_act_mem, 1);
2075     gl->sig_mem = _del_FreeList(gl->sig_mem, 1);
2076     gl->sigs = NULL;       /* Already freed by freeing sig_mem */
2077     gl->bindings = _del_KeyTab(gl->bindings);
2078     if(gl->vi.undo.line)
2079       free(gl->vi.undo.line);
2080 #ifdef USE_TERMCAP
2081     if(gl->tgetent_buf)
2082       free(gl->tgetent_buf);
2083     if(gl->tgetstr_buf)
2084       free(gl->tgetstr_buf);
2085 #endif
2086     if(gl->app_file)
2087       free(gl->app_file);
2088     if(gl->user_file)
2089       free(gl->user_file);
2090 #ifdef HAVE_SELECT
2091     gl->fd_node_mem = _del_FreeList(gl->fd_node_mem, 1);
2092     gl->fd_nodes = NULL;  /* Already freed by freeing gl->fd_node_mem */
2093 #endif
2094 /*
2095  * Delete the now empty container.
2096  */
2097     free(gl);
2098   };
2099   return NULL;
2100 }
2101 
2102 /*.......................................................................
2103  * Bind a control or meta character to an action.
2104  *
2105  * Input:
2106  *  gl         GetLine *  The resource object of this program.
2107  *  binder    KtBinder    The source of the binding.
2108  *  c             char    The control or meta character.
2109  *                        If this is '\0', the call is ignored.
2110  *  action  const char *  The action name to bind the key to.
2111  * Output:
2112  *  return         int    0 - OK.
2113  *                        1 - Error.
2114  */
2115 static int gl_bind_control_char(GetLine *gl, KtBinder binder, char c,
2116 				const char *action)
2117 {
2118   char keyseq[2];
2119 /*
2120  * Quietly reject binding to the NUL control character, since this
2121  * is an ambiguous prefix of all bindings.
2122  */
2123   if(c == '\0')
2124     return 0;
2125 /*
2126  * Making sure not to bind characters which aren't either control or
2127  * meta characters.
2128  */
2129   if(IS_CTRL_CHAR(c) || IS_META_CHAR(c)) {
2130     keyseq[0] = c;
2131     keyseq[1] = '\0';
2132   } else {
2133     return 0;
2134   };
2135 /*
2136  * Install the binding.
2137  */
2138   if(_kt_set_keybinding(gl->bindings, binder, keyseq, action)) {
2139     _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
2140     return 1;
2141   };
2142   return 0;
2143 }
2144 
2145 /*.......................................................................
2146  * Read a line from the user.
2147  *
2148  * Input:
2149  *  gl       GetLine *  A resource object returned by new_GetLine().
2150  *  prompt      char *  The prompt to prefix the line with.
2151  *  start_line  char *  The initial contents of the input line, or NULL
2152  *                      if it should start out empty.
2153  *  start_pos    int    If start_line isn't NULL, this specifies the
2154  *                      index of the character over which the cursor
2155  *                      should initially be positioned within the line.
2156  *                      If you just want it to follow the last character
2157  *                      of the line, send -1.
2158  * Output:
2159  *  return      char *  An internal buffer containing the input line, or
2160  *                      NULL at the end of input. If the line fitted in
2161  *                      the buffer there will be a '\n' newline character
2162  *                      before the terminating '\0'. If it was truncated
2163  *                      there will be no newline character, and the remains
2164  *                      of the line should be retrieved via further calls
2165  *                      to this function.
2166  */
2167 char *gl_get_line(GetLine *gl, const char *prompt,
2168 		  const char *start_line, int start_pos)
2169 {
2170   char *retval;   /* The return value of _gl_get_line() */
2171 /*
2172  * Check the arguments.
2173  */
2174   if(!gl) {
2175     errno = EINVAL;
2176     return NULL;
2177   };
2178 /*
2179  * Temporarily block all of the signals that we have been asked to trap.
2180  */
2181   if(gl_mask_signals(gl, &gl->old_signal_set))
2182     return NULL;
2183 /*
2184  * Perform the command-line editing task.
2185  */
2186   retval = _gl_get_line(gl, prompt, start_line, start_pos);
2187 /*
2188  * Restore the process signal mask to how it was when this function was
2189  * first called.
2190  */
2191   gl_unmask_signals(gl, &gl->old_signal_set);
2192   return retval;
2193 }
2194 
2195 
2196 /*.......................................................................
2197  * This is the main body of the public function gl_get_line().
2198  */
2199 static char *_gl_get_line(GetLine *gl, const char *prompt,
2200 			  const char *start_line, int start_pos)
2201 {
2202   int waserr = 0;    /* True if an error occurs */
2203 /*
2204  * Assume that this call will successfully complete the input
2205  * line until proven otherwise.
2206  */
2207   gl_clear_status(gl);
2208 /*
2209  * If this is the first call to this function since new_GetLine(),
2210  * complete any postponed configuration.
2211  */
2212   if(!gl->configured) {
2213     (void) _gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE);
2214     gl->configured = 1;
2215   };
2216 /*
2217  * Before installing our signal handler functions, record the fact
2218  * that there are no pending signals.
2219  */
2220   gl_pending_signal = -1;
2221 /*
2222  * Temporarily override the signal handlers of the calling program,
2223  * so that we can intercept signals that would leave the terminal
2224  * in a bad state.
2225  */
2226   waserr = gl_override_signal_handlers(gl);
2227 /*
2228  * After recording the current terminal settings, switch the terminal
2229  * into raw input mode.
2230  */
2231   waserr = waserr || _gl_raw_io(gl, 1);
2232 /*
2233  * Attempt to read the line. This will require more than one attempt if
2234  * either a current temporary input file is opened by gl_get_input_line()
2235  * or the end of a temporary input file is reached by gl_read_stream_line().
2236  */
2237   while(!waserr) {
2238 /*
2239  * Read a line from a non-interactive stream?
2240  */
2241     if(gl->file_fp || !gl->is_term) {
2242       if(gl_read_stream_line(gl)==0) {
2243 	break;
2244       } else if(gl->file_fp) {
2245 	gl_revert_input(gl);
2246 	gl_record_status(gl, GLR_NEWLINE, 0);
2247       } else {
2248 	waserr = 1;
2249 	break;
2250       };
2251     };
2252 /*
2253  * Read from the terminal? Note that the above if() block may have
2254  * changed gl->file_fp, so it is necessary to retest it here, rather
2255  * than using an else statement.
2256  */
2257     if(!gl->file_fp && gl->is_term) {
2258       if(gl_get_input_line(gl, prompt, start_line, start_pos))
2259 	waserr = 1;
2260       else
2261 	break;
2262     };
2263   };
2264 /*
2265  * If an error occurred, but gl->rtn_status is still set to
2266  * GLR_NEWLINE, change the status to GLR_ERROR. Otherwise
2267  * leave it at whatever specific value was assigned by the function
2268  * that aborted input. This means that only functions that trap
2269  * non-generic errors have to remember to update gl->rtn_status
2270  * themselves.
2271  */
2272   if(waserr && gl->rtn_status == GLR_NEWLINE)
2273     gl_record_status(gl, GLR_ERROR, errno);
2274 /*
2275  * Restore terminal settings.
2276  */
2277   if(gl->io_mode != GL_SERVER_MODE)
2278     _gl_normal_io(gl);
2279 /*
2280  * Restore the signal handlers.
2281  */
2282   gl_restore_signal_handlers(gl);
2283 /*
2284  * If gl_get_line() gets aborted early, the errno value associated
2285  * with the event that caused this to happen is recorded in
2286  * gl->rtn_errno. Since errno may have been overwritten by cleanup
2287  * functions after this, restore its value to the value that it had
2288  * when the error condition occured, so that the caller can examine it
2289  * to find out what happened.
2290  */
2291   errno = gl->rtn_errno;
2292 /*
2293  * Check the completion status to see how to return.
2294  */
2295   switch(gl->rtn_status) {
2296   case GLR_NEWLINE:    /* Success */
2297     return gl->line;
2298   case GLR_BLOCKED:    /* These events abort the current input line, */
2299   case GLR_SIGNAL:     /*  when in normal blocking I/O mode, but only */
2300   case GLR_TIMEOUT:    /*  temporarily pause line editing when in */
2301   case GLR_FDABORT:    /*  non-blocking server I/O mode. */
2302     if(gl->io_mode != GL_SERVER_MODE)
2303       _gl_abandon_line(gl);
2304     return NULL;
2305   case GLR_ERROR:      /* Unrecoverable errors abort the input line, */
2306   case GLR_EOF:        /*  regardless of the I/O mode. */
2307   default:
2308     _gl_abandon_line(gl);
2309     return NULL;
2310   };
2311 }
2312 
2313 /*.......................................................................
2314  * Read a single character from the user.
2315  *
2316  * Input:
2317  *  gl       GetLine *  A resource object returned by new_GetLine().
2318  *  prompt      char *  The prompt to prefix the line with, or NULL if
2319  *                      no prompt is required.
2320  *  defchar     char    The character to substitute if the
2321  *                      user simply hits return, or '\n' if you don't
2322  *                      need to substitute anything.
2323  * Output:
2324  *  return       int    The character that was read, or EOF if the read
2325  *                      had to be aborted (in which case you can call
2326  *                      gl_return_status() to find out why).
2327  */
2328 int gl_query_char(GetLine *gl, const char *prompt, char defchar)
2329 {
2330   int retval;   /* The return value of _gl_query_char() */
2331 /*
2332  * Check the arguments.
2333  */
2334   if(!gl) {
2335     errno = EINVAL;
2336     return EOF;
2337   };
2338 /*
2339  * Temporarily block all of the signals that we have been asked to trap.
2340  */
2341   if(gl_mask_signals(gl, &gl->old_signal_set))
2342     return EOF;
2343 /*
2344  * Perform the character reading task.
2345  */
2346   retval = _gl_query_char(gl, prompt, defchar);
2347 /*
2348  * Restore the process signal mask to how it was when this function was
2349  * first called.
2350  */
2351   gl_unmask_signals(gl, &gl->old_signal_set);
2352   return retval;
2353 }
2354 
2355 /*.......................................................................
2356  * This is the main body of the public function gl_query_char().
2357  */
2358 static int _gl_query_char(GetLine *gl, const char *prompt, char defchar)
2359 {
2360   int c = EOF;       /* The character to be returned */
2361   int waserr = 0;    /* True if an error occurs */
2362 /*
2363  * Assume that this call will successfully complete the input operation
2364  * until proven otherwise.
2365  */
2366   gl_clear_status(gl);
2367 /*
2368  * If this is the first call to this function or gl_get_line(),
2369  * since new_GetLine(), complete any postponed configuration.
2370  */
2371   if(!gl->configured) {
2372     (void) _gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE);
2373     gl->configured = 1;
2374   };
2375 /*
2376  * Before installing our signal handler functions, record the fact
2377  * that there are no pending signals.
2378  */
2379   gl_pending_signal = -1;
2380 /*
2381  * Temporarily override the signal handlers of the calling program,
2382  * so that we can intercept signals that would leave the terminal
2383  * in a bad state.
2384  */
2385   waserr = gl_override_signal_handlers(gl);
2386 /*
2387  * After recording the current terminal settings, switch the terminal
2388  * into raw input mode without redisplaying any partially entered
2389  * input line.
2390  */
2391   waserr = waserr || _gl_raw_io(gl, 0);
2392 /*
2393  * Attempt to read the line. This will require more than one attempt if
2394  * either a current temporary input file is opened by gl_get_input_line()
2395  * or the end of a temporary input file is reached by gl_read_stream_line().
2396  */
2397   while(!waserr) {
2398 /*
2399  * Read a line from a non-interactive stream?
2400  */
2401     if(gl->file_fp || !gl->is_term) {
2402       c = gl_read_stream_char(gl);
2403       if(c != EOF) {            /* Success? */
2404 	if(c=='\n') c = defchar;
2405 	break;
2406       } else if(gl->file_fp) {  /* End of temporary input file? */
2407 	gl_revert_input(gl);
2408 	gl_record_status(gl, GLR_NEWLINE, 0);
2409       } else {                  /* An error? */
2410 	waserr = 1;
2411 	break;
2412       };
2413     };
2414 /*
2415  * Read from the terminal? Note that the above if() block may have
2416  * changed gl->file_fp, so it is necessary to retest it here, rather
2417  * than using an else statement.
2418  */
2419     if(!gl->file_fp && gl->is_term) {
2420       c = gl_get_query_char(gl, prompt, defchar);
2421       if(c==EOF)
2422 	waserr = 1;
2423       else
2424 	break;
2425     };
2426   };
2427 /*
2428  * If an error occurred, but gl->rtn_status is still set to
2429  * GLR_NEWLINE, change the status to GLR_ERROR. Otherwise
2430  * leave it at whatever specific value was assigned by the function
2431  * that aborted input. This means that only functions that trap
2432  * non-generic errors have to remember to update gl->rtn_status
2433  * themselves.
2434  */
2435   if(waserr && gl->rtn_status == GLR_NEWLINE)
2436     gl_record_status(gl, GLR_ERROR, errno);
2437 /*
2438  * Restore terminal settings.
2439  */
2440   if(gl->io_mode != GL_SERVER_MODE)
2441     _gl_normal_io(gl);
2442 /*
2443  * Restore the signal handlers.
2444  */
2445   gl_restore_signal_handlers(gl);
2446 /*
2447  * If this function gets aborted early, the errno value associated
2448  * with the event that caused this to happen is recorded in
2449  * gl->rtn_errno. Since errno may have been overwritten by cleanup
2450  * functions after this, restore its value to the value that it had
2451  * when the error condition occured, so that the caller can examine it
2452  * to find out what happened.
2453  */
2454   errno = gl->rtn_errno;
2455 /*
2456  * Error conditions are signalled to the caller, by setting the returned
2457  * character to EOF.
2458  */
2459   if(gl->rtn_status != GLR_NEWLINE)
2460     c = EOF;
2461 /*
2462  * In this mode, every character that is read is a completed
2463  * transaction, just like reading a completed input line, so prepare
2464  * for the next input line or character.
2465  */
2466   _gl_abandon_line(gl);
2467 /*
2468  * Return the acquired character.
2469  */
2470   return c;
2471 }
2472 
2473 /*.......................................................................
2474  * Record of the signal handlers of the calling program, so that they
2475  * can be restored later.
2476  *
2477  * Input:
2478  *  gl    GetLine *   The resource object of this library.
2479  * Output:
2480  *  return    int     0 - OK.
2481  *                    1 - Error.
2482  */
2483 static int gl_override_signal_handlers(GetLine *gl)
2484 {
2485   GlSignalNode *sig;   /* A node in the list of signals to be caught */
2486 /*
2487  * Set up our signal handler.
2488  */
2489   SigAction act;
2490   act.sa_handler = gl_signal_handler;
2491   memcpy(&act.sa_mask, &gl->all_signal_set, sizeof(sigset_t));
2492   act.sa_flags = 0;
2493 /*
2494  * Get the subset of the signals that we are supposed to trap that
2495  * should actually be trapped.
2496  */
2497   sigemptyset(&gl->use_signal_set);
2498   for(sig=gl->sigs; sig; sig=sig->next) {
2499 /*
2500  * Trap this signal? If it is blocked by the calling program and we
2501  * haven't been told to unblock it, don't arrange to trap this signal.
2502  */
2503     if(sig->flags & GLS_UNBLOCK_SIG ||
2504        !sigismember(&gl->old_signal_set, sig->signo)) {
2505       if(sigaddset(&gl->use_signal_set, sig->signo) == -1) {
2506 	_err_record_msg(gl->err, "sigaddset error", END_ERR_MSG);
2507 	return 1;
2508       };
2509     };
2510   };
2511 /*
2512  * Override the actions of the signals that we are trapping.
2513  */
2514   for(sig=gl->sigs; sig; sig=sig->next) {
2515     if(sigismember(&gl->use_signal_set, sig->signo)) {
2516       sigdelset(&act.sa_mask, sig->signo);
2517       if(sigaction(sig->signo, &act, &sig->original)) {
2518 	_err_record_msg(gl->err, "sigaction error", END_ERR_MSG);
2519 	return 1;
2520       };
2521       sigaddset(&act.sa_mask, sig->signo);
2522     };
2523   };
2524 /*
2525  * Record the fact that the application's signal handlers have now
2526  * been overriden.
2527  */
2528   gl->signals_overriden = 1;
2529 /*
2530  * Just in case a SIGWINCH signal was sent to the process while our
2531  * SIGWINCH signal handler wasn't in place, check to see if the terminal
2532  * size needs updating.
2533  */
2534   if(_gl_update_size(gl))
2535     return 1;
2536   return 0;
2537 }
2538 
2539 /*.......................................................................
2540  * Restore the signal handlers of the calling program.
2541  *
2542  * Input:
2543  *  gl     GetLine *  The resource object of this library.
2544  * Output:
2545  *  return     int    0 - OK.
2546  *                    1 - Error.
2547  */
2548 static int gl_restore_signal_handlers(GetLine *gl)
2549 {
2550   GlSignalNode *sig;   /* A node in the list of signals to be caught */
2551 /*
2552  * Restore application signal handlers that were overriden
2553  * by gl_override_signal_handlers().
2554  */
2555   for(sig=gl->sigs; sig; sig=sig->next) {
2556     if(sigismember(&gl->use_signal_set, sig->signo) &&
2557        sigaction(sig->signo, &sig->original, NULL)) {
2558       _err_record_msg(gl->err, "sigaction error", END_ERR_MSG);
2559       return 1;
2560     };
2561   };
2562 /*
2563  * Record the fact that the application's signal handlers have now
2564  * been restored.
2565  */
2566   gl->signals_overriden = 0;
2567   return 0;
2568 }
2569 
2570 /*.......................................................................
2571  * This signal handler simply records the fact that a given signal was
2572  * caught in the file-scope gl_pending_signal variable.
2573  */
2574 static void gl_signal_handler(int signo)
2575 {
2576   gl_pending_signal = signo;
2577   siglongjmp(gl_setjmp_buffer, 1);
2578 }
2579 
2580 /*.......................................................................
2581  * Switch the terminal into raw mode after storing the previous terminal
2582  * settings in gl->attributes.
2583  *
2584  * Input:
2585  *  gl     GetLine *   The resource object of this program.
2586  * Output:
2587  *  return     int     0 - OK.
2588  *                     1 - Error.
2589  */
2590 static int gl_raw_terminal_mode(GetLine *gl)
2591 {
2592   Termios newattr;   /* The new terminal attributes */
2593 /*
2594  * If the terminal is already in raw mode, do nothing.
2595  */
2596   if(gl->raw_mode)
2597     return 0;
2598 /*
2599  * Record the current terminal attributes.
2600  */
2601   if(tcgetattr(gl->input_fd, &gl->oldattr)) {
2602     _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG);
2603     return 1;
2604   };
2605 /*
2606  * This function shouldn't do anything but record the current terminal
2607  * attritubes if editing has been disabled.
2608  */
2609   if(gl->editor == GL_NO_EDITOR)
2610     return 0;
2611 /*
2612  * Modify the existing attributes.
2613  */
2614   newattr = gl->oldattr;
2615 /*
2616  * Turn off local echo, canonical input mode and extended input processing.
2617  */
2618   newattr.c_lflag &= ~(ECHO | ICANON | IEXTEN);
2619 /*
2620  * Don't translate carriage return to newline, turn off input parity
2621  * checking, don't strip off 8th bit, turn off output flow control.
2622  */
2623   newattr.c_iflag &= ~(ICRNL | INPCK | ISTRIP);
2624 /*
2625  * Clear size bits, turn off parity checking, and allow 8-bit characters.
2626  */
2627   newattr.c_cflag &= ~(CSIZE | PARENB);
2628   newattr.c_cflag |= CS8;
2629 /*
2630  * Turn off output processing.
2631  */
2632   newattr.c_oflag &= ~(OPOST);
2633 /*
2634  * Request one byte at a time, without waiting.
2635  */
2636   newattr.c_cc[VMIN] = gl->io_mode==GL_SERVER_MODE ? 0:1;
2637   newattr.c_cc[VTIME] = 0;
2638 /*
2639  * Install the new terminal modes.
2640  */
2641   while(tcsetattr(gl->input_fd, TCSADRAIN, &newattr)) {
2642     if(errno != EINTR) {
2643       _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
2644       return 1;
2645     };
2646   };
2647 /*
2648  * Record the new terminal mode.
2649  */
2650   gl->raw_mode = 1;
2651   return 0;
2652 }
2653 
2654 /*.......................................................................
2655  * Restore the terminal attributes recorded in gl->oldattr.
2656  *
2657  * Input:
2658  *  gl     GetLine *   The resource object of this library.
2659  * Output:
2660  *  return     int     0 - OK.
2661  *                     1 - Error.
2662  */
2663 static int gl_restore_terminal_attributes(GetLine *gl)
2664 {
2665   int waserr = 0;
2666 /*
2667  * If not in raw mode, do nothing.
2668  */
2669   if(!gl->raw_mode)
2670     return 0;
2671 /*
2672  * Before changing the terminal attributes, make sure that all output
2673  * has been passed to the terminal.
2674  */
2675   if(gl_flush_output(gl))
2676     waserr = 1;
2677 /*
2678  * Reset the terminal attributes to the values that they had on
2679  * entry to gl_get_line().
2680  */
2681   while(tcsetattr(gl->input_fd, TCSADRAIN, &gl->oldattr)) {
2682     if(errno != EINTR) {
2683       _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
2684       waserr = 1;
2685       break;
2686     };
2687   };
2688 /*
2689  * Record the new terminal mode.
2690  */
2691   gl->raw_mode = 0;
2692   return waserr;
2693 }
2694 
2695 /*.......................................................................
2696  * Switch the terminal file descriptor to use non-blocking I/O.
2697  *
2698  * Input:
2699  *  gl         GetLine *  The resource object of gl_get_line().
2700  *  fd             int    The file descriptor to make non-blocking.
2701  */
2702 static int gl_nonblocking_io(GetLine *gl, int fd)
2703 {
2704   int fcntl_flags;   /* The new file-descriptor control flags */
2705 /*
2706  * Is non-blocking I/O supported on this system?  Note that even
2707  * without non-blocking I/O, the terminal will probably still act as
2708  * though it was non-blocking, because we also set the terminal
2709  * attributes to return immediately if no input is available and we
2710  * use select() to wait to be able to write. If select() also isn't
2711  * available, then input will probably remain fine, but output could
2712  * block, depending on the behaviour of the terminal driver.
2713  */
2714 #if defined(NON_BLOCKING_FLAG)
2715 /*
2716  * Query the current file-control flags, and add the
2717  * non-blocking I/O flag.
2718  */
2719   fcntl_flags = fcntl(fd, F_GETFL) | NON_BLOCKING_FLAG;
2720 /*
2721  * Install the new control flags.
2722  */
2723   if(fcntl(fd, F_SETFL, fcntl_flags) == -1) {
2724     _err_record_msg(gl->err, "fcntl error", END_ERR_MSG);
2725     return 1;
2726   };
2727 #endif
2728   return 0;
2729 }
2730 
2731 /*.......................................................................
2732  * Switch to blocking terminal I/O.
2733  *
2734  * Input:
2735  *  gl         GetLine *  The resource object of gl_get_line().
2736  *  fd             int    The file descriptor to make blocking.
2737  */
2738 static int gl_blocking_io(GetLine *gl, int fd)
2739 {
2740   int fcntl_flags;   /* The new file-descriptor control flags */
2741 /*
2742  * Is non-blocking I/O implemented on this system?
2743  */
2744 #if defined(NON_BLOCKING_FLAG)
2745 /*
2746  * Query the current file control flags and remove the non-blocking
2747  * I/O flag.
2748  */
2749   fcntl_flags = fcntl(fd, F_GETFL) & ~NON_BLOCKING_FLAG;
2750 /*
2751  * Install the modified control flags.
2752  */
2753   if(fcntl(fd, F_SETFL, fcntl_flags) == -1) {
2754     _err_record_msg(gl->err, "fcntl error", END_ERR_MSG);
2755     return 1;
2756   };
2757 #endif
2758   return 0;
2759 }
2760 
2761 /*.......................................................................
2762  * Read a new input line from the user.
2763  *
2764  * Input:
2765  *  gl         GetLine *  The resource object of this library.
2766  *  prompt        char *  The prompt to prefix the line with, or NULL to
2767  *                        use the same prompt that was used by the previous
2768  *                        line.
2769  *  start_line    char *  The initial contents of the input line, or NULL
2770  *                        if it should start out empty.
2771  *  start_pos      int    If start_line isn't NULL, this specifies the
2772  *                        index of the character over which the cursor
2773  *                        should initially be positioned within the line.
2774  *                        If you just want it to follow the last character
2775  *                        of the line, send -1.
2776  * Output:
2777  *  return    int    0 - OK.
2778  *                   1 - Error.
2779  */
2780 static int gl_get_input_line(GetLine *gl, const char *prompt,
2781 			     const char *start_line, int start_pos)
2782 {
2783   char c;               /* The character being read */
2784 /*
2785  * Flush any pending output to the terminal.
2786  */
2787   if(_glq_char_count(gl->cq) > 0 && gl_flush_output(gl))
2788     return 1;
2789 /*
2790  * Are we starting a new line?
2791  */
2792   if(gl->endline) {
2793 /*
2794  * Delete any incompletely enterred line.
2795  */
2796     if(gl_erase_line(gl))
2797       return 1;
2798 /*
2799  * Display the new line to be edited.
2800  */
2801     if(gl_present_line(gl, prompt, start_line, start_pos))
2802       return 1;
2803   };
2804 /*
2805  * Read one character at a time.
2806  */
2807   while(gl_read_terminal(gl, 1, &c) == 0) {
2808 /*
2809  * Increment the count of the number of key sequences entered.
2810  */
2811     gl->keyseq_count++;
2812 /*
2813  * Interpret the character either as the start of a new key-sequence,
2814  * as a continuation of a repeat count, or as a printable character
2815  * to be added to the line.
2816  */
2817     if(gl_interpret_char(gl, c))
2818       break;
2819 /*
2820  * If we just ran an action function which temporarily asked for
2821  * input to be taken from a file, abort this call.
2822  */
2823     if(gl->file_fp)
2824       return 0;
2825 /*
2826  * Has the line been completed?
2827  */
2828     if(gl->endline)
2829       return gl_line_ended(gl, c);
2830   };
2831 /*
2832  * To get here, gl_read_terminal() must have returned non-zero. See
2833  * whether a signal was caught that requested that the current line
2834  * be returned.
2835  */
2836   if(gl->endline)
2837     return gl_line_ended(gl, '\n');
2838 /*
2839  * If I/O blocked while attempting to get the latest character
2840  * of the key sequence, rewind the key buffer to allow interpretation of
2841  * the current key sequence to be restarted on the next call to this
2842  * function.
2843  */
2844   if(gl->rtn_status == GLR_BLOCKED && gl->pending_io == GLP_READ)
2845     gl->nread = 0;
2846   return 1;
2847 }
2848 
2849 /*.......................................................................
2850  * This is the private function of gl_query_char() that handles
2851  * prompting the user, reading a character from the terminal, and
2852  * displaying what the user entered.
2853  *
2854  * Input:
2855  *  gl         GetLine *  The resource object of this library.
2856  *  prompt        char *  The prompt to prefix the line with.
2857  *  defchar       char    The character to substitute if the
2858  *                        user simply hits return, or '\n' if you don't
2859  *                        need to substitute anything.
2860  * Output:
2861  *  return         int    The character that was read, or EOF if something
2862  *                        prevented a character from being read.
2863  */
2864 static int gl_get_query_char(GetLine *gl, const char *prompt, int defchar)
2865 {
2866   char c;               /* The character being read */
2867   int retval;           /* The return value of this function */
2868 /*
2869  * Flush any pending output to the terminal.
2870  */
2871   if(_glq_char_count(gl->cq) > 0 && gl_flush_output(gl))
2872     return EOF;
2873 /*
2874  * Delete any incompletely entered line.
2875  */
2876   if(gl_erase_line(gl))
2877     return EOF;
2878 /*
2879  * Reset the line input parameters and display the prompt, if any.
2880  */
2881   if(gl_present_line(gl, prompt, NULL, 0))
2882     return EOF;
2883 /*
2884  * Read one character.
2885  */
2886   if(gl_read_terminal(gl, 1, &c) == 0) {
2887 /*
2888  * In this mode, count each character as being a new key-sequence.
2889  */
2890     gl->keyseq_count++;
2891 /*
2892  * Delete the character that was read, from the key-press buffer.
2893  */
2894     gl_discard_chars(gl, gl->nread);
2895 /*
2896  * Convert carriage returns to newlines.
2897  */
2898     if(c == '\r')
2899       c = '\n';
2900 /*
2901  * If the user just hit return, subsitute the default character.
2902  */
2903     if(c == '\n')
2904       c = defchar;
2905 /*
2906  * Display the entered character to the right of the prompt.
2907  */
2908     if(c!='\n') {
2909       if(gl_end_of_line(gl, 1, NULL)==0)
2910 	gl_print_char(gl, c, ' ');
2911     };
2912 /*
2913  * Record the return character, and mark the call as successful.
2914  */
2915     retval = c;
2916     gl_record_status(gl, GLR_NEWLINE, 0);
2917 /*
2918  * Was a signal caught whose disposition is to cause the current input
2919  * line to be returned? If so return a newline character.
2920  */
2921   } else if(gl->endline) {
2922     retval = '\n';
2923     gl_record_status(gl, GLR_NEWLINE, 0);
2924   } else {
2925     retval = EOF;
2926   };
2927 /*
2928  * Start a new line.
2929  */
2930   if(gl_start_newline(gl, 1))
2931     return EOF;
2932 /*
2933  * Attempt to flush any pending output.
2934  */
2935   (void) gl_flush_output(gl);
2936 /*
2937  * Return either the character that was read, or EOF if an error occurred.
2938  */
2939   return retval;
2940 }
2941 
2942 /*.......................................................................
2943  * Add a character to the line buffer at the current cursor position,
2944  * inserting or overwriting according the current mode.
2945  *
2946  * Input:
2947  *  gl   GetLine *   The resource object of this library.
2948  *  c       char     The character to be added.
2949  * Output:
2950  *  return   int     0 - OK.
2951  *                   1 - Insufficient room.
2952  */
2953 static int gl_add_char_to_line(GetLine *gl, char c)
2954 {
2955 /*
2956  * Keep a record of the current cursor position.
2957  */
2958   int buff_curpos = gl->buff_curpos;
2959   int term_curpos = gl->term_curpos;
2960 /*
2961  * Work out the displayed width of the new character.
2962  */
2963   int width = gl_displayed_char_width(gl, c, term_curpos);
2964 /*
2965  * If we are in insert mode, or at the end of the line,
2966  * check that we can accomodate a new character in the buffer.
2967  * If not, simply return, leaving it up to the calling program
2968  * to check for the absence of a newline character.
2969  */
2970   if((gl->insert || buff_curpos >= gl->ntotal) && gl->ntotal >= gl->linelen)
2971     return 0;
2972 /*
2973  * Are we adding characters to the line (ie. inserting or appending)?
2974  */
2975   if(gl->insert || buff_curpos >= gl->ntotal) {
2976 /*
2977  * If inserting, make room for the new character.
2978  */
2979     if(buff_curpos < gl->ntotal)
2980       gl_make_gap_in_buffer(gl, buff_curpos, 1);
2981 /*
2982  * Copy the character into the buffer.
2983  */
2984     gl_buffer_char(gl, c, buff_curpos);
2985     gl->buff_curpos++;
2986 /*
2987  * Redraw the line from the cursor position to the end of the line,
2988  * and move the cursor to just after the added character.
2989  */
2990     if(gl_print_string(gl, gl->line + buff_curpos, '\0') ||
2991        gl_set_term_curpos(gl, term_curpos + width))
2992       return 1;
2993 /*
2994  * Are we overwriting an existing character?
2995  */
2996   } else {
2997 /*
2998  * Get the width of the character being overwritten.
2999  */
3000     int old_width = gl_displayed_char_width(gl, gl->line[buff_curpos],
3001 					    term_curpos);
3002 /*
3003  * Overwrite the character in the buffer.
3004  */
3005     gl_buffer_char(gl, c, buff_curpos);
3006 /*
3007  * If we are replacing with a narrower character, we need to
3008  * redraw the terminal string to the end of the line, then
3009  * overwrite the trailing old_width - width characters
3010  * with spaces.
3011  */
3012     if(old_width > width) {
3013       if(gl_print_string(gl, gl->line + buff_curpos, '\0'))
3014 	return 1;
3015 /*
3016  * Clear to the end of the terminal.
3017  */
3018       if(gl_truncate_display(gl))
3019 	return 1;
3020 /*
3021  * Move the cursor to the end of the new character.
3022  */
3023       if(gl_set_term_curpos(gl, term_curpos + width))
3024 	return 1;
3025       gl->buff_curpos++;
3026 /*
3027  * If we are replacing with a wider character, then we will be
3028  * inserting new characters, and thus extending the line.
3029  */
3030     } else if(width > old_width) {
3031 /*
3032  * Redraw the line from the cursor position to the end of the line,
3033  * and move the cursor to just after the added character.
3034  */
3035       if(gl_print_string(gl, gl->line + buff_curpos, '\0') ||
3036 	 gl_set_term_curpos(gl, term_curpos + width))
3037 	return 1;
3038       gl->buff_curpos++;
3039 /*
3040  * The original and replacement characters have the same width,
3041  * so simply overwrite.
3042  */
3043     } else {
3044 /*
3045  * Copy the character into the buffer.
3046  */
3047       gl_buffer_char(gl, c, buff_curpos);
3048       gl->buff_curpos++;
3049 /*
3050  * Overwrite the original character.
3051  */
3052       if(gl_print_char(gl, c, gl->line[gl->buff_curpos]))
3053 	return 1;
3054     };
3055   };
3056   return 0;
3057 }
3058 
3059 /*.......................................................................
3060  * Insert/append a string to the line buffer and terminal at the current
3061  * cursor position.
3062  *
3063  * Input:
3064  *  gl   GetLine *   The resource object of this library.
3065  *  s       char *   The string to be added.
3066  * Output:
3067  *  return   int     0 - OK.
3068  *                   1 - Insufficient room.
3069  */
3070 static int gl_add_string_to_line(GetLine *gl, const char *s)
3071 {
3072   int buff_slen;   /* The length of the string being added to line[] */
3073   int term_slen;   /* The length of the string being written to the terminal */
3074   int buff_curpos; /* The original value of gl->buff_curpos */
3075   int term_curpos; /* The original value of gl->term_curpos */
3076 /*
3077  * Keep a record of the current cursor position.
3078  */
3079   buff_curpos = gl->buff_curpos;
3080   term_curpos = gl->term_curpos;
3081 /*
3082  * How long is the string to be added?
3083  */
3084   buff_slen = strlen(s);
3085   term_slen = gl_displayed_string_width(gl, s, buff_slen, term_curpos);
3086 /*
3087  * Check that we can accomodate the string in the buffer.
3088  * If not, simply return, leaving it up to the calling program
3089  * to check for the absence of a newline character.
3090  */
3091   if(gl->ntotal + buff_slen > gl->linelen)
3092     return 0;
3093 /*
3094  * Move the characters that follow the cursor in the buffer by
3095  * buff_slen characters to the right.
3096  */
3097   if(gl->ntotal > gl->buff_curpos)
3098     gl_make_gap_in_buffer(gl, gl->buff_curpos, buff_slen);
3099 /*
3100  * Copy the string into the buffer.
3101  */
3102   gl_buffer_string(gl, s, buff_slen, gl->buff_curpos);
3103   gl->buff_curpos += buff_slen;
3104 /*
3105  * Write the modified part of the line to the terminal, then move
3106  * the terminal cursor to the end of the displayed input string.
3107  */
3108   if(gl_print_string(gl, gl->line + buff_curpos, '\0') ||
3109      gl_set_term_curpos(gl, term_curpos + term_slen))
3110     return 1;
3111   return 0;
3112 }
3113 
3114 /*.......................................................................
3115  * Read a single character from the terminal.
3116  *
3117  * Input:
3118  *  gl    GetLine *   The resource object of this library.
3119  *  keep      int     If true, the returned character will be kept in
3120  *                    the input buffer, for potential replays. It should
3121  *                    subsequently be removed from the buffer when the
3122  *                    key sequence that it belongs to has been fully
3123  *                    processed, by calling gl_discard_chars().
3124  * Input/Output:
3125  *  c        char *   The character that is read, is assigned to *c.
3126  * Output:
3127  *  return    int     0 - OK.
3128  *                    1 - Either an I/O error occurred, or a signal was
3129  *                        caught who's disposition is to abort gl_get_line()
3130  *                        or to have gl_get_line() return the current line
3131  *                        as though the user had pressed return. In the
3132  *                        latter case gl->endline will be non-zero.
3133  */
3134 static int gl_read_terminal(GetLine *gl, int keep, char *c)
3135 {
3136 /*
3137  * Before waiting for a new character to be input, flush unwritten
3138  * characters to the terminal.
3139  */
3140   if(gl_flush_output(gl))
3141     return 1;
3142 /*
3143  * Record the fact that we are about to read from the terminal.
3144  */
3145   gl->pending_io = GLP_READ;
3146 /*
3147  * If there is already an unread character in the buffer,
3148  * return it.
3149  */
3150   if(gl->nread < gl->nbuf) {
3151     *c = gl->keybuf[gl->nread];
3152 /*
3153  * Retain the character in the key buffer, but mark it as having been read?
3154  */
3155     if(keep) {
3156       gl->nread++;
3157 /*
3158  * Completely remove the character from the key buffer?
3159  */
3160     } else {
3161       memmove(gl->keybuf + gl->nread, gl->keybuf + gl->nread + 1,
3162 	      gl->nbuf - gl->nread - 1);
3163     };
3164     return 0;
3165   };
3166 /*
3167  * Make sure that there is space in the key buffer for one more character.
3168  * This should always be true if gl_interpret_char() is called for each
3169  * new character added, since it will clear the buffer once it has recognized
3170  * or rejected a key sequence.
3171  */
3172   if(gl->nbuf + 1 > GL_KEY_MAX) {
3173     gl_print_info(gl, "gl_read_terminal: Buffer overflow avoided.",
3174 		  GL_END_INFO);
3175     errno = EIO;
3176     return 1;
3177   };
3178 /*
3179  * Read one character from the terminal.
3180  */
3181   switch(gl_read_input(gl, c)) {
3182   case GL_READ_OK:
3183     break;
3184   case GL_READ_BLOCKED:
3185     gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO);
3186     return 1;
3187     break;
3188   default:
3189     return 1;
3190     break;
3191   };
3192 /*
3193  * Append the character to the key buffer?
3194  */
3195   if(keep) {
3196     gl->keybuf[gl->nbuf] = *c;
3197     gl->nread = ++gl->nbuf;
3198   };
3199   return 0;
3200 }
3201 
3202 /*.......................................................................
3203  * Read one or more keypresses from the terminal of an input stream.
3204  *
3205  * Input:
3206  *  gl           GetLine *  The resource object of this module.
3207  *  c               char *  The character that was read is assigned to *c.
3208  * Output:
3209  *  return  GlReadStatus    The completion status of the read operation.
3210  */
3211 static GlReadStatus gl_read_input(GetLine *gl, char *c)
3212 {
3213 /*
3214  * We may have to repeat the read if window change signals are received.
3215  */
3216   for(;;) {
3217 /*
3218  * Which file descriptor should we read from? Mark this volatile, so
3219  * that siglongjmp() can't clobber it.
3220  */
3221     volatile int fd = gl->file_fp ? fileno(gl->file_fp) : gl->input_fd;
3222 /*
3223  * If the endline flag becomes set, don't wait for another character.
3224  */
3225     if(gl->endline)
3226       return GL_READ_ERROR;
3227 /*
3228  * Since the code in this function can block, trap signals.
3229  */
3230     if(sigsetjmp(gl_setjmp_buffer, 1)==0) {
3231 /*
3232  * Handle the different I/O modes.
3233  */
3234       switch(gl->io_mode) {
3235 /*
3236  * In normal I/O mode, we call the event handler before attempting
3237  * to read, since read() blocks.
3238  */
3239       case GL_NORMAL_MODE:
3240 	if(gl_event_handler(gl, fd))
3241 	  return GL_READ_ERROR;
3242 	return gl_read_unmasked(gl, fd, c);  /* Read one character */
3243 	break;
3244 /*
3245  * In non-blocking server I/O mode, we attempt to read a character,
3246  * and only if this fails, call the event handler to wait for a any
3247  * user-configured timeout and any other user-configured events.  In
3248  * addition, we turn off the fcntl() non-blocking flag when reading
3249  * from the terminal, to work around a bug in Solaris. We can do this
3250  * without causing the read() to block, because when in non-blocking
3251  * server-I/O mode, gl_raw_io() sets the VMIN terminal attribute to 0,
3252  * which tells the terminal driver to return immediately if no
3253  * characters are available to be read.
3254  */
3255       case GL_SERVER_MODE:
3256 	{
3257 	  GlReadStatus status;        /* The return status */
3258 	  if(isatty(fd))              /* If we reading from a terminal, */
3259 	     gl_blocking_io(gl, fd);  /* switch to blocking I/O */
3260 	  status = gl_read_unmasked(gl, fd, c); /* Try reading */
3261 	  if(status == GL_READ_BLOCKED) {       /* Nothing readable yet */
3262 	    if(gl_event_handler(gl, fd))        /* Wait for input */
3263 	      status = GL_READ_ERROR;
3264 	    else
3265 	      status = gl_read_unmasked(gl, fd, c); /* Try reading again */
3266 	  };
3267 	  gl_nonblocking_io(gl, fd); /* Restore non-blocking I/O */
3268 	  return status;
3269 	};
3270 	break;
3271       };
3272     };
3273 /*
3274  * To get here, one of the signals that we are trapping must have
3275  * been received. Note that by using sigsetjmp() instead of setjmp()
3276  * the signal mask that was blocking these signals will have been
3277  * reinstated, so we can be sure that no more of these signals will
3278  * be received until we explicitly unblock them again.
3279  *
3280  * First, if non-blocking I/O was temporarily disabled, reinstate it.
3281  */
3282     if(gl->io_mode == GL_SERVER_MODE)
3283       gl_nonblocking_io(gl, fd);
3284 /*
3285  * Now respond to the signal that was caught.
3286  */
3287     if(gl_check_caught_signal(gl))
3288       return GL_READ_ERROR;
3289   };
3290 }
3291 
3292 /*.......................................................................
3293  * This is a private function of gl_read_input(), which unblocks signals
3294  * temporarily while it reads a single character from the specified file
3295  * descriptor.
3296  *
3297  * Input:
3298  *  gl          GetLine *  The resource object of this module.
3299  *  fd              int    The file descriptor to read from.
3300  *  c              char *  The character that was read is assigned to *c.
3301  * Output:
3302  *  return GlReadStatus    The completion status of the read.
3303  */
3304 static int gl_read_unmasked(GetLine *gl, int fd, char *c)
3305 {
3306   int nread;  /* The return value of read() */
3307 /*
3308  * Unblock the signals that we are trapping, while waiting for I/O.
3309  */
3310   gl_catch_signals(gl);
3311 /*
3312  * Attempt to read one character from the terminal, restarting the read
3313  * if any signals that we aren't trapping, are received.
3314  */
3315   do {
3316     errno = 0;
3317     nread = read(fd, c, 1);
3318   } while(nread < 0 && errno==EINTR);
3319 /*
3320  * Block all of the signals that we are trapping.
3321  */
3322   gl_mask_signals(gl, NULL);
3323 /*
3324  * Check the completion status of the read.
3325  */
3326   switch(nread) {
3327   case 1:
3328     return GL_READ_OK;
3329   case 0:
3330     return (isatty(fd) || errno != 0) ? GL_READ_BLOCKED : GL_READ_EOF;
3331   default:
3332     return GL_READ_ERROR;
3333   };
3334 }
3335 
3336 /*.......................................................................
3337  * Remove a specified number of characters from the start of the
3338  * key-press lookahead buffer, gl->keybuf[], and arrange for the next
3339  * read to start from the character at the start of the shifted buffer.
3340  *
3341  * Input:
3342  *  gl      GetLine *  The resource object of this module.
3343  *  nused       int    The number of characters to discard from the start
3344  *                     of the buffer.
3345  */
3346 static void gl_discard_chars(GetLine *gl, int nused)
3347 {
3348   int nkeep = gl->nbuf - nused;
3349   if(nkeep > 0) {
3350     memmove(gl->keybuf, gl->keybuf + nused, nkeep);
3351     gl->nbuf = nkeep;
3352     gl->nread = 0;
3353   } else {
3354     gl->nbuf = gl->nread = 0;
3355   };
3356 }
3357 
3358 /*.......................................................................
3359  * This function is called to handle signals caught between calls to
3360  * sigsetjmp() and siglongjmp().
3361  *
3362  * Input:
3363  *  gl      GetLine *   The resource object of this library.
3364  * Output:
3365  *  return      int     0 - Signal handled internally.
3366  *                      1 - Signal requires gl_get_line() to abort.
3367  */
3368 static int gl_check_caught_signal(GetLine *gl)
3369 {
3370   GlSignalNode *sig;      /* The signal disposition */
3371   SigAction keep_action;  /* The signal disposition of tecla signal handlers */
3372   unsigned flags;         /* The signal processing flags to use */
3373   int signo;              /* The signal to be handled */
3374 /*
3375  * Was no signal caught?
3376  */
3377   if(gl_pending_signal == -1)
3378     return 0;
3379 /*
3380  * Get the signal to be handled.
3381  */
3382   signo = gl_pending_signal;
3383 /*
3384  * Mark the signal as handled. Note that at this point, all of
3385  * the signals that we are trapping are blocked from delivery.
3386  */
3387   gl_pending_signal = -1;
3388 /*
3389  * Record the signal that was caught, so that the user can query it later.
3390  */
3391   gl->last_signal = signo;
3392 /*
3393  * In non-blocking server mode, the application is responsible for
3394  * responding to terminal signals, and we don't want gl_get_line()s
3395  * normal signal handling to clash with this, so whenever a signal
3396  * is caught, we arrange for gl_get_line() to abort and requeue the
3397  * signal while signals are still blocked. If the application
3398  * had the signal unblocked when gl_get_line() was called, the signal
3399  * will be delivered again as soon as gl_get_line() restores the
3400  * process signal mask, just before returning to the application.
3401  * Note that the caller of this function should set gl->pending_io
3402  * to the appropriate choice of GLP_READ and GLP_WRITE, before returning.
3403  */
3404   if(gl->io_mode==GL_SERVER_MODE) {
3405     gl_record_status(gl, GLR_SIGNAL, EINTR);
3406     raise(signo);
3407     return 1;
3408   };
3409 /*
3410  * Lookup the requested disposition of this signal.
3411  */
3412   for(sig=gl->sigs; sig && sig->signo != signo; sig=sig->next)
3413     ;
3414   if(!sig)
3415     return 0;
3416 /*
3417  * Get the signal response flags for this signal.
3418  */
3419   flags = sig->flags;
3420 /*
3421  * Did we receive a terminal size signal?
3422  */
3423 #ifdef SIGWINCH
3424   if(signo == SIGWINCH && _gl_update_size(gl))
3425     return 1;
3426 #endif
3427 /*
3428  * Start a fresh line?
3429  */
3430   if(flags & GLS_RESTORE_LINE) {
3431     if(gl_start_newline(gl, 0))
3432       return 1;
3433   };
3434 /*
3435  * Restore terminal settings to how they were before gl_get_line() was
3436  * called?
3437  */
3438   if(flags & GLS_RESTORE_TTY)
3439     gl_restore_terminal_attributes(gl);
3440 /*
3441  * Restore signal handlers to how they were before gl_get_line() was
3442  * called? If this hasn't been requested, only reinstate the signal
3443  * handler of the signal that we are handling.
3444  */
3445   if(flags & GLS_RESTORE_SIG) {
3446     gl_restore_signal_handlers(gl);
3447     gl_unmask_signals(gl, &gl->old_signal_set);
3448   } else {
3449     (void) sigaction(sig->signo, &sig->original, &keep_action);
3450     (void) sigprocmask(SIG_UNBLOCK, &sig->proc_mask, NULL);
3451   };
3452 /*
3453  * Forward the signal to the application's signal handler.
3454  */
3455   if(!(flags & GLS_DONT_FORWARD))
3456     raise(signo);
3457 /*
3458  * Reinstate our signal handlers.
3459  */
3460   if(flags & GLS_RESTORE_SIG) {
3461     gl_mask_signals(gl, NULL);
3462     gl_override_signal_handlers(gl);
3463   } else {
3464     (void) sigaction(sig->signo, &keep_action, NULL);
3465     (void) sigprocmask(SIG_BLOCK, &sig->proc_mask, NULL);
3466   };
3467 /*
3468  * Do we need to reinstate our terminal settings?
3469  */
3470   if(flags & GLS_RESTORE_TTY)
3471     gl_raw_terminal_mode(gl);
3472 /*
3473  * Redraw the line?
3474  */
3475   if(flags & GLS_REDRAW_LINE)
3476     gl_queue_redisplay(gl);
3477 /*
3478  * What next?
3479  */
3480   switch(sig->after) {
3481   case GLS_RETURN:
3482     gl_newline(gl, 1, NULL);
3483     return gl_flush_output(gl);
3484     break;
3485   case GLS_ABORT:
3486     gl_record_status(gl, GLR_SIGNAL, sig->errno_value);
3487     return 1;
3488     break;
3489   case GLS_CONTINUE:
3490     return gl_flush_output(gl);
3491     break;
3492   };
3493   return 0;
3494 }
3495 
3496 /*.......................................................................
3497  * Get pertinent terminal control strings and the initial terminal size.
3498  *
3499  * Input:
3500  *  gl     GetLine *  The resource object of this library.
3501  *  term      char *  The type of the terminal.
3502  * Output:
3503  *  return     int    0 - OK.
3504  *                    1 - Error.
3505  */
3506 static int gl_control_strings(GetLine *gl, const char *term)
3507 {
3508   int bad_term = 0;   /* True if term is unusable */
3509 /*
3510  * Discard any existing control strings from a previous terminal.
3511  */
3512   gl->left = NULL;
3513   gl->right = NULL;
3514   gl->up = NULL;
3515   gl->down = NULL;
3516   gl->home = NULL;
3517   gl->bol = 0;
3518   gl->clear_eol = NULL;
3519   gl->clear_eod = NULL;
3520   gl->u_arrow = NULL;
3521   gl->d_arrow = NULL;
3522   gl->l_arrow = NULL;
3523   gl->r_arrow = NULL;
3524   gl->sound_bell = NULL;
3525   gl->bold = NULL;
3526   gl->underline = NULL;
3527   gl->standout = NULL;
3528   gl->dim = NULL;
3529   gl->reverse = NULL;
3530   gl->blink = NULL;
3531   gl->text_attr_off = NULL;
3532   gl->nline = 0;
3533   gl->ncolumn = 0;
3534 #ifdef USE_TERMINFO
3535   gl->left_n = NULL;
3536   gl->right_n = NULL;
3537 #endif
3538 /*
3539  * If possible lookup the information in a terminal information
3540  * database.
3541  */
3542 #ifdef USE_TERMINFO
3543   {
3544     int errret;
3545     if(!term || setupterm((char *)term, gl->input_fd, &errret) == ERR) {
3546       bad_term = 1;
3547     } else {
3548       _clr_StringGroup(gl->capmem);
3549       gl->left = gl_tigetstr(gl, "cub1");
3550       gl->right = gl_tigetstr(gl, "cuf1");
3551       gl->up = gl_tigetstr(gl, "cuu1");
3552       gl->down = gl_tigetstr(gl, "cud1");
3553       gl->home = gl_tigetstr(gl, "home");
3554       gl->clear_eol = gl_tigetstr(gl, "el");
3555       gl->clear_eod = gl_tigetstr(gl, "ed");
3556       gl->u_arrow = gl_tigetstr(gl, "kcuu1");
3557       gl->d_arrow = gl_tigetstr(gl, "kcud1");
3558       gl->l_arrow = gl_tigetstr(gl, "kcub1");
3559       gl->r_arrow = gl_tigetstr(gl, "kcuf1");
3560       gl->left_n = gl_tigetstr(gl, "cub");
3561       gl->right_n = gl_tigetstr(gl, "cuf");
3562       gl->sound_bell = gl_tigetstr(gl, "bel");
3563       gl->bold = gl_tigetstr(gl, "bold");
3564       gl->underline = gl_tigetstr(gl, "smul");
3565       gl->standout = gl_tigetstr(gl, "smso");
3566       gl->dim = gl_tigetstr(gl, "dim");
3567       gl->reverse = gl_tigetstr(gl, "rev");
3568       gl->blink = gl_tigetstr(gl, "blink");
3569       gl->text_attr_off = gl_tigetstr(gl, "sgr0");
3570     };
3571   };
3572 #elif defined(USE_TERMCAP)
3573   if(!term || tgetent(gl->tgetent_buf, (char *)term) < 0) {
3574     bad_term = 1;
3575   } else {
3576     char *tgetstr_buf_ptr = gl->tgetstr_buf;
3577     _clr_StringGroup(gl->capmem);
3578     gl->left = gl_tgetstr(gl, "le", &tgetstr_buf_ptr);
3579     gl->right = gl_tgetstr(gl, "nd", &tgetstr_buf_ptr);
3580     gl->up = gl_tgetstr(gl, "up", &tgetstr_buf_ptr);
3581     gl->down = gl_tgetstr(gl, "do", &tgetstr_buf_ptr);
3582     gl->home = gl_tgetstr(gl, "ho", &tgetstr_buf_ptr);
3583     gl->clear_eol = gl_tgetstr(gl, "ce", &tgetstr_buf_ptr);
3584     gl->clear_eod = gl_tgetstr(gl, "cd", &tgetstr_buf_ptr);
3585     gl->u_arrow = gl_tgetstr(gl, "ku", &tgetstr_buf_ptr);
3586     gl->d_arrow = gl_tgetstr(gl, "kd", &tgetstr_buf_ptr);
3587     gl->l_arrow = gl_tgetstr(gl, "kl", &tgetstr_buf_ptr);
3588     gl->r_arrow = gl_tgetstr(gl, "kr", &tgetstr_buf_ptr);
3589     gl->sound_bell = gl_tgetstr(gl, "bl", &tgetstr_buf_ptr);
3590     gl->bold = gl_tgetstr(gl, "md", &tgetstr_buf_ptr);
3591     gl->underline = gl_tgetstr(gl, "us", &tgetstr_buf_ptr);
3592     gl->standout = gl_tgetstr(gl, "so", &tgetstr_buf_ptr);
3593     gl->dim = gl_tgetstr(gl, "mh", &tgetstr_buf_ptr);
3594     gl->reverse = gl_tgetstr(gl, "mr", &tgetstr_buf_ptr);
3595     gl->blink = gl_tgetstr(gl, "mb", &tgetstr_buf_ptr);
3596     gl->text_attr_off = gl_tgetstr(gl, "me", &tgetstr_buf_ptr);
3597   };
3598 #endif
3599 /*
3600  * Report term being unusable.
3601  */
3602   if(bad_term) {
3603     gl_print_info(gl, "Bad terminal type: \"", term ? term : "(null)",
3604 		  "\". Will assume vt100.", GL_END_INFO);
3605   };
3606 /*
3607  * Fill in missing information with ANSI VT100 strings.
3608  */
3609   if(!gl->left)
3610     gl->left = "\b";    /* ^H */
3611   if(!gl->right)
3612     gl->right = GL_ESC_STR "[C";
3613   if(!gl->up)
3614     gl->up = GL_ESC_STR "[A";
3615   if(!gl->down)
3616     gl->down = "\n";
3617   if(!gl->home)
3618     gl->home = GL_ESC_STR "[H";
3619   if(!gl->bol)
3620     gl->bol = "\r";
3621   if(!gl->clear_eol)
3622     gl->clear_eol = GL_ESC_STR "[K";
3623   if(!gl->clear_eod)
3624     gl->clear_eod = GL_ESC_STR "[J";
3625   if(!gl->u_arrow)
3626     gl->u_arrow = GL_ESC_STR "[A";
3627   if(!gl->d_arrow)
3628     gl->d_arrow = GL_ESC_STR "[B";
3629   if(!gl->l_arrow)
3630     gl->l_arrow = GL_ESC_STR "[D";
3631   if(!gl->r_arrow)
3632     gl->r_arrow = GL_ESC_STR "[C";
3633   if(!gl->sound_bell)
3634     gl->sound_bell = "\a";
3635   if(!gl->bold)
3636     gl->bold = GL_ESC_STR "[1m";
3637   if(!gl->underline)
3638     gl->underline = GL_ESC_STR "[4m";
3639   if(!gl->standout)
3640     gl->standout = GL_ESC_STR "[1;7m";
3641   if(!gl->dim)
3642     gl->dim = "";  /* Not available */
3643   if(!gl->reverse)
3644     gl->reverse = GL_ESC_STR "[7m";
3645   if(!gl->blink)
3646     gl->blink = GL_ESC_STR "[5m";
3647   if(!gl->text_attr_off)
3648     gl->text_attr_off = GL_ESC_STR "[m";
3649 /*
3650  * Find out the current terminal size.
3651  */
3652   (void) _gl_terminal_size(gl, GL_DEF_NCOLUMN, GL_DEF_NLINE, NULL);
3653   return 0;
3654 }
3655 
3656 #ifdef USE_TERMINFO
3657 /*.......................................................................
3658  * This is a private function of gl_control_strings() used to look up
3659  * a termninal capability string from the terminfo database and make
3660  * a private copy of it.
3661  *
3662  * Input:
3663  *  gl         GetLine *  The resource object of gl_get_line().
3664  *  name    const char *  The name of the terminfo string to look up.
3665  * Output:
3666  *  return  const char *  The local copy of the capability, or NULL
3667  *                        if not available.
3668  */
3669 static const char *gl_tigetstr(GetLine *gl, const char *name)
3670 {
3671   const char *value = tigetstr((char *)name);
3672   if(!value || value == (char *) -1)
3673     return NULL;
3674   return _sg_store_string(gl->capmem, value, 0);
3675 }
3676 #elif defined(USE_TERMCAP)
3677 /*.......................................................................
3678  * This is a private function of gl_control_strings() used to look up
3679  * a termninal capability string from the termcap database and make
3680  * a private copy of it. Note that some emulations of tgetstr(), such
3681  * as that used by Solaris, ignores the buffer pointer that is past to
3682  * it, so we can't assume that a private copy has been made that won't
3683  * be trashed by another call to gl_control_strings() by another
3684  * GetLine object. So we make what may be a redundant private copy
3685  * of the string in gl->capmem.
3686  *
3687  * Input:
3688  *  gl         GetLine *  The resource object of gl_get_line().
3689  *  name    const char *  The name of the terminfo string to look up.
3690  * Input/Output:
3691  *  bufptr        char ** On input *bufptr points to the location in
3692  *                        gl->tgetstr_buf at which to record the
3693  *                        capability string. On output *bufptr is
3694  *                        incremented over the stored string.
3695  * Output:
3696  *  return  const char *  The local copy of the capability, or NULL
3697  *                        on error.
3698  */
3699 static const char *gl_tgetstr(GetLine *gl, const char *name, char **bufptr)
3700 {
3701   const char *value = tgetstr((char *)name, bufptr);
3702   if(!value || value == (char *) -1)
3703     return NULL;
3704   return _sg_store_string(gl->capmem, value, 0);
3705 }
3706 #endif
3707 
3708 /*.......................................................................
3709  * This is an action function that implements a user interrupt (eg. ^C).
3710  */
3711 static KT_KEY_FN(gl_user_interrupt)
3712 {
3713   raise(SIGINT);
3714   return 1;
3715 }
3716 
3717 /*.......................................................................
3718  * This is an action function that implements the abort signal.
3719  */
3720 static KT_KEY_FN(gl_abort)
3721 {
3722   raise(SIGABRT);
3723   return 1;
3724 }
3725 
3726 /*.......................................................................
3727  * This is an action function that sends a suspend signal (eg. ^Z) to the
3728  * the parent process.
3729  */
3730 static KT_KEY_FN(gl_suspend)
3731 {
3732   raise(SIGTSTP);
3733   return 0;
3734 }
3735 
3736 /*.......................................................................
3737  * This is an action function that halts output to the terminal.
3738  */
3739 static KT_KEY_FN(gl_stop_output)
3740 {
3741   tcflow(gl->output_fd, TCOOFF);
3742   return 0;
3743 }
3744 
3745 /*.......................................................................
3746  * This is an action function that resumes halted terminal output.
3747  */
3748 static KT_KEY_FN(gl_start_output)
3749 {
3750   tcflow(gl->output_fd, TCOON);
3751   return 0;
3752 }
3753 
3754 /*.......................................................................
3755  * This is an action function that allows the next character to be accepted
3756  * without any interpretation as a special character.
3757  */
3758 static KT_KEY_FN(gl_literal_next)
3759 {
3760   char c;   /* The character to be added to the line */
3761   int i;
3762 /*
3763  * Get the character to be inserted literally.
3764  */
3765   if(gl_read_terminal(gl, 1, &c))
3766     return 1;
3767 /*
3768  * Add the character to the line 'count' times.
3769  */
3770   for(i=0; i<count; i++)
3771     gl_add_char_to_line(gl, c);
3772   return 0;
3773 }
3774 
3775 /*.......................................................................
3776  * Return the width of a tab character at a given position when
3777  * displayed at a given position on the terminal. This is needed
3778  * because the width of tab characters depends on where they are,
3779  * relative to the preceding tab stops.
3780  *
3781  * Input:
3782  *  gl       GetLine *  The resource object of this library.
3783  *  term_curpos  int    The destination terminal location of the character.
3784  * Output:
3785  *  return       int    The number of terminal charaters needed.
3786  */
3787 static int gl_displayed_tab_width(GetLine *gl, int term_curpos)
3788 {
3789   return TAB_WIDTH - ((term_curpos % gl->ncolumn) % TAB_WIDTH);
3790 }
3791 
3792 /*.......................................................................
3793  * Return the number of characters needed to display a given character
3794  * on the screen. Tab characters require eight spaces, and control
3795  * characters are represented by a caret followed by the modified
3796  * character.
3797  *
3798  * Input:
3799  *  gl       GetLine *  The resource object of this library.
3800  *  c           char    The character to be displayed.
3801  *  term_curpos  int    The destination terminal location of the character.
3802  *                      This is needed because the width of tab characters
3803  *                      depends on where they are, relative to the
3804  *                      preceding tab stops.
3805  * Output:
3806  *  return       int    The number of terminal charaters needed.
3807  */
3808 static int gl_displayed_char_width(GetLine *gl, char c, int term_curpos)
3809 {
3810   if(c=='\t')
3811     return gl_displayed_tab_width(gl, term_curpos);
3812   if(IS_CTRL_CHAR(c))
3813     return 2;
3814   if(!isprint((int)(unsigned char) c))
3815     return gl_octal_width((int)(unsigned char)c) + 1;
3816   return 1;
3817 }
3818 
3819 
3820 /*.......................................................................
3821  * Work out the length of given string of characters on the terminal.
3822  *
3823  * Input:
3824  *  gl       GetLine *  The resource object of this library.
3825  *  string      char *  The string to be measured.
3826  *  nc           int    The number of characters to be measured, or -1
3827  *                      to measure the whole string.
3828  *  term_curpos  int    The destination terminal location of the character.
3829  *                      This is needed because the width of tab characters
3830  *                      depends on where they are, relative to the
3831  *                      preceding tab stops.
3832  * Output:
3833  *  return       int    The number of displayed characters.
3834  */
3835 static int gl_displayed_string_width(GetLine *gl, const char *string, int nc,
3836 				     int term_curpos)
3837 {
3838   int slen = 0;   /* The displayed number of characters */
3839   int i;
3840 /*
3841  * How many characters are to be measured?
3842  */
3843   if(nc < 0)
3844     nc = strlen(string);
3845 /*
3846  * Add up the length of the displayed string.
3847  */
3848   for(i=0; i<nc; i++)
3849     slen += gl_displayed_char_width(gl, string[i], term_curpos + slen);
3850   return slen;
3851 }
3852 
3853 /*.......................................................................
3854  * Write a string verbatim to the current terminal or output stream.
3855  *
3856  * Note that when async-signal safety is required, the 'buffered'
3857  * argument must be 0, and n must not be -1.
3858  *
3859  * Input:
3860  *  gl         GetLine *  The resource object of the gl_get_line().
3861  *  buffered       int    If true, used buffered I/O when writing to
3862  *                        the terminal. Otherwise use async-signal-safe
3863  *                        unbuffered I/O.
3864  *  string  const char *  The string to be written (this need not be
3865  *                        '\0' terminated unless n<0).
3866  *  n              int    The number of characters to write from the
3867  *                        prefix of string[], or -1 to request that
3868  *                        gl_print_raw_string() use strlen() to figure
3869  *                        out the length.
3870  * Output:
3871  *  return         int    0 - OK.
3872  *                        1 - Error.
3873  */
3874 static int gl_print_raw_string(GetLine *gl, int buffered,
3875 			       const char *string, int n)
3876 {
3877   GlWriteFn *write_fn = buffered ? gl_write_fn : gl->flush_fn;
3878 /*
3879  * Only display output when echoing is turned on.
3880  */
3881   if(gl->echo) {
3882     int ndone = 0;   /* The number of characters written so far */
3883 /*
3884  * When using un-buffered I/O, flush pending output first.
3885  */
3886     if(!buffered) {
3887       if(gl_flush_output(gl))
3888 	return 1;
3889     };
3890 /*
3891  * If no length has been provided, measure the length of the string.
3892  */
3893     if(n < 0)
3894       n = strlen(string);
3895 /*
3896  * Write the string.
3897  */
3898     if(write_fn(gl, string + ndone, n-ndone) != n)
3899       return 1;
3900   };
3901   return 0;
3902 }
3903 
3904 /*.......................................................................
3905  * Output a terminal control sequence. When using terminfo,
3906  * this must be a sequence returned by tgetstr() or tigetstr()
3907  * respectively.
3908  *
3909  * Input:
3910  *  gl     GetLine *   The resource object of this library.
3911  *  nline      int     The number of lines affected by the operation,
3912  *                     or 1 if not relevant.
3913  *  string    char *   The control sequence to be sent.
3914  * Output:
3915  *  return     int     0 - OK.
3916  *                     1 - Error.
3917  */
3918 static int gl_print_control_sequence(GetLine *gl, int nline, const char *string)
3919 {
3920   int waserr = 0;   /* True if an error occurs */
3921 /*
3922  * Only write characters to the terminal when echoing is enabled.
3923  */
3924   if(gl->echo) {
3925 #if defined(USE_TERMINFO) || defined(USE_TERMCAP)
3926     tputs_gl = gl;
3927     errno = 0;
3928     tputs((char *)string, nline, gl_tputs_putchar);
3929     waserr = errno != 0;
3930 #else
3931     waserr = gl_print_raw_string(gl, 1, string, -1);
3932 #endif
3933   };
3934   return waserr;
3935 }
3936 
3937 #if defined(USE_TERMINFO) || defined(USE_TERMCAP)
3938 /*.......................................................................
3939  * The following callback function is called by tputs() to output a raw
3940  * control character to the terminal.
3941  */
3942 static TputsRetType gl_tputs_putchar(TputsArgType c)
3943 {
3944   char ch = c;
3945 #if TPUTS_RETURNS_VALUE
3946   return gl_print_raw_string(tputs_gl, 1, &ch, 1);
3947 #else
3948   (void) gl_print_raw_string(tputs_gl, 1, &ch, 1);
3949 #endif
3950 }
3951 #endif
3952 
3953 /*.......................................................................
3954  * Move the terminal cursor n characters to the left or right.
3955  *
3956  * Input:
3957  *  gl     GetLine *   The resource object of this program.
3958  *  n          int     number of positions to the right (> 0) or left (< 0).
3959  * Output:
3960  *  return     int     0 - OK.
3961  *                     1 - Error.
3962  */
3963 static int gl_terminal_move_cursor(GetLine *gl, int n)
3964 {
3965   int cur_row, cur_col; /* The current terminal row and column index of */
3966                         /*  the cursor wrt the start of the input line. */
3967   int new_row, new_col; /* The target terminal row and column index of */
3968                         /*  the cursor wrt the start of the input line. */
3969 /*
3970  * Do nothing if the input line isn't currently displayed. In this
3971  * case, the cursor will be moved to the right place when the line
3972  * is next redisplayed.
3973  */
3974   if(!gl->displayed)
3975     return 0;
3976 /*
3977  * How far can we move left?
3978  */
3979   if(gl->term_curpos + n < 0)
3980     n = gl->term_curpos;
3981 /*
3982  * Break down the current and target cursor locations into rows and columns.
3983  */
3984   cur_row = gl->term_curpos / gl->ncolumn;
3985   cur_col = gl->term_curpos % gl->ncolumn;
3986   new_row = (gl->term_curpos + n) / gl->ncolumn;
3987   new_col = (gl->term_curpos + n) % gl->ncolumn;
3988 /*
3989  * Move down to the next line.
3990  */
3991   for(; cur_row < new_row; cur_row++) {
3992     if(gl_print_control_sequence(gl, 1, gl->down))
3993       return 1;
3994   };
3995 /*
3996  * Move up to the previous line.
3997  */
3998   for(; cur_row > new_row; cur_row--) {
3999     if(gl_print_control_sequence(gl, 1, gl->up))
4000       return 1;
4001   };
4002 /*
4003  * Move to the right within the target line?
4004  */
4005   if(cur_col < new_col) {
4006 #ifdef USE_TERMINFO
4007 /*
4008  * Use a parameterized control sequence if it generates less control
4009  * characters (guess based on ANSI terminal termcap entry).
4010  */
4011     if(gl->right_n != NULL && new_col - cur_col > 1) {
4012       if(gl_print_control_sequence(gl, 1, tparm((char *)gl->right_n,
4013            (long)(new_col - cur_col), 0l, 0l, 0l, 0l, 0l, 0l, 0l, 0l)))
4014 	return 1;
4015     } else
4016 #endif
4017     {
4018       for(; cur_col < new_col; cur_col++) {
4019         if(gl_print_control_sequence(gl, 1, gl->right))
4020           return 1;
4021       };
4022     };
4023 /*
4024  * Move to the left within the target line?
4025  */
4026   } else if(cur_col > new_col) {
4027 #ifdef USE_TERMINFO
4028 /*
4029  * Use a parameterized control sequence if it generates less control
4030  * characters (guess based on ANSI terminal termcap entry).
4031  */
4032     if(gl->left_n != NULL && cur_col - new_col > 3) {
4033       if(gl_print_control_sequence(gl, 1, tparm((char *)gl->left_n,
4034            (long)(cur_col - new_col), 0l, 0l, 0l, 0l, 0l, 0l, 0l, 0l)))
4035 	return 1;
4036     } else
4037 #endif
4038     {
4039       for(; cur_col > new_col; cur_col--) {
4040         if(gl_print_control_sequence(gl, 1, gl->left))
4041           return 1;
4042       };
4043     };
4044   }
4045 /*
4046  * Update the recorded position of the terminal cursor.
4047  */
4048   gl->term_curpos += n;
4049   return 0;
4050 }
4051 
4052 /*.......................................................................
4053  * Write a character to the terminal after expanding tabs and control
4054  * characters to their multi-character representations.
4055  *
4056  * Input:
4057  *  gl    GetLine *   The resource object of this program.
4058  *  c        char     The character to be output.
4059  *  pad      char     Many terminals have the irritating feature that
4060  *                    when one writes a character in the last column of
4061  *                    of the terminal, the cursor isn't wrapped to the
4062  *                    start of the next line until one more character
4063  *                    is written. Some terminals don't do this, so
4064  *                    after such a write, we don't know where the
4065  *                    terminal is unless we output an extra character.
4066  *                    This argument specifies the character to write.
4067  *                    If at the end of the input line send '\0' or a
4068  *                    space, and a space will be written. Otherwise,
4069  *                    pass the next character in the input line
4070  *                    following the one being written.
4071  * Output:
4072  *  return    int     0 - OK.
4073  */
4074 static int gl_print_char(GetLine *gl, char c, char pad)
4075 {
4076   char string[TAB_WIDTH + 4]; /* A work area for composing compound strings */
4077   int nchar;                  /* The number of terminal characters */
4078   int i;
4079 /*
4080  * Check for special characters.
4081  */
4082   if(c == '\t') {
4083 /*
4084  * How many spaces do we need to represent a tab at the current terminal
4085  * column?
4086  */
4087     nchar = gl_displayed_tab_width(gl, gl->term_curpos);
4088 /*
4089  * Compose the tab string.
4090  */
4091     for(i=0; i<nchar; i++)
4092       string[i] = ' ';
4093   } else if(IS_CTRL_CHAR(c)) {
4094     string[0] = '^';
4095     string[1] = CTRL_TO_CHAR(c);
4096     nchar = 2;
4097   } else if(!isprint((int)(unsigned char) c)) {
4098     snprintf(string, sizeof(string), "\\%o", (int)(unsigned char)c);
4099     nchar = strlen(string);
4100   } else {
4101     string[0] = c;
4102     nchar = 1;
4103   };
4104 /*
4105  * Terminate the string.
4106  */
4107   string[nchar] = '\0';
4108 /*
4109  * Write the string to the terminal.
4110  */
4111   if(gl_print_raw_string(gl, 1, string, -1))
4112     return 1;
4113 /*
4114  * Except for one exception to be described in a moment, the cursor should
4115  * now have been positioned after the character that was just output.
4116  */
4117   gl->term_curpos += nchar;
4118 /*
4119  * Keep a record of the number of characters in the terminal version
4120  * of the input line.
4121  */
4122   if(gl->term_curpos > gl->term_len)
4123     gl->term_len = gl->term_curpos;
4124 /*
4125  * If the new character ended exactly at the end of a line,
4126  * most terminals won't move the cursor onto the next line until we
4127  * have written a character on the next line, so append an extra
4128  * space then move the cursor back.
4129  */
4130   if(gl->term_curpos % gl->ncolumn == 0) {
4131     int term_curpos = gl->term_curpos;
4132     if(gl_print_char(gl, pad ? pad : ' ', ' ') ||
4133        gl_set_term_curpos(gl, term_curpos))
4134       return 1;
4135   };
4136   return 0;
4137 }
4138 
4139 /*.......................................................................
4140  * Write a string to the terminal after expanding tabs and control
4141  * characters to their multi-character representations.
4142  *
4143  * Input:
4144  *  gl    GetLine *   The resource object of this program.
4145  *  string   char *   The string to be output.
4146  *  pad      char     Many terminals have the irritating feature that
4147  *                    when one writes a character in the last column of
4148  *                    of the terminal, the cursor isn't wrapped to the
4149  *                    start of the next line until one more character
4150  *                    is written. Some terminals don't do this, so
4151  *                    after such a write, we don't know where the
4152  *                    terminal is unless we output an extra character.
4153  *                    This argument specifies the character to write.
4154  *                    If at the end of the input line send '\0' or a
4155  *                    space, and a space will be written. Otherwise,
4156  *                    pass the next character in the input line
4157  *                    following the one being written.
4158  * Output:
4159  *  return    int     0 - OK.
4160  */
4161 static int gl_print_string(GetLine *gl, const char *string, char pad)
4162 {
4163   const char *cptr;   /* A pointer into string[] */
4164   for(cptr=string; *cptr; cptr++) {
4165     char nextc = cptr[1];
4166     if(gl_print_char(gl, *cptr, nextc ? nextc : pad))
4167       return 1;
4168   };
4169   return 0;
4170 }
4171 
4172 /*.......................................................................
4173  * Move the terminal cursor position.
4174  *
4175  * Input:
4176  *  gl      GetLine *  The resource object of this library.
4177  *  term_curpos int    The destination terminal cursor position.
4178  * Output:
4179  *  return      int    0 - OK.
4180  *                     1 - Error.
4181  */
4182 static int gl_set_term_curpos(GetLine *gl, int term_curpos)
4183 {
4184   return gl_terminal_move_cursor(gl, term_curpos - gl->term_curpos);
4185 }
4186 
4187 /*.......................................................................
4188  * This is an action function that moves the buffer cursor one character
4189  * left, and updates the terminal cursor to match.
4190  */
4191 static KT_KEY_FN(gl_cursor_left)
4192 {
4193   return gl_place_cursor(gl, gl->buff_curpos - count);
4194 }
4195 
4196 /*.......................................................................
4197  * This is an action function that moves the buffer cursor one character
4198  * right, and updates the terminal cursor to match.
4199  */
4200 static KT_KEY_FN(gl_cursor_right)
4201 {
4202   return gl_place_cursor(gl, gl->buff_curpos + count);
4203 }
4204 
4205 /*.......................................................................
4206  * This is an action function that toggles between overwrite and insert
4207  * mode.
4208  */
4209 static KT_KEY_FN(gl_insert_mode)
4210 {
4211   gl->insert = !gl->insert;
4212   return 0;
4213 }
4214 
4215 /*.......................................................................
4216  * This is an action function which moves the cursor to the beginning of
4217  * the line.
4218  */
4219 static KT_KEY_FN(gl_beginning_of_line)
4220 {
4221   return gl_place_cursor(gl, 0);
4222 }
4223 
4224 /*.......................................................................
4225  * This is an action function which moves the cursor to the end of
4226  * the line.
4227  */
4228 static KT_KEY_FN(gl_end_of_line)
4229 {
4230   return gl_place_cursor(gl, gl->ntotal);
4231 }
4232 
4233 /*.......................................................................
4234  * This is an action function which deletes the entire contents of the
4235  * current line.
4236  */
4237 static KT_KEY_FN(gl_delete_line)
4238 {
4239 /*
4240  * If in vi command mode, preserve the current line for potential
4241  * use by vi-undo.
4242  */
4243   gl_save_for_undo(gl);
4244 /*
4245  * Copy the contents of the line to the cut buffer.
4246  */
4247   strlcpy(gl->cutbuf, gl->line, gl->linelen);
4248 /*
4249  * Clear the buffer.
4250  */
4251   gl_truncate_buffer(gl, 0);
4252 /*
4253  * Move the terminal cursor to just after the prompt.
4254  */
4255   if(gl_place_cursor(gl, 0))
4256     return 1;
4257 /*
4258  * Clear from the end of the prompt to the end of the terminal.
4259  */
4260   if(gl_truncate_display(gl))
4261     return 1;
4262   return 0;
4263 }
4264 
4265 /*.......................................................................
4266  * This is an action function which deletes all characters between the
4267  * current cursor position and the end of the line.
4268  */
4269 static KT_KEY_FN(gl_kill_line)
4270 {
4271 /*
4272  * If in vi command mode, preserve the current line for potential
4273  * use by vi-undo.
4274  */
4275   gl_save_for_undo(gl);
4276 /*
4277  * Copy the part of the line that is about to be deleted to the cut buffer.
4278  */
4279   strlcpy(gl->cutbuf, gl->line + gl->buff_curpos, gl->linelen);
4280 /*
4281  * Terminate the buffered line at the current cursor position.
4282  */
4283   gl_truncate_buffer(gl, gl->buff_curpos);
4284 /*
4285  * Clear the part of the line that follows the cursor.
4286  */
4287   if(gl_truncate_display(gl))
4288     return 1;
4289 /*
4290  * Explicitly reset the cursor position to allow vi command mode
4291  * constraints on its position to be set.
4292  */
4293   return gl_place_cursor(gl, gl->buff_curpos);
4294 }
4295 
4296 /*.......................................................................
4297  * This is an action function which deletes all characters between the
4298  * start of the line and the current cursor position.
4299  */
4300 static KT_KEY_FN(gl_backward_kill_line)
4301 {
4302 /*
4303  * How many characters are to be deleted from before the cursor?
4304  */
4305   int nc = gl->buff_curpos - gl->insert_curpos;
4306   if (!nc)
4307     return 0;
4308 /*
4309  * Move the cursor to the start of the line, or in vi input mode,
4310  * the start of the sub-line at which insertion started, and delete
4311  * up to the old cursor position.
4312  */
4313   return gl_place_cursor(gl, gl->insert_curpos) ||
4314          gl_delete_chars(gl, nc, gl->editor == GL_EMACS_MODE || gl->vi.command);
4315 }
4316 
4317 /*.......................................................................
4318  * This is an action function which moves the cursor forward by a word.
4319  */
4320 static KT_KEY_FN(gl_forward_word)
4321 {
4322   return gl_place_cursor(gl, gl_nth_word_end_forward(gl, count) +
4323 			 (gl->editor==GL_EMACS_MODE));
4324 }
4325 
4326 /*.......................................................................
4327  * This is an action function which moves the cursor forward to the start
4328  * of the next word.
4329  */
4330 static KT_KEY_FN(gl_forward_to_word)
4331 {
4332   return gl_place_cursor(gl, gl_nth_word_start_forward(gl, count));
4333 }
4334 
4335 /*.......................................................................
4336  * This is an action function which moves the cursor backward by a word.
4337  */
4338 static KT_KEY_FN(gl_backward_word)
4339 {
4340   return gl_place_cursor(gl, gl_nth_word_start_backward(gl, count));
4341 }
4342 
4343 /*.......................................................................
4344  * Delete one or more characters, starting with the one under the cursor.
4345  *
4346  * Input:
4347  *  gl     GetLine *  The resource object of this library.
4348  *  nc         int    The number of characters to delete.
4349  *  cut        int    If true, copy the characters to the cut buffer.
4350  * Output:
4351  *  return     int    0 - OK.
4352  *                    1 - Error.
4353  */
4354 static int gl_delete_chars(GetLine *gl, int nc, int cut)
4355 {
4356 /*
4357  * If in vi command mode, preserve the current line for potential
4358  * use by vi-undo.
4359  */
4360   gl_save_for_undo(gl);
4361 /*
4362  * If there are fewer than nc characters following the cursor, limit
4363  * nc to the number available.
4364  */
4365   if(gl->buff_curpos + nc > gl->ntotal)
4366     nc = gl->ntotal - gl->buff_curpos;
4367 /*
4368  * Copy the about to be deleted region to the cut buffer.
4369  */
4370   if(cut) {
4371     memcpy(gl->cutbuf, gl->line + gl->buff_curpos, nc);
4372     gl->cutbuf[nc] = '\0';
4373   }
4374 /*
4375  * Nothing to delete?
4376  */
4377   if(nc <= 0)
4378     return 0;
4379 /*
4380  * In vi overwrite mode, restore any previously overwritten characters
4381  * from the undo buffer.
4382  */
4383   if(gl->editor == GL_VI_MODE && !gl->vi.command && !gl->insert) {
4384 /*
4385  * How many of the characters being deleted can be restored from the
4386  * undo buffer?
4387  */
4388     int nrestore = gl->buff_curpos + nc <= gl->vi.undo.ntotal ?
4389       nc : gl->vi.undo.ntotal - gl->buff_curpos;
4390 /*
4391  * Restore any available characters.
4392  */
4393     if(nrestore > 0) {
4394       gl_buffer_string(gl, gl->vi.undo.line + gl->buff_curpos, nrestore,
4395 		       gl->buff_curpos);
4396     };
4397 /*
4398  * If their were insufficient characters in the undo buffer, then this
4399  * implies that we are deleting from the end of the line, so we need
4400  * to terminate the line either where the undo buffer ran out, or if
4401  * we are deleting from beyond the end of the undo buffer, at the current
4402  * cursor position.
4403  */
4404     if(nc != nrestore) {
4405       gl_truncate_buffer(gl, (gl->vi.undo.ntotal > gl->buff_curpos) ?
4406 			 gl->vi.undo.ntotal : gl->buff_curpos);
4407     };
4408   } else {
4409 /*
4410  * Copy the remaining part of the line back over the deleted characters.
4411  */
4412     gl_remove_from_buffer(gl, gl->buff_curpos, nc);
4413   };
4414 /*
4415  * Redraw the remaining characters following the cursor.
4416  */
4417   if(gl_print_string(gl, gl->line + gl->buff_curpos, '\0'))
4418     return 1;
4419 /*
4420  * Clear to the end of the terminal.
4421  */
4422   if(gl_truncate_display(gl))
4423     return 1;
4424 /*
4425  * Place the cursor at the start of where the deletion was performed.
4426  */
4427   return gl_place_cursor(gl, gl->buff_curpos);
4428 }
4429 
4430 /*.......................................................................
4431  * This is an action function which deletes character(s) under the
4432  * cursor without moving the cursor.
4433  */
4434 static KT_KEY_FN(gl_forward_delete_char)
4435 {
4436 /*
4437  * Delete 'count' characters.
4438  */
4439   return gl_delete_chars(gl, count, gl->vi.command);
4440 }
4441 
4442 /*.......................................................................
4443  * This is an action function which deletes character(s) under the
4444  * cursor and moves the cursor back one character.
4445  */
4446 static KT_KEY_FN(gl_backward_delete_char)
4447 {
4448 /*
4449  * Restrict the deletion count to the number of characters that
4450  * precede the insertion point.
4451  */
4452   if(count > gl->buff_curpos - gl->insert_curpos)
4453     count = gl->buff_curpos - gl->insert_curpos;
4454 /*
4455  * If in vi command mode, preserve the current line for potential
4456  * use by vi-undo.
4457  */
4458   gl_save_for_undo(gl);
4459   return gl_cursor_left(gl, count, NULL) ||
4460     gl_delete_chars(gl, count, gl->vi.command);
4461 }
4462 
4463 /*.......................................................................
4464  * Starting from the cursor position delete to the specified column.
4465  */
4466 static KT_KEY_FN(gl_delete_to_column)
4467 {
4468   if (--count >= gl->buff_curpos)
4469     return gl_forward_delete_char(gl, count - gl->buff_curpos, NULL);
4470   else
4471     return gl_backward_delete_char(gl, gl->buff_curpos - count, NULL);
4472 }
4473 
4474 /*.......................................................................
4475  * Starting from the cursor position delete characters to a matching
4476  * parenthesis.
4477  */
4478 static KT_KEY_FN(gl_delete_to_parenthesis)
4479 {
4480   int curpos = gl_index_of_matching_paren(gl);
4481   if(curpos >= 0) {
4482     gl_save_for_undo(gl);
4483     if(curpos >= gl->buff_curpos)
4484       return gl_forward_delete_char(gl, curpos - gl->buff_curpos + 1, NULL);
4485     else
4486       return gl_backward_delete_char(gl, ++gl->buff_curpos - curpos + 1, NULL);
4487   };
4488   return 0;
4489 }
4490 
4491 /*.......................................................................
4492  * This is an action function which deletes from the cursor to the end
4493  * of the word that the cursor is either in or precedes.
4494  */
4495 static KT_KEY_FN(gl_forward_delete_word)
4496 {
4497 /*
4498  * If in vi command mode, preserve the current line for potential
4499  * use by vi-undo.
4500  */
4501   gl_save_for_undo(gl);
4502 /*
4503  * In emacs mode delete to the end of the word. In vi mode delete to the
4504  * start of the net word.
4505  */
4506   if(gl->editor == GL_EMACS_MODE) {
4507     return gl_delete_chars(gl,
4508 		gl_nth_word_end_forward(gl,count) - gl->buff_curpos + 1, 1);
4509   } else {
4510     return gl_delete_chars(gl,
4511 		gl_nth_word_start_forward(gl,count) - gl->buff_curpos,
4512 		gl->vi.command);
4513   };
4514 }
4515 
4516 /*.......................................................................
4517  * This is an action function which deletes the word that precedes the
4518  * cursor.
4519  */
4520 static KT_KEY_FN(gl_backward_delete_word)
4521 {
4522 /*
4523  * Keep a record of the current cursor position.
4524  */
4525   int buff_curpos = gl->buff_curpos;
4526 /*
4527  * If in vi command mode, preserve the current line for potential
4528  * use by vi-undo.
4529  */
4530   gl_save_for_undo(gl);
4531 /*
4532  * Move back 'count' words.
4533  */
4534   if(gl_backward_word(gl, count, NULL))
4535     return 1;
4536 /*
4537  * Delete from the new cursor position to the original one.
4538  */
4539   return gl_delete_chars(gl, buff_curpos - gl->buff_curpos,
4540   			 gl->editor == GL_EMACS_MODE || gl->vi.command);
4541 }
4542 
4543 /*.......................................................................
4544  * Searching in a given direction, delete to the count'th
4545  * instance of a specified or queried character, in the input line.
4546  *
4547  * Input:
4548  *  gl       GetLine *  The getline resource object.
4549  *  count        int    The number of times to search.
4550  *  c           char    The character to be searched for, or '\0' if
4551  *                      the character should be read from the user.
4552  *  forward      int    True if searching forward.
4553  *  onto         int    True if the search should end on top of the
4554  *                      character, false if the search should stop
4555  *                      one character before the character in the
4556  *                      specified search direction.
4557  *  change       int    If true, this function is being called upon
4558  *                      to do a vi change command, in which case the
4559  *                      user will be left in insert mode after the
4560  *                      deletion.
4561  * Output:
4562  *  return       int    0 - OK.
4563  *                      1 - Error.
4564  */
4565 static int gl_delete_find(GetLine *gl, int count, char c, int forward,
4566 			  int onto, int change)
4567 {
4568 /*
4569  * Search for the character, and abort the deletion if not found.
4570  */
4571   int pos = gl_find_char(gl, count, forward, onto, c);
4572   if(pos < 0)
4573     return 0;
4574 /*
4575  * If in vi command mode, preserve the current line for potential
4576  * use by vi-undo.
4577  */
4578   gl_save_for_undo(gl);
4579 /*
4580  * Allow the cursor to be at the end of the line if this is a change
4581  * command.
4582  */
4583   if(change)
4584     gl->vi.command = 0;
4585 /*
4586  * Delete the appropriate span of characters.
4587  */
4588   if(forward) {
4589     if(gl_delete_chars(gl, pos - gl->buff_curpos + 1, 1))
4590       return 1;
4591   } else {
4592     int buff_curpos = gl->buff_curpos;
4593     if(gl_place_cursor(gl, pos) ||
4594        gl_delete_chars(gl, buff_curpos - gl->buff_curpos, 1))
4595       return 1;
4596   };
4597 /*
4598  * If this is a change operation, switch the insert mode.
4599  */
4600   if(change && gl_vi_insert(gl, 0, NULL))
4601     return 1;
4602   return 0;
4603 }
4604 
4605 /*.......................................................................
4606  * This is an action function which deletes forward from the cursor up to and
4607  * including a specified character.
4608  */
4609 static KT_KEY_FN(gl_forward_delete_find)
4610 {
4611   return gl_delete_find(gl, count, '\0', 1, 1, 0);
4612 }
4613 
4614 /*.......................................................................
4615  * This is an action function which deletes backward from the cursor back to
4616  * and including a specified character.
4617  */
4618 static KT_KEY_FN(gl_backward_delete_find)
4619 {
4620   return gl_delete_find(gl, count, '\0', 0, 1, 0);
4621 }
4622 
4623 /*.......................................................................
4624  * This is an action function which deletes forward from the cursor up to but
4625  * not including a specified character.
4626  */
4627 static KT_KEY_FN(gl_forward_delete_to)
4628 {
4629   return gl_delete_find(gl, count, '\0', 1, 0, 0);
4630 }
4631 
4632 /*.......................................................................
4633  * This is an action function which deletes backward from the cursor back to
4634  * but not including a specified character.
4635  */
4636 static KT_KEY_FN(gl_backward_delete_to)
4637 {
4638   return gl_delete_find(gl, count, '\0', 0, 0, 0);
4639 }
4640 
4641 /*.......................................................................
4642  * This is an action function which deletes to a character specified by a
4643  * previous search.
4644  */
4645 static KT_KEY_FN(gl_delete_refind)
4646 {
4647   return gl_delete_find(gl, count, gl->vi.find_char, gl->vi.find_forward,
4648 			gl->vi.find_onto, 0);
4649 }
4650 
4651 /*.......................................................................
4652  * This is an action function which deletes to a character specified by a
4653  * previous search, but in the opposite direction.
4654  */
4655 static KT_KEY_FN(gl_delete_invert_refind)
4656 {
4657   return gl_delete_find(gl, count, gl->vi.find_char,
4658 			!gl->vi.find_forward, gl->vi.find_onto, 0);
4659 }
4660 
4661 /*.......................................................................
4662  * This is an action function which converts the characters in the word
4663  * following the cursor to upper case.
4664  */
4665 static KT_KEY_FN(gl_upcase_word)
4666 {
4667 /*
4668  * Locate the count'th word ending after the cursor.
4669  */
4670   int last = gl_nth_word_end_forward(gl, count);
4671 /*
4672  * If in vi command mode, preserve the current line for potential
4673  * use by vi-undo.
4674  */
4675   gl_save_for_undo(gl);
4676 /*
4677  * Upcase characters from the current cursor position to 'last'.
4678  */
4679   while(gl->buff_curpos <= last) {
4680     char *cptr = gl->line + gl->buff_curpos;
4681 /*
4682  * Convert the character to upper case?
4683  */
4684     if(islower((int)(unsigned char) *cptr))
4685       gl_buffer_char(gl, toupper((int) *cptr), gl->buff_curpos);
4686     gl->buff_curpos++;
4687 /*
4688  * Write the possibly modified character back. Note that for non-modified
4689  * characters we want to do this as well, so as to advance the cursor.
4690  */
4691     if(gl_print_char(gl, *cptr, cptr[1]))
4692       return 1;
4693   };
4694   return gl_place_cursor(gl, gl->buff_curpos);	/* bounds check */
4695 }
4696 
4697 /*.......................................................................
4698  * This is an action function which converts the characters in the word
4699  * following the cursor to lower case.
4700  */
4701 static KT_KEY_FN(gl_downcase_word)
4702 {
4703 /*
4704  * Locate the count'th word ending after the cursor.
4705  */
4706   int last = gl_nth_word_end_forward(gl, count);
4707 /*
4708  * If in vi command mode, preserve the current line for potential
4709  * use by vi-undo.
4710  */
4711   gl_save_for_undo(gl);
4712 /*
4713  * Upcase characters from the current cursor position to 'last'.
4714  */
4715   while(gl->buff_curpos <= last) {
4716     char *cptr = gl->line + gl->buff_curpos;
4717 /*
4718  * Convert the character to upper case?
4719  */
4720     if(isupper((int)(unsigned char) *cptr))
4721       gl_buffer_char(gl, tolower((int) *cptr), gl->buff_curpos);
4722     gl->buff_curpos++;
4723 /*
4724  * Write the possibly modified character back. Note that for non-modified
4725  * characters we want to do this as well, so as to advance the cursor.
4726  */
4727     if(gl_print_char(gl, *cptr, cptr[1]))
4728       return 1;
4729   };
4730   return gl_place_cursor(gl, gl->buff_curpos);	/* bounds check */
4731 }
4732 
4733 /*.......................................................................
4734  * This is an action function which converts the first character of the
4735  * following word to upper case, in order to capitalize the word, and
4736  * leaves the cursor at the end of the word.
4737  */
4738 static KT_KEY_FN(gl_capitalize_word)
4739 {
4740   char *cptr;   /* &gl->line[gl->buff_curpos] */
4741   int first;    /* True for the first letter of the word */
4742   int i;
4743 /*
4744  * Keep a record of the current insert mode and the cursor position.
4745  */
4746   int insert = gl->insert;
4747 /*
4748  * If in vi command mode, preserve the current line for potential
4749  * use by vi-undo.
4750  */
4751   gl_save_for_undo(gl);
4752 /*
4753  * We want to overwrite the modified word.
4754  */
4755   gl->insert = 0;
4756 /*
4757  * Capitalize 'count' words.
4758  */
4759   for(i=0; i<count && gl->buff_curpos < gl->ntotal; i++) {
4760     int pos = gl->buff_curpos;
4761 /*
4762  * If we are not already within a word, skip to the start of the word.
4763  */
4764     for(cptr = gl->line + pos ; pos<gl->ntotal && !gl_is_word_char((int) *cptr);
4765 	pos++, cptr++)
4766       ;
4767 /*
4768  * Move the cursor to the new position.
4769  */
4770     if(gl_place_cursor(gl, pos))
4771       return 1;
4772 /*
4773  * While searching for the end of the word, change lower case letters
4774  * to upper case.
4775  */
4776     for(first=1; gl->buff_curpos<gl->ntotal && gl_is_word_char((int) *cptr);
4777 	gl->buff_curpos++, cptr++) {
4778 /*
4779  * Convert the character to upper case?
4780  */
4781       if(first) {
4782 	if(islower((int)(unsigned char) *cptr))
4783 	  gl_buffer_char(gl, toupper((int) *cptr), cptr - gl->line);
4784       } else {
4785 	if(isupper((int)(unsigned char) *cptr))
4786 	  gl_buffer_char(gl, tolower((int) *cptr), cptr - gl->line);
4787       };
4788       first = 0;
4789 /*
4790  * Write the possibly modified character back. Note that for non-modified
4791  * characters we want to do this as well, so as to advance the cursor.
4792  */
4793       if(gl_print_char(gl, *cptr, cptr[1]))
4794 	return 1;
4795     };
4796   };
4797 /*
4798  * Restore the insertion mode.
4799  */
4800   gl->insert = insert;
4801   return gl_place_cursor(gl, gl->buff_curpos);	/* bounds check */
4802 }
4803 
4804 /*.......................................................................
4805  * This is an action function which redraws the current line.
4806  */
4807 static KT_KEY_FN(gl_redisplay)
4808 {
4809 /*
4810  * Keep a record of the current cursor position.
4811  */
4812   int buff_curpos = gl->buff_curpos;
4813 /*
4814  * Do nothing if there is no line to be redisplayed.
4815  */
4816   if(gl->endline)
4817     return 0;
4818 /*
4819  * Erase the current input line.
4820  */
4821   if(gl_erase_line(gl))
4822     return 1;
4823 /*
4824  * Display the current prompt.
4825  */
4826   if(gl_display_prompt(gl))
4827     return 1;
4828 /*
4829  * Render the part of the line that the user has typed in so far.
4830  */
4831   if(gl_print_string(gl, gl->line, '\0'))
4832     return 1;
4833 /*
4834  * Restore the cursor position.
4835  */
4836   if(gl_place_cursor(gl, buff_curpos))
4837     return 1;
4838 /*
4839  * Mark the redisplay operation as having been completed.
4840  */
4841   gl->redisplay = 0;
4842 /*
4843  * Flush the redisplayed line to the terminal.
4844  */
4845   return gl_flush_output(gl);
4846 }
4847 
4848 /*.......................................................................
4849  * This is an action function which clears the display and redraws the
4850  * input line from the home position.
4851  */
4852 static KT_KEY_FN(gl_clear_screen)
4853 {
4854 /*
4855  * Home the cursor and clear from there to the end of the display.
4856  */
4857   if(gl_print_control_sequence(gl, gl->nline, gl->home) ||
4858      gl_print_control_sequence(gl, gl->nline, gl->clear_eod))
4859     return 1;
4860 /*
4861  * The input line is no longer displayed.
4862  */
4863   gl_line_erased(gl);
4864 /*
4865  * Arrange for the input line to be redisplayed.
4866  */
4867   gl_queue_redisplay(gl);
4868   return 0;
4869 }
4870 
4871 /*.......................................................................
4872  * This is an action function which swaps the character under the cursor
4873  * with the character to the left of the cursor.
4874  */
4875 static KT_KEY_FN(gl_transpose_chars)
4876 {
4877   char from[3];     /* The original string of 2 characters */
4878   char swap[3];     /* The swapped string of two characters */
4879 /*
4880  * If we are at the beginning or end of the line, there aren't two
4881  * characters to swap.
4882  */
4883   if(gl->buff_curpos < 1 || gl->buff_curpos >= gl->ntotal)
4884     return 0;
4885 /*
4886  * If in vi command mode, preserve the current line for potential
4887  * use by vi-undo.
4888  */
4889   gl_save_for_undo(gl);
4890 /*
4891  * Get the original and swapped strings of the two characters.
4892  */
4893   from[0] = gl->line[gl->buff_curpos - 1];
4894   from[1] = gl->line[gl->buff_curpos];
4895   from[2] = '\0';
4896   swap[0] = gl->line[gl->buff_curpos];
4897   swap[1] = gl->line[gl->buff_curpos - 1];
4898   swap[2] = '\0';
4899 /*
4900  * Move the cursor to the start of the two characters.
4901  */
4902   if(gl_place_cursor(gl, gl->buff_curpos-1))
4903     return 1;
4904 /*
4905  * Swap the two characters in the buffer.
4906  */
4907   gl_buffer_char(gl, swap[0], gl->buff_curpos);
4908   gl_buffer_char(gl, swap[1], gl->buff_curpos+1);
4909 /*
4910  * If the sum of the displayed width of the two characters
4911  * in their current and final positions is the same, swapping can
4912  * be done by just overwriting with the two swapped characters.
4913  */
4914   if(gl_displayed_string_width(gl, from, -1, gl->term_curpos) ==
4915      gl_displayed_string_width(gl, swap, -1, gl->term_curpos)) {
4916     int insert = gl->insert;
4917     gl->insert = 0;
4918     if(gl_print_char(gl, swap[0], swap[1]) ||
4919        gl_print_char(gl, swap[1], gl->line[gl->buff_curpos+2]))
4920       return 1;
4921     gl->insert = insert;
4922 /*
4923  * If the swapped substring has a different displayed size, we need to
4924  * redraw everything after the first of the characters.
4925  */
4926   } else {
4927     if(gl_print_string(gl, gl->line + gl->buff_curpos, '\0') ||
4928        gl_truncate_display(gl))
4929       return 1;
4930   };
4931 /*
4932  * Advance the cursor to the character after the swapped pair.
4933  */
4934   return gl_place_cursor(gl, gl->buff_curpos + 2);
4935 }
4936 
4937 /*.......................................................................
4938  * This is an action function which sets a mark at the current cursor
4939  * location.
4940  */
4941 static KT_KEY_FN(gl_set_mark)
4942 {
4943   gl->buff_mark = gl->buff_curpos;
4944   return 0;
4945 }
4946 
4947 /*.......................................................................
4948  * This is an action function which swaps the mark location for the
4949  * cursor location.
4950  */
4951 static KT_KEY_FN(gl_exchange_point_and_mark)
4952 {
4953 /*
4954  * Get the old mark position, and limit to the extent of the input
4955  * line.
4956  */
4957   int old_mark = gl->buff_mark <= gl->ntotal ? gl->buff_mark : gl->ntotal;
4958 /*
4959  * Make the current cursor position the new mark.
4960  */
4961   gl->buff_mark = gl->buff_curpos;
4962 /*
4963  * Move the cursor to the old mark position.
4964  */
4965   return gl_place_cursor(gl, old_mark);
4966 }
4967 
4968 /*.......................................................................
4969  * This is an action function which deletes the characters between the
4970  * mark and the cursor, recording them in gl->cutbuf for later pasting.
4971  */
4972 static KT_KEY_FN(gl_kill_region)
4973 {
4974 /*
4975  * If in vi command mode, preserve the current line for potential
4976  * use by vi-undo.
4977  */
4978   gl_save_for_undo(gl);
4979 /*
4980  * Limit the mark to be within the line.
4981  */
4982   if(gl->buff_mark > gl->ntotal)
4983     gl->buff_mark = gl->ntotal;
4984 /*
4985  * If there are no characters between the cursor and the mark, simply clear
4986  * the cut buffer.
4987  */
4988   if(gl->buff_mark == gl->buff_curpos) {
4989     gl->cutbuf[0] = '\0';
4990     return 0;
4991   };
4992 /*
4993  * If the mark is before the cursor, swap the cursor and the mark.
4994  */
4995   if(gl->buff_mark < gl->buff_curpos && gl_exchange_point_and_mark(gl,1,NULL))
4996     return 1;
4997 /*
4998  * Delete the characters.
4999  */
5000   if(gl_delete_chars(gl, gl->buff_mark - gl->buff_curpos, 1))
5001     return 1;
5002 /*
5003  * Make the mark the same as the cursor position.
5004  */
5005   gl->buff_mark = gl->buff_curpos;
5006   return 0;
5007 }
5008 
5009 /*.......................................................................
5010  * This is an action function which records the characters between the
5011  * mark and the cursor, in gl->cutbuf for later pasting.
5012  */
5013 static KT_KEY_FN(gl_copy_region_as_kill)
5014 {
5015   int ca, cb;  /* The indexes of the first and last characters in the region */
5016   int mark;    /* The position of the mark */
5017 /*
5018  * Get the position of the mark, limiting it to lie within the line.
5019  */
5020   mark = gl->buff_mark > gl->ntotal ? gl->ntotal : gl->buff_mark;
5021 /*
5022  * If there are no characters between the cursor and the mark, clear
5023  * the cut buffer.
5024  */
5025   if(mark == gl->buff_curpos) {
5026     gl->cutbuf[0] = '\0';
5027     return 0;
5028   };
5029 /*
5030  * Get the line indexes of the first and last characters in the region.
5031  */
5032   if(mark < gl->buff_curpos) {
5033     ca = mark;
5034     cb = gl->buff_curpos - 1;
5035   } else {
5036     ca = gl->buff_curpos;
5037     cb = mark - 1;
5038   };
5039 /*
5040  * Copy the region to the cut buffer.
5041  */
5042   memcpy(gl->cutbuf, gl->line + ca, cb + 1 - ca);
5043   gl->cutbuf[cb + 1 - ca] = '\0';
5044   return 0;
5045 }
5046 
5047 /*.......................................................................
5048  * This is an action function which inserts the contents of the cut
5049  * buffer at the current cursor location.
5050  */
5051 static KT_KEY_FN(gl_yank)
5052 {
5053   int i;
5054 /*
5055  * Set the mark at the current location.
5056  */
5057   gl->buff_mark = gl->buff_curpos;
5058 /*
5059  * Do nothing else if the cut buffer is empty.
5060  */
5061   if(gl->cutbuf[0] == '\0')
5062     return gl_ring_bell(gl, 1, NULL);
5063 /*
5064  * If in vi command mode, preserve the current line for potential
5065  * use by vi-undo.
5066  */
5067   gl_save_for_undo(gl);
5068 /*
5069  * Insert the string count times.
5070  */
5071   for(i=0; i<count; i++) {
5072     if(gl_add_string_to_line(gl, gl->cutbuf))
5073       return 1;
5074   };
5075 /*
5076  * gl_add_string_to_line() leaves the cursor after the last character that
5077  * was pasted, whereas vi leaves the cursor over the last character pasted.
5078  */
5079   if(gl->editor == GL_VI_MODE && gl_cursor_left(gl, 1, NULL))
5080     return 1;
5081   return 0;
5082 }
5083 
5084 /*.......................................................................
5085  * This is an action function which inserts the contents of the cut
5086  * buffer one character beyond the current cursor location.
5087  */
5088 static KT_KEY_FN(gl_append_yank)
5089 {
5090   int was_command = gl->vi.command;
5091   int i;
5092 /*
5093  * If the cut buffer is empty, ring the terminal bell.
5094  */
5095   if(gl->cutbuf[0] == '\0')
5096     return gl_ring_bell(gl, 1, NULL);
5097 /*
5098  * Set the mark at the current location + 1.
5099  */
5100   gl->buff_mark = gl->buff_curpos + 1;
5101 /*
5102  * If in vi command mode, preserve the current line for potential
5103  * use by vi-undo.
5104  */
5105   gl_save_for_undo(gl);
5106 /*
5107  * Arrange to paste the text in insert mode after the current character.
5108  */
5109   if(gl_vi_append(gl, 0, NULL))
5110     return 1;
5111 /*
5112  * Insert the string count times.
5113  */
5114   for(i=0; i<count; i++) {
5115     if(gl_add_string_to_line(gl, gl->cutbuf))
5116       return 1;
5117   };
5118 /*
5119  * Switch back to command mode if necessary.
5120  */
5121   if(was_command)
5122     gl_vi_command_mode(gl);
5123   return 0;
5124 }
5125 
5126 /*.......................................................................
5127  * Attempt to ask the terminal for its current size. On systems that
5128  * don't support the TIOCWINSZ ioctl() for querying the terminal size,
5129  * the current values of gl->ncolumn and gl->nrow are returned.
5130  *
5131  * Input:
5132  *  gl     GetLine *  The resource object of gl_get_line().
5133  * Input/Output:
5134  *  ncolumn    int *  The number of columns will be assigned to *ncolumn.
5135  *  nline      int *  The number of lines will be assigned to *nline.
5136  */
5137 static void gl_query_size(GetLine *gl, int *ncolumn, int *nline)
5138 {
5139 #ifdef TIOCGWINSZ
5140 /*
5141  * Query the new terminal window size. Ignore invalid responses.
5142  */
5143   struct winsize size;
5144   if(ioctl(gl->output_fd, TIOCGWINSZ, &size) == 0 &&
5145      size.ws_row > 0 && size.ws_col > 0) {
5146     *ncolumn = size.ws_col;
5147     *nline = size.ws_row;
5148     return;
5149   };
5150 #endif
5151 /*
5152  * Return the existing values.
5153  */
5154   *ncolumn = gl->ncolumn;
5155   *nline = gl->nline;
5156   return;
5157 }
5158 
5159 /*.......................................................................
5160  * Query the size of the terminal, and if it has changed, redraw the
5161  * current input line accordingly.
5162  *
5163  * Input:
5164  *  gl     GetLine *  The resource object of gl_get_line().
5165  * Output:
5166  *  return     int    0 - OK.
5167  *                    1 - Error.
5168  */
5169 static int _gl_update_size(GetLine *gl)
5170 {
5171   int ncolumn, nline;    /* The new size of the terminal */
5172 /*
5173  * Query the new terminal window size.
5174  */
5175   gl_query_size(gl, &ncolumn, &nline);
5176 /*
5177  * Update gl and the displayed line to fit the new dimensions.
5178  */
5179   return gl_handle_tty_resize(gl, ncolumn, nline);
5180 }
5181 
5182 /*.......................................................................
5183  * Redraw the current input line to account for a change in the terminal
5184  * size. Also install the new size in gl.
5185  *
5186  * Input:
5187  *  gl     GetLine *  The resource object of gl_get_line().
5188  *  ncolumn    int    The new number of columns.
5189  *  nline      int    The new number of lines.
5190  * Output:
5191  *  return     int    0 - OK.
5192  *                    1 - Error.
5193  */
5194 static int gl_handle_tty_resize(GetLine *gl, int ncolumn, int nline)
5195 {
5196 /*
5197  * If the input device isn't a terminal, just record the new size.
5198  */
5199   if(!gl->is_term) {
5200     gl->nline = nline;
5201     gl->ncolumn = ncolumn;
5202 /*
5203  * Has the size actually changed?
5204  */
5205   } else if(ncolumn != gl->ncolumn || nline != gl->nline) {
5206 /*
5207  * If we are currently editing a line, erase it.
5208  */
5209     if(gl_erase_line(gl))
5210       return 1;
5211 /*
5212  * Update the recorded window size.
5213  */
5214     gl->nline = nline;
5215     gl->ncolumn = ncolumn;
5216 /*
5217  * Arrange for the input line to be redrawn before the next character
5218  * is read from the terminal.
5219  */
5220     gl_queue_redisplay(gl);
5221   };
5222   return 0;
5223 }
5224 
5225 /*.......................................................................
5226  * This is the action function that recalls the previous line in the
5227  * history buffer.
5228  */
5229 static KT_KEY_FN(gl_up_history)
5230 {
5231 /*
5232  * In vi mode, switch to command mode, since the user is very
5233  * likely to want to move around newly recalled lines.
5234  */
5235   gl_vi_command_mode(gl);
5236 /*
5237  * Forget any previous recall session.
5238  */
5239   gl->preload_id = 0;
5240 /*
5241  * Record the key sequence number of this search action.
5242  */
5243   gl->last_search = gl->keyseq_count;
5244 /*
5245  * We don't want a search prefix for this function.
5246  */
5247   if(_glh_search_prefix(gl->glh, gl->line, 0)) {
5248     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
5249     return 1;
5250   };
5251 /*
5252  * Recall the count'th next older line in the history list. If the first one
5253  * fails we can return since nothing has changed, otherwise we must continue
5254  * and update the line state.
5255  */
5256   if(_glh_find_backwards(gl->glh, gl->line, gl->linelen+1) == NULL)
5257     return 0;
5258   while(--count && _glh_find_backwards(gl->glh, gl->line, gl->linelen+1))
5259     ;
5260 /*
5261  * Accomodate the new contents of gl->line[].
5262  */
5263   gl_update_buffer(gl);
5264 /*
5265  * Arrange to have the cursor placed at the end of the new line.
5266  */
5267   gl->buff_curpos = gl->ntotal;
5268 /*
5269  * Erase and display the new line.
5270  */
5271   gl_queue_redisplay(gl);
5272   return 0;
5273 }
5274 
5275 /*.......................................................................
5276  * This is the action function that recalls the next line in the
5277  * history buffer.
5278  */
5279 static KT_KEY_FN(gl_down_history)
5280 {
5281 /*
5282  * In vi mode, switch to command mode, since the user is very
5283  * likely to want to move around newly recalled lines.
5284  */
5285   gl_vi_command_mode(gl);
5286 /*
5287  * Record the key sequence number of this search action.
5288  */
5289   gl->last_search = gl->keyseq_count;
5290 /*
5291  * If no search is currently in progress continue a previous recall
5292  * session from a previous entered line if possible.
5293  */
5294   if(_glh_line_id(gl->glh, 0) == 0 && gl->preload_id) {
5295     _glh_recall_line(gl->glh, gl->preload_id, gl->line, gl->linelen+1);
5296     gl->preload_id = 0;
5297   } else {
5298 /*
5299  * We don't want a search prefix for this function.
5300  */
5301     if(_glh_search_prefix(gl->glh, gl->line, 0)) {
5302       _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
5303       return 1;
5304     };
5305 /*
5306  * Recall the count'th next newer line in the history list. If the first one
5307  * fails we can return since nothing has changed otherwise we must continue
5308  * and update the line state.
5309  */
5310     if(_glh_find_forwards(gl->glh, gl->line, gl->linelen+1) == NULL)
5311       return 0;
5312     while(--count && _glh_find_forwards(gl->glh, gl->line, gl->linelen+1))
5313       ;
5314   };
5315 /*
5316  * Accomodate the new contents of gl->line[].
5317  */
5318   gl_update_buffer(gl);
5319 /*
5320  * Arrange to have the cursor placed at the end of the new line.
5321  */
5322   gl->buff_curpos = gl->ntotal;
5323 /*
5324  * Erase and display the new line.
5325  */
5326   gl_queue_redisplay(gl);
5327   return 0;
5328 }
5329 
5330 /*.......................................................................
5331  * This is the action function that recalls the previous line in the
5332  * history buffer whos prefix matches the characters that currently
5333  * precede the cursor. By setting count=-1, this can be used internally
5334  * to force searching for the prefix used in the last search.
5335  */
5336 static KT_KEY_FN(gl_history_search_backward)
5337 {
5338 /*
5339  * In vi mode, switch to command mode, since the user is very
5340  * likely to want to move around newly recalled lines.
5341  */
5342   gl_vi_command_mode(gl);
5343 /*
5344  * Forget any previous recall session.
5345  */
5346   gl->preload_id = 0;
5347 /*
5348  * Record the key sequence number of this search action.
5349  */
5350   gl->last_search = gl->keyseq_count;
5351 /*
5352  * If a prefix search isn't already in progress, replace the search
5353  * prefix to the string that precedes the cursor. In vi command mode
5354  * include the character that is under the cursor in the string.  If
5355  * count<0 keep the previous search prefix regardless, so as to force
5356  * a repeat search even if the last command wasn't a history command.
5357  */
5358   if(count >= 0 && !_glh_search_active(gl->glh) &&
5359      _glh_search_prefix(gl->glh, gl->line, gl->buff_curpos +
5360 			(gl->editor==GL_VI_MODE && gl->ntotal>0))) {
5361     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
5362     return 1;
5363   };
5364 /*
5365  * Search backwards for a match to the part of the line which precedes the
5366  * cursor.
5367  */
5368   if(_glh_find_backwards(gl->glh, gl->line, gl->linelen+1) == NULL)
5369     return 0;
5370 /*
5371  * Accomodate the new contents of gl->line[].
5372  */
5373   gl_update_buffer(gl);
5374 /*
5375  * Arrange to have the cursor placed at the end of the new line.
5376  */
5377   gl->buff_curpos = gl->ntotal;
5378 /*
5379  * Erase and display the new line.
5380  */
5381   gl_queue_redisplay(gl);
5382   return 0;
5383 }
5384 
5385 /*.......................................................................
5386  * This is the action function that recalls the previous line in the
5387  * history buffer who's prefix matches that specified in an earlier call
5388  * to gl_history_search_backward() or gl_history_search_forward().
5389  */
5390 static KT_KEY_FN(gl_history_re_search_backward)
5391 {
5392   return gl_history_search_backward(gl, -1, NULL);
5393 }
5394 
5395 /*.......................................................................
5396  * This is the action function that recalls the next line in the
5397  * history buffer who's prefix matches that specified in the earlier call
5398  * to gl_history_search_backward) which started the history search.
5399  * By setting count=-1, this can be used internally to force searching
5400  * for the prefix used in the last search.
5401  */
5402 static KT_KEY_FN(gl_history_search_forward)
5403 {
5404 /*
5405  * In vi mode, switch to command mode, since the user is very
5406  * likely to want to move around newly recalled lines.
5407  */
5408   gl_vi_command_mode(gl);
5409 /*
5410  * Record the key sequence number of this search action.
5411  */
5412   gl->last_search = gl->keyseq_count;
5413 /*
5414  * If a prefix search isn't already in progress, replace the search
5415  * prefix to the string that precedes the cursor. In vi command mode
5416  * include the character that is under the cursor in the string.  If
5417  * count<0 keep the previous search prefix regardless, so as to force
5418  * a repeat search even if the last command wasn't a history command.
5419  */
5420   if(count >= 0 && !_glh_search_active(gl->glh) &&
5421      _glh_search_prefix(gl->glh, gl->line, gl->buff_curpos +
5422 			(gl->editor==GL_VI_MODE && gl->ntotal>0))) {
5423     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
5424     return 1;
5425   };
5426 /*
5427  * Search forwards for the next matching line.
5428  */
5429   if(_glh_find_forwards(gl->glh, gl->line, gl->linelen+1) == NULL)
5430     return 0;
5431 /*
5432  * Accomodate the new contents of gl->line[].
5433  */
5434   gl_update_buffer(gl);
5435 /*
5436  * Arrange for the cursor to be placed at the end of the new line.
5437  */
5438   gl->buff_curpos = gl->ntotal;
5439 /*
5440  * Erase and display the new line.
5441  */
5442   gl_queue_redisplay(gl);
5443   return 0;
5444 }
5445 
5446 /*.......................................................................
5447  * This is the action function that recalls the next line in the
5448  * history buffer who's prefix matches that specified in an earlier call
5449  * to gl_history_search_backward() or gl_history_search_forward().
5450  */
5451 static KT_KEY_FN(gl_history_re_search_forward)
5452 {
5453   return gl_history_search_forward(gl, -1, NULL);
5454 }
5455 
5456 #ifdef HIDE_FILE_SYSTEM
5457 /*.......................................................................
5458  * The following function is used as the default completion handler when
5459  * the filesystem is to be hidden. It simply reports no completions.
5460  */
5461 static CPL_MATCH_FN(gl_no_completions)
5462 {
5463   return 0;
5464 }
5465 #endif
5466 
5467 /*.......................................................................
5468  * This is the tab completion function that completes the filename that
5469  * precedes the cursor position. Its callback data argument must be a
5470  * pointer to a GlCplCallback containing the completion callback function
5471  * and its callback data, or NULL to use the builtin filename completer.
5472  */
5473 static KT_KEY_FN(gl_complete_word)
5474 {
5475   CplMatches *matches;    /* The possible completions */
5476   int suffix_len;         /* The length of the completion extension */
5477   int cont_len;           /* The length of any continuation suffix */
5478   int nextra;             /* The number of characters being added to the */
5479                           /*  total length of the line. */
5480   int buff_pos;           /* The buffer index at which the completion is */
5481                           /*  to be inserted. */
5482   int waserr = 0;         /* True after errors */
5483 /*
5484  * Get the container of the completion callback and its callback data.
5485  */
5486   GlCplCallback *cb = data ? (GlCplCallback *) data : &gl->cplfn;
5487 /*
5488  * In vi command mode, switch to append mode so that the character under
5489  * the cursor is included in the completion (otherwise people can't
5490  * complete at the end of the line).
5491  */
5492   if(gl->vi.command && gl_vi_append(gl, 0, NULL))
5493     return 1;
5494 /*
5495  * Get the cursor position at which the completion is to be inserted.
5496  */
5497   buff_pos = gl->buff_curpos;
5498 /*
5499  * Perform the completion.
5500  */
5501   matches = cpl_complete_word(gl->cpl, gl->line, gl->buff_curpos, cb->data,
5502 			      cb->fn);
5503 /*
5504  * No matching completions?
5505  */
5506   if(!matches) {
5507     waserr = gl_print_info(gl, cpl_last_error(gl->cpl), GL_END_INFO);
5508 /*
5509  * Are there any completions?
5510  */
5511   } else if(matches->nmatch >= 1) {
5512 /*
5513  * If there any ambiguous matches, report them, starting on a new line.
5514  */
5515     if(matches->nmatch > 1 && gl->echo) {
5516       if(_gl_normal_io(gl) ||
5517 	 _cpl_output_completions(matches, gl_write_fn, gl, gl->ncolumn))
5518 	waserr = 1;
5519     };
5520 /*
5521  * Get the length of the suffix and any continuation suffix to add to it.
5522  */
5523     suffix_len = strlen(matches->suffix);
5524     cont_len = strlen(matches->cont_suffix);
5525 /*
5526  * If there is an unambiguous match, and the continuation suffix ends in
5527  * a newline, strip that newline and arrange to have getline return
5528  * after this action function returns.
5529  */
5530     if(matches->nmatch==1 && cont_len > 0 &&
5531        matches->cont_suffix[cont_len - 1] == '\n') {
5532       cont_len--;
5533       if(gl_newline(gl, 1, NULL))
5534 	waserr = 1;
5535     };
5536 /*
5537  * Work out the number of characters that are to be added.
5538  */
5539     nextra = suffix_len + cont_len;
5540 /*
5541  * Is there anything to be added?
5542  */
5543     if(!waserr && nextra) {
5544 /*
5545  * Will there be space for the expansion in the line buffer?
5546  */
5547       if(gl->ntotal + nextra < gl->linelen) {
5548 /*
5549  * Make room to insert the filename extension.
5550  */
5551 	gl_make_gap_in_buffer(gl, gl->buff_curpos, nextra);
5552 /*
5553  * Insert the filename extension.
5554  */
5555 	gl_buffer_string(gl, matches->suffix, suffix_len, gl->buff_curpos);
5556 /*
5557  * Add the terminating characters.
5558  */
5559 	gl_buffer_string(gl, matches->cont_suffix, cont_len,
5560 			 gl->buff_curpos + suffix_len);
5561 /*
5562  * Place the cursor position at the end of the completion.
5563  */
5564 	gl->buff_curpos += nextra;
5565 /*
5566  * If we don't have to redisplay the whole line, redisplay the part
5567  * of the line which follows the original cursor position, and place
5568  * the cursor at the end of the completion.
5569  */
5570 	if(gl->displayed) {
5571 	  if(gl_truncate_display(gl) ||
5572 	     gl_print_string(gl, gl->line + buff_pos, '\0') ||
5573 	     gl_place_cursor(gl, gl->buff_curpos))
5574 	    waserr = 1;
5575 	};
5576       } else {
5577 	(void) gl_print_info(gl,
5578 			     "Insufficient room in line for file completion.",
5579 			     GL_END_INFO);
5580 	waserr = 1;
5581       };
5582     };
5583   };
5584 /*
5585  * If any output had to be written to the terminal, then editing will
5586  * have been suspended, make sure that we are back in raw line editing
5587  * mode before returning.
5588  */
5589   if(_gl_raw_io(gl, 1))
5590     waserr = 1;
5591   return 0;
5592 }
5593 
5594 #ifndef HIDE_FILE_SYSTEM
5595 /*.......................................................................
5596  * This is the function that expands the filename that precedes the
5597  * cursor position. It expands ~user/ expressions, $envvar expressions,
5598  * and wildcards.
5599  */
5600 static KT_KEY_FN(gl_expand_filename)
5601 {
5602   char *start_path;      /* The pointer to the start of the pathname in */
5603                          /*  gl->line[]. */
5604   FileExpansion *result; /* The results of the filename expansion */
5605   int pathlen;           /* The length of the pathname being expanded */
5606   int length;            /* The number of characters needed to display the */
5607                          /*  expanded files. */
5608   int nextra;            /* The number of characters to be added */
5609   int i,j;
5610 /*
5611  * In vi command mode, switch to append mode so that the character under
5612  * the cursor is included in the completion (otherwise people can't
5613  * complete at the end of the line).
5614  */
5615   if(gl->vi.command && gl_vi_append(gl, 0, NULL))
5616     return 1;
5617 /*
5618  * Locate the start of the filename that precedes the cursor position.
5619  */
5620   start_path = _pu_start_of_path(gl->line, gl->buff_curpos);
5621   if(!start_path)
5622     return 1;
5623 /*
5624  * Get the length of the string that is to be expanded.
5625  */
5626   pathlen = gl->buff_curpos - (start_path - gl->line);
5627 /*
5628  * Attempt to expand it.
5629  */
5630   result = ef_expand_file(gl->ef, start_path, pathlen);
5631 /*
5632  * If there was an error, report the error on a new line.
5633  */
5634   if(!result)
5635     return gl_print_info(gl, ef_last_error(gl->ef), GL_END_INFO);
5636 /*
5637  * If no files matched, report this as well.
5638  */
5639   if(result->nfile == 0 || !result->exists)
5640     return gl_print_info(gl, "No files match.", GL_END_INFO);
5641 /*
5642  * If in vi command mode, preserve the current line for potential use by
5643  * vi-undo.
5644  */
5645   gl_save_for_undo(gl);
5646 /*
5647  * Work out how much space we will need to display all of the matching
5648  * filenames, taking account of the space that we need to place between
5649  * them, and the number of additional '\' characters needed to escape
5650  * spaces, tabs and backslash characters in the individual filenames.
5651  */
5652   length = 0;
5653   for(i=0; i<result->nfile; i++) {
5654     char *file = result->files[i];
5655     while(*file) {
5656       int c = *file++;
5657       switch(c) {
5658       case ' ': case '\t': case '\\': case '*': case '?': case '[':
5659 	length++;  /* Count extra backslash characters */
5660       };
5661       length++;    /* Count the character itself */
5662     };
5663     length++;      /* Count the space that follows each filename */
5664   };
5665 /*
5666  * Work out the number of characters that are to be added.
5667  */
5668   nextra = length - pathlen;
5669 /*
5670  * Will there be space for the expansion in the line buffer?
5671  */
5672   if(gl->ntotal + nextra >= gl->linelen) {
5673     return gl_print_info(gl, "Insufficient room in line for file expansion.",
5674 			 GL_END_INFO);
5675   } else {
5676 /*
5677  * Do we need to move the part of the line that followed the unexpanded
5678  * filename?
5679  */
5680     if(nextra > 0) {
5681       gl_make_gap_in_buffer(gl, gl->buff_curpos, nextra);
5682     } else if(nextra < 0) {
5683       gl->buff_curpos += nextra;
5684       gl_remove_from_buffer(gl, gl->buff_curpos, -nextra);
5685     };
5686 /*
5687  * Insert the filenames, separated by spaces, and with internal spaces,
5688  * tabs and backslashes escaped with backslashes.
5689  */
5690     for(i=0,j=start_path - gl->line; i<result->nfile; i++) {
5691       char *file = result->files[i];
5692       while(*file) {
5693 	int c = *file++;
5694 	switch(c) {
5695 	case ' ': case '\t': case '\\': case '*': case '?': case '[':
5696 	  gl_buffer_char(gl, '\\', j++);
5697 	};
5698 	gl_buffer_char(gl, c, j++);
5699       };
5700       gl_buffer_char(gl, ' ', j++);
5701     };
5702   };
5703 /*
5704  * Redisplay the part of the line which follows the start of
5705  * the original filename.
5706  */
5707   if(gl_place_cursor(gl, start_path - gl->line) ||
5708      gl_truncate_display(gl) ||
5709      gl_print_string(gl, start_path, start_path[length]))
5710     return 1;
5711 /*
5712  * Move the cursor to the end of the expansion.
5713  */
5714   return gl_place_cursor(gl, (start_path - gl->line) + length);
5715 }
5716 #endif
5717 
5718 #ifndef HIDE_FILE_SYSTEM
5719 /*.......................................................................
5720  * This is the action function that lists glob expansions of the
5721  * filename that precedes the cursor position. It expands ~user/
5722  * expressions, $envvar expressions, and wildcards.
5723  */
5724 static KT_KEY_FN(gl_list_glob)
5725 {
5726   char *start_path;      /* The pointer to the start of the pathname in */
5727                          /*  gl->line[]. */
5728   FileExpansion *result; /* The results of the filename expansion */
5729   int pathlen;           /* The length of the pathname being expanded */
5730 /*
5731  * Locate the start of the filename that precedes the cursor position.
5732  */
5733   start_path = _pu_start_of_path(gl->line, gl->buff_curpos);
5734   if(!start_path)
5735     return 1;
5736 /*
5737  * Get the length of the string that is to be expanded.
5738  */
5739   pathlen = gl->buff_curpos - (start_path - gl->line);
5740 /*
5741  * Attempt to expand it.
5742  */
5743   result = ef_expand_file(gl->ef, start_path, pathlen);
5744 /*
5745  * If there was an error, report it.
5746  */
5747   if(!result) {
5748     return gl_print_info(gl,  ef_last_error(gl->ef), GL_END_INFO);
5749 /*
5750  * If no files matched, report this as well.
5751  */
5752   } else if(result->nfile == 0 || !result->exists) {
5753     return gl_print_info(gl, "No files match.", GL_END_INFO);
5754 /*
5755  * List the matching expansions.
5756  */
5757   } else if(gl->echo) {
5758     if(gl_start_newline(gl, 1) ||
5759        _ef_output_expansions(result, gl_write_fn, gl, gl->ncolumn))
5760       return 1;
5761     gl_queue_redisplay(gl);
5762   };
5763   return 0;
5764 }
5765 #endif
5766 
5767 /*.......................................................................
5768  * Return non-zero if a character should be considered a part of a word.
5769  *
5770  * Input:
5771  *  c       int  The character to be tested.
5772  * Output:
5773  *  return  int  True if the character should be considered part of a word.
5774  */
5775 static int gl_is_word_char(int c)
5776 {
5777   return isalnum((int)(unsigned char)c) || strchr(GL_WORD_CHARS, c) != NULL;
5778 }
5779 
5780 /*.......................................................................
5781  * Override the builtin file-completion callback that is bound to the
5782  * "complete_word" action function.
5783  *
5784  * Input:
5785  *  gl            GetLine *  The resource object of the command-line input
5786  *                           module.
5787  *  data             void *  This is passed to match_fn() whenever it is
5788  *                           called. It could, for example, point to a
5789  *                           symbol table where match_fn() could look
5790  *                           for possible completions.
5791  *  match_fn   CplMatchFn *  The function that will identify the prefix
5792  *                           to be completed from the input line, and
5793  *                           report matching symbols.
5794  * Output:
5795  *  return            int    0 - OK.
5796  *                           1 - Error.
5797  */
5798 int gl_customize_completion(GetLine *gl, void *data, CplMatchFn *match_fn)
5799 {
5800   sigset_t oldset; /* The signals that were blocked on entry to this function */
5801 /*
5802  * Check the arguments.
5803  */
5804   if(!gl || !match_fn) {
5805     if(gl)
5806       _err_record_msg(gl->err, "NULL argument", END_ERR_MSG);
5807     errno = EINVAL;
5808     return 1;
5809   };
5810 /*
5811  * Temporarily block all signals.
5812  */
5813   gl_mask_signals(gl, &oldset);
5814 /*
5815  * Record the new completion function and its callback data.
5816  */
5817   gl->cplfn.fn = match_fn;
5818   gl->cplfn.data = data;
5819 /*
5820  * Restore the process signal mask before returning.
5821  */
5822   gl_unmask_signals(gl, &oldset);
5823   return 0;
5824 }
5825 
5826 /*.......................................................................
5827  * Change the terminal (or stream) that getline interacts with.
5828  *
5829  * Input:
5830  *  gl            GetLine *  The resource object of the command-line input
5831  *                           module.
5832  *  input_fp         FILE *  The stdio stream to read from.
5833  *  output_fp        FILE *  The stdio stream to write to.
5834  *  term             char *  The terminal type. This can be NULL if
5835  *                           either or both of input_fp and output_fp don't
5836  *                           refer to a terminal. Otherwise it should refer
5837  *                           to an entry in the terminal information database.
5838  * Output:
5839  *  return            int    0 - OK.
5840  *                           1 - Error.
5841  */
5842 int gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp,
5843 		       const char *term)
5844 {
5845   sigset_t oldset; /* The signals that were blocked on entry to this function */
5846   int status;      /* The return status of _gl_change_terminal() */
5847 /*
5848  * Check the arguments.
5849  */
5850   if(!gl) {
5851     errno = EINVAL;
5852     return 1;
5853   };
5854 /*
5855  * Block all signals.
5856  */
5857   if(gl_mask_signals(gl, &oldset))
5858     return 1;
5859 /*
5860  * Execute the private body of the function while signals are blocked.
5861  */
5862   status = _gl_change_terminal(gl, input_fp, output_fp, term);
5863 /*
5864  * Restore the process signal mask.
5865  */
5866   gl_unmask_signals(gl, &oldset);
5867   return status;
5868 }
5869 
5870 /*.......................................................................
5871  * This is the private body of the gl_change_terminal() function. It
5872  * assumes that the caller has checked its arguments and blocked the
5873  * delivery of signals.
5874  */
5875 static int _gl_change_terminal(GetLine *gl, FILE *input_fp, FILE *output_fp,
5876 			       const char *term)
5877 {
5878   int is_term = 0;   /* True if both input_fd and output_fd are associated */
5879                      /*  with a terminal. */
5880 /*
5881  * Require that input_fp and output_fp both be valid.
5882  */
5883   if(!input_fp || !output_fp) {
5884     gl_print_info(gl, "Can't change terminal. Bad input/output stream(s).",
5885 		  GL_END_INFO);
5886     return 1;
5887   };
5888 /*
5889  * Are we displacing an existing terminal (as opposed to setting the
5890  * initial terminal)?
5891  */
5892   if(gl->input_fd >= 0) {
5893 /*
5894  * Make sure to leave the previous terminal in a usable state.
5895  */
5896     if(_gl_normal_io(gl))
5897       return 1;
5898 /*
5899  * Remove the displaced terminal from the list of fds to watch.
5900  */
5901 #ifdef HAVE_SELECT
5902     FD_CLR(gl->input_fd, &gl->rfds);
5903 #endif
5904   };
5905 /*
5906  * Record the file descriptors and streams.
5907  */
5908   gl->input_fp = input_fp;
5909   gl->input_fd = fileno(input_fp);
5910   gl->output_fp = output_fp;
5911   gl->output_fd = fileno(output_fp);
5912 /*
5913  * If needed, expand the record of the maximum file-descriptor that might
5914  * need to be monitored with select().
5915  */
5916 #ifdef HAVE_SELECT
5917   if(gl->input_fd > gl->max_fd)
5918     gl->max_fd = gl->input_fd;
5919 #endif
5920 /*
5921  * Disable terminal interaction until we have enough info to interact
5922  * with the terminal.
5923  */
5924   gl->is_term = 0;
5925 /*
5926  * For terminal editing, we need both output_fd and input_fd to refer to
5927  * a terminal. While we can't verify that they both point to the same
5928  * terminal, we can verify that they point to terminals.
5929  */
5930   is_term = isatty(gl->input_fd) && isatty(gl->output_fd);
5931 /*
5932  * If we are interacting with a terminal and no terminal type has been
5933  * specified, treat it as a generic ANSI terminal.
5934  */
5935   if(is_term && !term)
5936     term = "ansi";
5937 /*
5938  * Make a copy of the terminal type string.
5939  */
5940   if(term != gl->term) {
5941 /*
5942  * Delete any old terminal type string.
5943  */
5944     if(gl->term) {
5945       free(gl->term);
5946       gl->term = NULL;
5947     };
5948 /*
5949  * Make a copy of the new terminal-type string, if any.
5950  */
5951     if(term) {
5952       size_t termsz = strlen(term)+1;
5953 
5954       gl->term = (char *) malloc(termsz);
5955       if(gl->term)
5956 	strlcpy(gl->term, term, termsz);
5957     };
5958   };
5959 /*
5960  * Clear any terminal-specific key bindings that were taken from the
5961  * settings of the last terminal.
5962  */
5963   _kt_clear_bindings(gl->bindings, KTB_TERM);
5964 /*
5965  * If we have a terminal install new bindings for it.
5966  */
5967   if(is_term) {
5968 /*
5969  * Get the current settings of the terminal.
5970  */
5971     if(tcgetattr(gl->input_fd, &gl->oldattr)) {
5972       _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG);
5973       return 1;
5974     };
5975 /*
5976  * If we don't set this now, gl_control_strings() won't know
5977  * that it is talking to a terminal.
5978  */
5979     gl->is_term = 1;
5980 /*
5981  * Lookup the terminal control string and size information.
5982  */
5983     if(gl_control_strings(gl, term)) {
5984       gl->is_term = 0;
5985       return 1;
5986     };
5987 /*
5988  * Bind terminal-specific keys.
5989  */
5990     if(gl_bind_terminal_keys(gl))
5991       return 1;
5992   };
5993 /*
5994  * Assume that the caller has given us a terminal in a sane state.
5995  */
5996   gl->io_mode = GL_NORMAL_MODE;
5997 /*
5998  * Switch into the currently configured I/O mode.
5999  */
6000   if(_gl_io_mode(gl, gl->io_mode))
6001     return 1;
6002   return 0;
6003 }
6004 
6005 /*.......................................................................
6006  * Set up terminal-specific key bindings.
6007  *
6008  * Input:
6009  *  gl            GetLine *  The resource object of the command-line input
6010  *                           module.
6011  * Output:
6012  *  return            int    0 - OK.
6013  *                           1 - Error.
6014  */
6015 static int gl_bind_terminal_keys(GetLine *gl)
6016 {
6017 /*
6018  * Install key-bindings for the special terminal characters.
6019  */
6020   if(gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VINTR],
6021 			  "user-interrupt") ||
6022      gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VQUIT], "abort") ||
6023      gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VSUSP], "suspend"))
6024     return 1;
6025 /*
6026  * In vi-mode, arrange for the above characters to be seen in command
6027  * mode.
6028  */
6029   if(gl->editor == GL_VI_MODE) {
6030     if(gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VINTR]),
6031 			    "user-interrupt") ||
6032        gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VQUIT]),
6033 			    "abort") ||
6034        gl_bind_control_char(gl, KTB_TERM, MAKE_META(gl->oldattr.c_cc[VSUSP]),
6035 			    "suspend"))
6036       return 1;
6037   };
6038 /*
6039  * Non-universal special keys.
6040  */
6041 #ifdef VLNEXT
6042   if(gl_bind_control_char(gl, KTB_TERM, gl->oldattr.c_cc[VLNEXT],
6043 			  "literal-next"))
6044     return 1;
6045 #else
6046   if(_kt_set_keybinding(gl->bindings, KTB_TERM, "^V", "literal-next")) {
6047     _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
6048     return 1;
6049   };
6050 #endif
6051 /*
6052  * Bind action functions to the terminal-specific arrow keys
6053  * looked up by gl_control_strings().
6054  */
6055   if(_gl_bind_arrow_keys(gl))
6056     return 1;
6057   return 0;
6058 }
6059 
6060 /*.......................................................................
6061  * This function is normally bound to control-D. When it is invoked within
6062  * a line it deletes the character which follows the cursor. When invoked
6063  * at the end of the line it lists possible file completions, and when
6064  * invoked on an empty line it causes gl_get_line() to return EOF. This
6065  * function emulates the one that is normally bound to control-D by tcsh.
6066  */
6067 static KT_KEY_FN(gl_del_char_or_list_or_eof)
6068 {
6069 /*
6070  * If we have an empty line arrange to return EOF.
6071  */
6072   if(gl->ntotal < 1) {
6073     gl_record_status(gl, GLR_EOF, 0);
6074     return 1;
6075 /*
6076  * If we are at the end of the line list possible completions.
6077  */
6078   } else if(gl->buff_curpos >= gl->ntotal) {
6079     return gl_list_completions(gl, 1, NULL);
6080 /*
6081  * Within the line delete the character that follows the cursor.
6082  */
6083   } else {
6084 /*
6085  * If in vi command mode, first preserve the current line for potential use
6086  * by vi-undo.
6087  */
6088     gl_save_for_undo(gl);
6089 /*
6090  * Delete 'count' characters.
6091  */
6092     return gl_forward_delete_char(gl, count, NULL);
6093   };
6094 }
6095 
6096 /*.......................................................................
6097  * This function is normally bound to control-D in vi mode. When it is
6098  * invoked within a line it lists possible file completions, and when
6099  * invoked on an empty line it causes gl_get_line() to return EOF. This
6100  * function emulates the one that is normally bound to control-D by tcsh.
6101  */
6102 static KT_KEY_FN(gl_list_or_eof)
6103 {
6104 /*
6105  * If we have an empty line arrange to return EOF.
6106  */
6107   if(gl->ntotal < 1) {
6108     gl_record_status(gl, GLR_EOF, 0);
6109     return 1;
6110 /*
6111  * Otherwise list possible completions.
6112  */
6113   } else {
6114     return gl_list_completions(gl, 1, NULL);
6115   };
6116 }
6117 
6118 /*.......................................................................
6119  * List possible completions of the word that precedes the cursor. The
6120  * callback data argument must either be NULL to select the default
6121  * file completion callback, or be a GlCplCallback object containing the
6122  * completion callback function to call.
6123  */
6124 static KT_KEY_FN(gl_list_completions)
6125 {
6126   int waserr = 0;   /* True after errors */
6127 /*
6128  * Get the container of the completion callback and its callback data.
6129  */
6130   GlCplCallback *cb = data ? (GlCplCallback *) data : &gl->cplfn;
6131 /*
6132  * Get the list of possible completions.
6133  */
6134   CplMatches *matches = cpl_complete_word(gl->cpl, gl->line, gl->buff_curpos,
6135 					  cb->data, cb->fn);
6136 /*
6137  * No matching completions?
6138  */
6139   if(!matches) {
6140     waserr = gl_print_info(gl, cpl_last_error(gl->cpl), GL_END_INFO);
6141 /*
6142  * List the matches.
6143  */
6144   } else if(matches->nmatch > 0 && gl->echo) {
6145     if(_gl_normal_io(gl) ||
6146        _cpl_output_completions(matches, gl_write_fn, gl, gl->ncolumn))
6147       waserr = 1;
6148   };
6149 /*
6150  * If any output had to be written to the terminal, then editing will
6151  * have been suspended, make sure that we are back in raw line editing
6152  * mode before returning.
6153  */
6154   if(_gl_raw_io(gl, 1))
6155     waserr = 1;
6156   return waserr;
6157 }
6158 
6159 /*.......................................................................
6160  * Where the user has used the symbolic arrow-key names to specify
6161  * arrow key bindings, bind the specified action functions to the default
6162  * and terminal specific arrow key sequences.
6163  *
6164  * Input:
6165  *  gl     GetLine *   The getline resource object.
6166  * Output:
6167  *  return     int     0 - OK.
6168  *                     1 - Error.
6169  */
6170 static int _gl_bind_arrow_keys(GetLine *gl)
6171 {
6172 /*
6173  * Process each of the arrow keys.
6174  */
6175   if(_gl_rebind_arrow_key(gl, "up", gl->u_arrow, "^[[A", "^[OA") ||
6176      _gl_rebind_arrow_key(gl, "down", gl->d_arrow, "^[[B", "^[OB") ||
6177      _gl_rebind_arrow_key(gl, "left", gl->l_arrow, "^[[D", "^[OD") ||
6178      _gl_rebind_arrow_key(gl, "right", gl->r_arrow, "^[[C", "^[OC"))
6179     return 1;
6180   return 0;
6181 }
6182 
6183 /*.......................................................................
6184  * Lookup the action function of a symbolic arrow-key binding, and bind
6185  * it to the terminal-specific and default arrow-key sequences. Note that
6186  * we don't trust the terminal-specified key sequences to be correct.
6187  * The main reason for this is that on some machines the xterm terminfo
6188  * entry is for hardware X-terminals, rather than xterm terminal emulators
6189  * and the two terminal types emit different character sequences when the
6190  * their cursor keys are pressed. As a result we also supply a couple
6191  * of default key sequences.
6192  *
6193  * Input:
6194  *  gl          GetLine *   The resource object of gl_get_line().
6195  *  name           char *   The symbolic name of the arrow key.
6196  *  term_seq       char *   The terminal-specific arrow-key sequence.
6197  *  def_seq1       char *   The first default arrow-key sequence.
6198  *  def_seq2       char *   The second arrow-key sequence.
6199  * Output:
6200  *  return          int     0 - OK.
6201  *                          1 - Error.
6202  */
6203 static int _gl_rebind_arrow_key(GetLine *gl, const char *name,
6204 				const char *term_seq, const char *def_seq1,
6205 				const char *def_seq2)
6206 {
6207   KeySym *keysym;  /* The binding-table entry matching the arrow-key name */
6208   int nsym;        /* The number of ambiguous matches */
6209 /*
6210  * Lookup the key binding for the symbolic name of the arrow key. This
6211  * will either be the default action, or a user provided one.
6212  */
6213   if(_kt_lookup_keybinding(gl->bindings, name, strlen(name), &keysym, &nsym)
6214      == KT_EXACT_MATCH) {
6215 /*
6216  * Get the action function.
6217  */
6218     KtAction *action = keysym->actions + keysym->binder;
6219     KtKeyFn *fn = action->fn;
6220     void *data = action->data;
6221 /*
6222  * Bind this to each of the specified key sequences.
6223  */
6224     if((term_seq &&
6225 	_kt_set_keyfn(gl->bindings, KTB_TERM, term_seq, fn, data)) ||
6226        (def_seq1 &&
6227 	_kt_set_keyfn(gl->bindings, KTB_NORM, def_seq1, fn, data)) ||
6228        (def_seq2 &&
6229 	_kt_set_keyfn(gl->bindings, KTB_NORM, def_seq2, fn, data))) {
6230       _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
6231       return 1;
6232     };
6233   };
6234   return 0;
6235 }
6236 
6237 /*.......................................................................
6238  * Read getline configuration information from a given file.
6239  *
6240  * Input:
6241  *  gl           GetLine *  The getline resource object.
6242  *  filename  const char *  The name of the file to read configuration
6243  *                          information from. The contents of this file
6244  *                          are as described in the gl_get_line(3) man
6245  *                          page for the default ~/.teclarc configuration
6246  *                          file.
6247  *  who         KtBinder    Who bindings are to be installed for.
6248  * Output:
6249  *  return           int    0 - OK.
6250  *                          1 - Irrecoverable error.
6251  */
6252 static int _gl_read_config_file(GetLine *gl, const char *filename, KtBinder who)
6253 {
6254 /*
6255  * If filesystem access is to be excluded, configuration files can't
6256  * be read.
6257  */
6258 #ifdef WITHOUT_FILE_SYSTEM
6259   _err_record_msg(gl->err,
6260 		  "Can't read configuration files without filesystem access",
6261 		  END_ERR_MSG);
6262   errno = EINVAL;
6263   return 1;
6264 #else
6265   FileExpansion *expansion; /* The expansion of the filename */
6266   FILE *fp;                 /* The opened file */
6267   int waserr = 0;           /* True if an error occurred while reading */
6268   int lineno = 1;           /* The line number being processed */
6269 /*
6270  * Check the arguments.
6271  */
6272   if(!gl || !filename) {
6273     if(gl)
6274       _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
6275     errno = EINVAL;
6276     return 1;
6277   };
6278 /*
6279  * Expand the filename.
6280  */
6281   expansion = ef_expand_file(gl->ef, filename, -1);
6282   if(!expansion) {
6283     gl_print_info(gl, "Unable to expand ", filename, " (",
6284 		  ef_last_error(gl->ef), ").", GL_END_INFO);
6285     return 1;
6286   };
6287 /*
6288  * Attempt to open the file.
6289  */
6290   fp = fopen(expansion->files[0], "r");
6291 /*
6292  * It isn't an error for there to be no configuration file.
6293  */
6294   if(!fp)
6295     return 0;
6296 /*
6297  * Parse the contents of the file.
6298  */
6299   while(!waserr && !feof(fp))
6300     waserr = _gl_parse_config_line(gl, fp, glc_file_getc, filename, who,
6301 				   &lineno);
6302 /*
6303  * Bind action functions to the terminal-specific arrow keys.
6304  */
6305   if(_gl_bind_arrow_keys(gl))
6306     return 1;
6307 /*
6308  * Clean up.
6309  */
6310   (void) fclose(fp);
6311   return waserr;
6312 #endif
6313 }
6314 
6315 /*.......................................................................
6316  * Read GetLine configuration information from a string. The contents of
6317  * the string are the same as those described in the gl_get_line(3)
6318  * man page for the contents of the ~/.teclarc configuration file.
6319  */
6320 static int _gl_read_config_string(GetLine *gl, const char *buffer, KtBinder who)
6321 {
6322   const char *bptr;         /* A pointer into buffer[] */
6323   int waserr = 0;           /* True if an error occurred while reading */
6324   int lineno = 1;           /* The line number being processed */
6325 /*
6326  * Check the arguments.
6327  */
6328   if(!gl || !buffer) {
6329     if(gl)
6330       _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
6331     errno = EINVAL;
6332     return 1;
6333   };
6334 /*
6335  * Get a pointer to the start of the buffer.
6336  */
6337   bptr = buffer;
6338 /*
6339  * Parse the contents of the buffer.
6340  */
6341   while(!waserr && *bptr)
6342     waserr = _gl_parse_config_line(gl, &bptr, glc_buff_getc, "", who, &lineno);
6343 /*
6344  * Bind action functions to the terminal-specific arrow keys.
6345  */
6346   if(_gl_bind_arrow_keys(gl))
6347     return 1;
6348   return waserr;
6349 }
6350 
6351 /*.......................................................................
6352  * Parse the next line of a getline configuration file.
6353  *
6354  * Input:
6355  *  gl         GetLine *  The getline resource object.
6356  *  stream        void *  The pointer representing the stream to be read
6357  *                        by getc_fn().
6358  *  getc_fn  GlcGetcFn *  A callback function which when called with
6359  *                       'stream' as its argument, returns the next
6360  *                        unread character from the stream.
6361  *  origin  const char *  The name of the entity being read (eg. a
6362  *                        file name).
6363  *  who       KtBinder    Who bindings are to be installed for.
6364  * Input/Output:
6365  *  lineno         int *  The line number being processed is to be
6366  *                        maintained in *lineno.
6367  * Output:
6368  *  return         int    0 - OK.
6369  *                        1 - Irrecoverable error.
6370  */
6371 static int _gl_parse_config_line(GetLine *gl, void *stream, GlcGetcFn *getc_fn,
6372 				 const char *origin, KtBinder who, int *lineno)
6373 {
6374   char buffer[GL_CONF_BUFLEN+1];  /* The input line buffer */
6375   char *argv[GL_CONF_MAXARG];     /* The argument list */
6376   int argc = 0;                   /* The number of arguments in argv[] */
6377   int c;                          /* A character from the file */
6378   int escaped = 0;                /* True if the next character is escaped */
6379   int i;
6380 /*
6381  * Skip spaces and tabs.
6382  */
6383   do c = getc_fn(stream); while(c==' ' || c=='\t');
6384 /*
6385  * Comments extend to the end of the line.
6386  */
6387   if(c=='#')
6388     do c = getc_fn(stream); while(c != '\n' && c != EOF);
6389 /*
6390  * Ignore empty lines.
6391  */
6392   if(c=='\n' || c==EOF) {
6393     (*lineno)++;
6394     return 0;
6395   };
6396 /*
6397  * Record the buffer location of the start of the first argument.
6398  */
6399   argv[argc] = buffer;
6400 /*
6401  * Read the rest of the line, stopping early if a comment is seen, or
6402  * the buffer overflows, and replacing sequences of spaces with a
6403  * '\0', and recording the thus terminated string as an argument.
6404  */
6405   i = 0;
6406   while(i<GL_CONF_BUFLEN) {
6407 /*
6408  * Did we hit the end of the latest argument?
6409  */
6410     if(c==EOF || (!escaped && (c==' ' || c=='\n' || c=='\t' || c=='#'))) {
6411 /*
6412  * Terminate the argument.
6413  */
6414       buffer[i++] = '\0';
6415       argc++;
6416 /*
6417  * Skip spaces and tabs.
6418  */
6419       while(c==' ' || c=='\t')
6420 	c = getc_fn(stream);
6421 /*
6422  * If we hit the end of the line, or the start of a comment, exit the loop.
6423  */
6424       if(c==EOF || c=='\n' || c=='#')
6425 	break;
6426 /*
6427  * Start recording the next argument.
6428  */
6429       if(argc >= GL_CONF_MAXARG) {
6430 	gl_report_config_error(gl, origin, *lineno, "Too many arguments.");
6431 	do c = getc_fn(stream); while(c!='\n' && c!=EOF);  /* Skip past eol */
6432 	return 0;
6433       };
6434       argv[argc] = buffer + i;
6435 /*
6436  * The next character was preceded by spaces, so it isn't escaped.
6437  */
6438       escaped = 0;
6439     } else {
6440 /*
6441  * If we hit an unescaped backslash, this means that we should arrange
6442  * to treat the next character like a simple alphabetical character.
6443  */
6444       if(c=='\\' && !escaped) {
6445 	escaped = 1;
6446 /*
6447  * Splice lines where the newline is escaped.
6448  */
6449       } else if(c=='\n' && escaped) {
6450 	(*lineno)++;
6451 /*
6452  * Record a normal character, preserving any preceding backslash.
6453  */
6454       } else {
6455 	if(escaped)
6456 	  buffer[i++] = '\\';
6457 	if(i>=GL_CONF_BUFLEN)
6458 	  break;
6459 	escaped = 0;
6460 	buffer[i++] = c;
6461       };
6462 /*
6463  * Get the next character.
6464  */
6465       c = getc_fn(stream);
6466     };
6467   };
6468 /*
6469  * Did the buffer overflow?
6470  */
6471   if(i>=GL_CONF_BUFLEN) {
6472     gl_report_config_error(gl, origin, *lineno, "Line too long.");
6473     return 0;
6474   };
6475 /*
6476  * The first argument should be a command name.
6477  */
6478   if(strcmp(argv[0], "bind") == 0) {
6479     const char *action = NULL; /* A NULL action removes a keybinding */
6480     const char *keyseq = NULL;
6481     switch(argc) {
6482     case 3:
6483       action = argv[2];
6484     case 2:              /* Note the intentional fallthrough */
6485       keyseq = argv[1];
6486 /*
6487  * Attempt to record the new keybinding.
6488  */
6489       if(_kt_set_keybinding(gl->bindings, who, keyseq, action)) {
6490 	gl_report_config_error(gl, origin, *lineno,
6491 			       _kt_last_error(gl->bindings));
6492       };
6493       break;
6494     default:
6495       gl_report_config_error(gl, origin, *lineno, "Wrong number of arguments.");
6496     };
6497   } else if(strcmp(argv[0], "edit-mode") == 0) {
6498     if(argc == 2 && strcmp(argv[1], "emacs") == 0) {
6499       gl_change_editor(gl, GL_EMACS_MODE);
6500     } else if(argc == 2 && strcmp(argv[1], "vi") == 0) {
6501       gl_change_editor(gl, GL_VI_MODE);
6502     } else if(argc == 2 && strcmp(argv[1], "none") == 0) {
6503       gl_change_editor(gl, GL_NO_EDITOR);
6504     } else {
6505       gl_report_config_error(gl, origin, *lineno,
6506 			     "The argument of editor should be vi or emacs.");
6507     };
6508   } else if(strcmp(argv[0], "nobeep") == 0) {
6509     gl->silence_bell = 1;
6510   } else {
6511     gl_report_config_error(gl, origin, *lineno, "Unknown command name.");
6512   };
6513 /*
6514  * Skip any trailing comment.
6515  */
6516   while(c != '\n' && c != EOF)
6517     c = getc_fn(stream);
6518   (*lineno)++;
6519   return 0;
6520 }
6521 
6522 /*.......................................................................
6523  * This is a private function of _gl_parse_config_line() which prints
6524  * out an error message about the contents of the line, prefixed by the
6525  * name of the origin of the line and its line number.
6526  *
6527  * Input:
6528  *  gl         GetLine *  The resource object of gl_get_line().
6529  *  origin  const char *  The name of the entity being read (eg. a
6530  *                        file name).
6531  *  lineno         int    The line number at which the error occurred.
6532  *  errmsg  const char *  The error message.
6533  * Output:
6534  *  return         int    0 - OK.
6535  *                        1 - Error.
6536  */
6537 static int gl_report_config_error(GetLine *gl, const char *origin, int lineno,
6538 				  const char *errmsg)
6539 {
6540   char lnum[20];   /* A buffer in which to render a single integer */
6541 /*
6542  * Convert the line number into a string.
6543  */
6544   snprintf(lnum, sizeof(lnum), "%d", lineno);
6545 /*
6546  * Have the string printed on the terminal.
6547  */
6548   return gl_print_info(gl, origin, ":", lnum, ": ", errmsg, GL_END_INFO);
6549 }
6550 
6551 /*.......................................................................
6552  * This is the _gl_parse_config_line() callback function which reads the
6553  * next character from a configuration file.
6554  */
6555 static GLC_GETC_FN(glc_file_getc)
6556 {
6557   return fgetc((FILE *) stream);
6558 }
6559 
6560 /*.......................................................................
6561  * This is the _gl_parse_config_line() callback function which reads the
6562  * next character from a buffer. Its stream argument is a pointer to a
6563  * variable which is, in turn, a pointer into the buffer being read from.
6564  */
6565 static GLC_GETC_FN(glc_buff_getc)
6566 {
6567   const char **lptr = (char const **) stream;
6568   return **lptr ? *(*lptr)++ : EOF;
6569 }
6570 
6571 #ifndef HIDE_FILE_SYSTEM
6572 /*.......................................................................
6573  * When this action is triggered, it arranges to temporarily read command
6574  * lines from the regular file whos name precedes the cursor.
6575  * The current line is first discarded.
6576  */
6577 static KT_KEY_FN(gl_read_from_file)
6578 {
6579   char *start_path;       /* The pointer to the start of the pathname in */
6580                           /*  gl->line[]. */
6581   FileExpansion *result;  /* The results of the filename expansion */
6582   int pathlen;            /* The length of the pathname being expanded */
6583 /*
6584  * Locate the start of the filename that precedes the cursor position.
6585  */
6586   start_path = _pu_start_of_path(gl->line, gl->buff_curpos);
6587   if(!start_path)
6588     return 1;
6589 /*
6590  * Get the length of the pathname string.
6591  */
6592   pathlen = gl->buff_curpos - (start_path - gl->line);
6593 /*
6594  * Attempt to expand the pathname.
6595  */
6596   result = ef_expand_file(gl->ef, start_path, pathlen);
6597 /*
6598  * If there was an error, report the error on a new line.
6599  */
6600   if(!result) {
6601     return gl_print_info(gl, ef_last_error(gl->ef), GL_END_INFO);
6602 /*
6603  * If no files matched, report this as well.
6604  */
6605   } else if(result->nfile == 0 || !result->exists) {
6606     return gl_print_info(gl, "No files match.", GL_END_INFO);
6607 /*
6608  * Complain if more than one file matches.
6609  */
6610   } else if(result->nfile > 1) {
6611     return gl_print_info(gl, "More than one file matches.", GL_END_INFO);
6612 /*
6613  * Disallow input from anything but normal files. In principle we could
6614  * also support input from named pipes. Terminal files would be a problem
6615  * since we wouldn't know the terminal type, and other types of files
6616  * might cause the library to lock up.
6617  */
6618   } else if(!_pu_path_is_file(result->files[0])) {
6619     return gl_print_info(gl, "Not a normal file.", GL_END_INFO);
6620   } else {
6621 /*
6622  * Attempt to open and install the specified file for reading.
6623  */
6624     gl->file_fp = fopen(result->files[0], "r");
6625     if(!gl->file_fp) {
6626       return gl_print_info(gl, "Unable to open: ", result->files[0],
6627 			   GL_END_INFO);
6628     };
6629 /*
6630  * If needed, expand the record of the maximum file-descriptor that might
6631  * need to be monitored with select().
6632  */
6633 #ifdef HAVE_SELECT
6634     if(fileno(gl->file_fp) > gl->max_fd)
6635       gl->max_fd = fileno(gl->file_fp);
6636 #endif
6637 /*
6638  * Is non-blocking I/O needed?
6639  */
6640     if(gl->raw_mode && gl->io_mode==GL_SERVER_MODE &&
6641        gl_nonblocking_io(gl, fileno(gl->file_fp))) {
6642       gl_revert_input(gl);
6643       return gl_print_info(gl, "Can't read file %s with non-blocking I/O",
6644 			   result->files[0]);
6645     };
6646 /*
6647  * Inform the user what is happening.
6648  */
6649     if(gl_print_info(gl, "<Taking input from ", result->files[0], ">",
6650 		     GL_END_INFO))
6651       return 1;
6652   };
6653   return 0;
6654 }
6655 #endif
6656 
6657 /*.......................................................................
6658  * Close any temporary file that is being used for input.
6659  *
6660  * Input:
6661  *  gl     GetLine *  The getline resource object.
6662  */
6663 static void gl_revert_input(GetLine *gl)
6664 {
6665   if(gl->file_fp)
6666     fclose(gl->file_fp);
6667   gl->file_fp = NULL;
6668   gl->endline = 1;
6669 }
6670 
6671 /*.......................................................................
6672  * This is the action function that recalls the oldest line in the
6673  * history buffer.
6674  */
6675 static KT_KEY_FN(gl_beginning_of_history)
6676 {
6677 /*
6678  * In vi mode, switch to command mode, since the user is very
6679  * likely to want to move around newly recalled lines.
6680  */
6681   gl_vi_command_mode(gl);
6682 /*
6683  * Forget any previous recall session.
6684  */
6685   gl->preload_id = 0;
6686 /*
6687  * Record the key sequence number of this search action.
6688  */
6689   gl->last_search = gl->keyseq_count;
6690 /*
6691  * Recall the next oldest line in the history list.
6692  */
6693   if(_glh_oldest_line(gl->glh, gl->line, gl->linelen+1) == NULL)
6694     return 0;
6695 /*
6696  * Accomodate the new contents of gl->line[].
6697  */
6698   gl_update_buffer(gl);
6699 /*
6700  * Arrange to have the cursor placed at the end of the new line.
6701  */
6702   gl->buff_curpos = gl->ntotal;
6703 /*
6704  * Erase and display the new line.
6705  */
6706   gl_queue_redisplay(gl);
6707   return 0;
6708 }
6709 
6710 /*.......................................................................
6711  * If a history session is currently in progress, this action function
6712  * recalls the line that was being edited when the session started. If
6713  * no history session is in progress, it does nothing.
6714  */
6715 static KT_KEY_FN(gl_end_of_history)
6716 {
6717 /*
6718  * In vi mode, switch to command mode, since the user is very
6719  * likely to want to move around newly recalled lines.
6720  */
6721   gl_vi_command_mode(gl);
6722 /*
6723  * Forget any previous recall session.
6724  */
6725   gl->preload_id = 0;
6726 /*
6727  * Record the key sequence number of this search action.
6728  */
6729   gl->last_search = gl->keyseq_count;
6730 /*
6731  * Recall the next oldest line in the history list.
6732  */
6733   if(_glh_current_line(gl->glh, gl->line, gl->linelen+1) == NULL)
6734     return 0;
6735 /*
6736  * Accomodate the new contents of gl->line[].
6737  */
6738   gl_update_buffer(gl);
6739 /*
6740  * Arrange to have the cursor placed at the end of the new line.
6741  */
6742   gl->buff_curpos = gl->ntotal;
6743 /*
6744  * Erase and display the new line.
6745  */
6746   gl_queue_redisplay(gl);
6747   return 0;
6748 }
6749 
6750 /*.......................................................................
6751  * This action function is treated specially, in that its count argument
6752  * is set to the end keystroke of the keysequence that activated it.
6753  * It accumulates a numeric argument, adding one digit on each call in
6754  * which the last keystroke was a numeric digit.
6755  */
6756 static KT_KEY_FN(gl_digit_argument)
6757 {
6758 /*
6759  * Was the last keystroke a digit?
6760  */
6761   int is_digit = isdigit((int)(unsigned char) count);
6762 /*
6763  * In vi command mode, a lone '0' means goto-start-of-line.
6764  */
6765   if(gl->vi.command && gl->number < 0 && count == '0')
6766     return gl_beginning_of_line(gl, count, NULL);
6767 /*
6768  * Are we starting to accumulate a new number?
6769  */
6770   if(gl->number < 0 || !is_digit)
6771     gl->number = 0;
6772 /*
6773  * Was the last keystroke a digit?
6774  */
6775   if(is_digit) {
6776 /*
6777  * Read the numeric value of the digit, without assuming ASCII.
6778  */
6779     int n;
6780     char s[2]; s[0] = count; s[1] = '\0';
6781     n = atoi(s);
6782 /*
6783  * Append the new digit.
6784  */
6785     gl->number = gl->number * 10 + n;
6786   };
6787   return 0;
6788 }
6789 
6790 /*.......................................................................
6791  * The newline action function sets gl->endline to tell
6792  * gl_get_input_line() that the line is now complete.
6793  */
6794 static KT_KEY_FN(gl_newline)
6795 {
6796   GlhLineID id;    /* The last history line recalled while entering this line */
6797 /*
6798  * Flag the line as ended.
6799  */
6800   gl->endline = 1;
6801 /*
6802  * Record the next position in the history buffer, for potential
6803  * recall by an action function on the next call to gl_get_line().
6804  */
6805   id = _glh_line_id(gl->glh, 1);
6806   if(id)
6807     gl->preload_id = id;
6808   return 0;
6809 }
6810 
6811 /*.......................................................................
6812  * The 'repeat' action function sets gl->endline to tell
6813  * gl_get_input_line() that the line is now complete, and records the
6814  * ID of the next history line in gl->preload_id so that the next call
6815  * to gl_get_input_line() will preload the line with that history line.
6816  */
6817 static KT_KEY_FN(gl_repeat_history)
6818 {
6819   gl->endline = 1;
6820   gl->preload_id = _glh_line_id(gl->glh, 1);
6821   gl->preload_history = 1;
6822   return 0;
6823 }
6824 
6825 /*.......................................................................
6826  * Flush unwritten characters to the terminal.
6827  *
6828  * Input:
6829  *  gl     GetLine *  The getline resource object.
6830  * Output:
6831  *  return     int    0 - OK.
6832  *                    1 - Either an error occured, or the output
6833  *                        blocked and non-blocking I/O is being used.
6834  *                        See gl->rtn_status for details.
6835  */
6836 static int gl_flush_output(GetLine *gl)
6837 {
6838 /*
6839  * Record the fact that we are about to write to the terminal.
6840  */
6841   gl->pending_io = GLP_WRITE;
6842 /*
6843  * Attempt to flush the output to the terminal.
6844  */
6845   errno = 0;
6846   switch(_glq_flush_queue(gl->cq, gl->flush_fn, gl)) {
6847   case GLQ_FLUSH_DONE:
6848     return gl->redisplay && !gl->postpone && gl_redisplay(gl, 1, NULL);
6849     break;
6850   case GLQ_FLUSH_AGAIN:      /* Output blocked */
6851     gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO);
6852     return 1;
6853     break;
6854   default:                   /* Abort the line if an error occurs */
6855     gl_record_status(gl, errno==EINTR ? GLR_SIGNAL : GLR_ERROR, errno);
6856     return 1;
6857     break;
6858   };
6859 }
6860 
6861 /*.......................................................................
6862  * This is the callback which _glq_flush_queue() uses to write buffered
6863  * characters to the terminal.
6864  */
6865 static GL_WRITE_FN(gl_flush_terminal)
6866 {
6867   int ndone = 0;    /* The number of characters written so far */
6868 /*
6869  * Get the line-editor resource object.
6870  */
6871   GetLine *gl = (GetLine *) data;
6872 /*
6873  * Transfer the latest array of characters to stdio.
6874  */
6875   while(ndone < n) {
6876     int nnew = write(gl->output_fd, s, n-ndone);
6877 /*
6878  * If the write was successful, add to the recorded number of bytes
6879  * that have now been written.
6880  */
6881     if(nnew > 0) {
6882       ndone += nnew;
6883 /*
6884  * If a signal interrupted the call, restart the write(), since all of
6885  * the signals that gl_get_line() has been told to watch for are
6886  * currently blocked.
6887  */
6888     } else if(errno == EINTR) {
6889       continue;
6890 /*
6891  * If we managed to write something before an I/O error occurred, or
6892  * output blocked before anything was written, report the number of
6893  * bytes that were successfully written before this happened.
6894  */
6895     } else if(ndone > 0
6896 #if defined(EAGAIN)
6897 	      || errno==EAGAIN
6898 #endif
6899 #if defined(EWOULDBLOCK)
6900 	      || errno==EWOULDBLOCK
6901 #endif
6902 	      ) {
6903       return ndone;
6904 
6905 /*
6906  * To get here, an error must have occurred before anything new could
6907  * be written.
6908  */
6909     } else {
6910       return -1;
6911     };
6912   };
6913 /*
6914  * To get here, we must have successfully written the number of
6915  * bytes that was specified.
6916  */
6917   return n;
6918 }
6919 
6920 /*.......................................................................
6921  * Change the style of editing to emulate a given editor.
6922  *
6923  * Input:
6924  *  gl       GetLine *  The getline resource object.
6925  *  editor  GlEditor    The type of editor to emulate.
6926  * Output:
6927  *  return       int    0 - OK.
6928  *                      1 - Error.
6929  */
6930 static int gl_change_editor(GetLine *gl, GlEditor editor)
6931 {
6932 /*
6933  * Install the default key-bindings of the requested editor.
6934  */
6935   switch(editor) {
6936   case GL_EMACS_MODE:
6937     _kt_clear_bindings(gl->bindings, KTB_NORM);
6938     _kt_clear_bindings(gl->bindings, KTB_TERM);
6939     (void) _kt_add_bindings(gl->bindings, KTB_NORM, gl_emacs_bindings,
6940 		   sizeof(gl_emacs_bindings)/sizeof(gl_emacs_bindings[0]));
6941     break;
6942   case GL_VI_MODE:
6943     _kt_clear_bindings(gl->bindings, KTB_NORM);
6944     _kt_clear_bindings(gl->bindings, KTB_TERM);
6945     (void) _kt_add_bindings(gl->bindings, KTB_NORM, gl_vi_bindings,
6946 			    sizeof(gl_vi_bindings)/sizeof(gl_vi_bindings[0]));
6947     break;
6948   case GL_NO_EDITOR:
6949     break;
6950   default:
6951     _err_record_msg(gl->err, "Unknown editor", END_ERR_MSG);
6952     errno = EINVAL;
6953     return 1;
6954   };
6955 /*
6956  * Record the new editing mode.
6957  */
6958   gl->editor = editor;
6959   gl->vi.command = 0;     /* Start in input mode */
6960   gl->insert_curpos = 0;
6961 /*
6962  * Reinstate terminal-specific bindings.
6963  */
6964   if(gl->editor != GL_NO_EDITOR && gl->input_fp)
6965     (void) gl_bind_terminal_keys(gl);
6966   return 0;
6967 }
6968 
6969 /*.......................................................................
6970  * This is an action function that switches to editing using emacs bindings
6971  */
6972 static KT_KEY_FN(gl_emacs_editing_mode)
6973 {
6974   return gl_change_editor(gl, GL_EMACS_MODE);
6975 }
6976 
6977 /*.......................................................................
6978  * This is an action function that switches to editing using vi bindings
6979  */
6980 static KT_KEY_FN(gl_vi_editing_mode)
6981 {
6982   return gl_change_editor(gl, GL_VI_MODE);
6983 }
6984 
6985 /*.......................................................................
6986  * This is the action function that switches to insert mode.
6987  */
6988 static KT_KEY_FN(gl_vi_insert)
6989 {
6990 /*
6991  * If in vi command mode, preserve the current line for potential
6992  * use by vi-undo.
6993  */
6994   gl_save_for_undo(gl);
6995 /*
6996  * Switch to vi insert mode.
6997  */
6998   gl->insert = 1;
6999   gl->vi.command = 0;
7000   gl->insert_curpos = gl->buff_curpos;
7001   return 0;
7002 }
7003 
7004 /*.......................................................................
7005  * This is an action function that switches to overwrite mode.
7006  */
7007 static KT_KEY_FN(gl_vi_overwrite)
7008 {
7009 /*
7010  * If in vi command mode, preserve the current line for potential
7011  * use by vi-undo.
7012  */
7013   gl_save_for_undo(gl);
7014 /*
7015  * Switch to vi overwrite mode.
7016  */
7017   gl->insert = 0;
7018   gl->vi.command = 0;
7019   gl->insert_curpos = gl->buff_curpos;
7020   return 0;
7021 }
7022 
7023 /*.......................................................................
7024  * This action function toggles the case of the character under the
7025  * cursor.
7026  */
7027 static KT_KEY_FN(gl_change_case)
7028 {
7029   int i;
7030 /*
7031  * Keep a record of the current insert mode and the cursor position.
7032  */
7033   int insert = gl->insert;
7034 /*
7035  * If in vi command mode, preserve the current line for potential
7036  * use by vi-undo.
7037  */
7038   gl_save_for_undo(gl);
7039 /*
7040  * We want to overwrite the modified word.
7041  */
7042   gl->insert = 0;
7043 /*
7044  * Toggle the case of 'count' characters.
7045  */
7046   for(i=0; i<count && gl->buff_curpos < gl->ntotal; i++) {
7047     char *cptr = gl->line + gl->buff_curpos++;
7048 /*
7049  * Convert the character to upper case?
7050  */
7051     if(islower((int)(unsigned char) *cptr))
7052       gl_buffer_char(gl, toupper((int) *cptr), cptr - gl->line);
7053     else if(isupper((int)(unsigned char) *cptr))
7054       gl_buffer_char(gl, tolower((int) *cptr), cptr - gl->line);
7055 /*
7056  * Write the possibly modified character back. Note that for non-modified
7057  * characters we want to do this as well, so as to advance the cursor.
7058  */
7059       if(gl_print_char(gl, *cptr, cptr[1]))
7060 	return 1;
7061   };
7062 /*
7063  * Restore the insertion mode.
7064  */
7065   gl->insert = insert;
7066   return gl_place_cursor(gl, gl->buff_curpos);	/* bounds check */
7067 }
7068 
7069 /*.......................................................................
7070  * This is the action function which implements the vi-style action which
7071  * moves the cursor to the start of the line, then switches to insert mode.
7072  */
7073 static KT_KEY_FN(gl_vi_insert_at_bol)
7074 {
7075   gl_save_for_undo(gl);
7076   return gl_beginning_of_line(gl, 0, NULL) ||
7077          gl_vi_insert(gl, 0, NULL);
7078 
7079 }
7080 
7081 /*.......................................................................
7082  * This is the action function which implements the vi-style action which
7083  * moves the cursor to the end of the line, then switches to insert mode
7084  * to allow text to be appended to the line.
7085  */
7086 static KT_KEY_FN(gl_vi_append_at_eol)
7087 {
7088   gl_save_for_undo(gl);
7089   gl->vi.command = 0;	/* Allow cursor at EOL */
7090   return gl_end_of_line(gl, 0, NULL) ||
7091          gl_vi_insert(gl, 0, NULL);
7092 }
7093 
7094 /*.......................................................................
7095  * This is the action function which implements the vi-style action which
7096  * moves the cursor to right one then switches to insert mode, thus
7097  * allowing text to be appended after the next character.
7098  */
7099 static KT_KEY_FN(gl_vi_append)
7100 {
7101   gl_save_for_undo(gl);
7102   gl->vi.command = 0;	/* Allow cursor at EOL */
7103   return gl_cursor_right(gl, 1, NULL) ||
7104          gl_vi_insert(gl, 0, NULL);
7105 }
7106 
7107 /*.......................................................................
7108  * This action function moves the cursor to the column specified by the
7109  * numeric argument. Column indexes start at 1.
7110  */
7111 static KT_KEY_FN(gl_goto_column)
7112 {
7113   return gl_place_cursor(gl, count - 1);
7114 }
7115 
7116 /*.......................................................................
7117  * Starting with the character under the cursor, replace 'count'
7118  * characters with the next character that the user types.
7119  */
7120 static KT_KEY_FN(gl_vi_replace_char)
7121 {
7122   char c;  /* The replacement character */
7123   int i;
7124 /*
7125  * Keep a record of the current insert mode.
7126  */
7127   int insert = gl->insert;
7128 /*
7129  * Get the replacement character.
7130  */
7131   if(gl->vi.repeat.active) {
7132     c = gl->vi.repeat.input_char;
7133   } else {
7134     if(gl_read_terminal(gl, 1, &c))
7135       return 1;
7136     gl->vi.repeat.input_char = c;
7137   };
7138 /*
7139  * Are there 'count' characters to be replaced?
7140  */
7141   if(gl->ntotal - gl->buff_curpos >= count) {
7142 /*
7143  * If in vi command mode, preserve the current line for potential
7144  * use by vi-undo.
7145  */
7146     gl_save_for_undo(gl);
7147 /*
7148  * Temporarily switch to overwrite mode.
7149  */
7150     gl->insert = 0;
7151 /*
7152  * Overwrite the current character plus count-1 subsequent characters
7153  * with the replacement character.
7154  */
7155     for(i=0; i<count; i++)
7156       gl_add_char_to_line(gl, c);
7157 /*
7158  * Restore the original insert/overwrite mode.
7159  */
7160     gl->insert = insert;
7161   };
7162   return gl_place_cursor(gl, gl->buff_curpos);	/* bounds check */
7163 }
7164 
7165 /*.......................................................................
7166  * This is an action function which changes all characters between the
7167  * current cursor position and the end of the line.
7168  */
7169 static KT_KEY_FN(gl_vi_change_rest_of_line)
7170 {
7171   gl_save_for_undo(gl);
7172   gl->vi.command = 0;	/* Allow cursor at EOL */
7173   return gl_kill_line(gl, count, NULL) || gl_vi_insert(gl, 0, NULL);
7174 }
7175 
7176 /*.......................................................................
7177  * This is an action function which changes all characters between the
7178  * start of the line and the current cursor position.
7179  */
7180 static KT_KEY_FN(gl_vi_change_to_bol)
7181 {
7182   return gl_backward_kill_line(gl,count,NULL) || gl_vi_insert(gl,0,NULL);
7183 }
7184 
7185 /*.......................................................................
7186  * This is an action function which deletes the entire contents of the
7187  * current line and switches to insert mode.
7188  */
7189 static KT_KEY_FN(gl_vi_change_line)
7190 {
7191   return gl_delete_line(gl,count,NULL) || gl_vi_insert(gl,0,NULL);
7192 }
7193 
7194 /*.......................................................................
7195  * Starting from the cursor position and looking towards the end of the
7196  * line, copy 'count' characters to the cut buffer.
7197  */
7198 static KT_KEY_FN(gl_forward_copy_char)
7199 {
7200 /*
7201  * Limit the count to the number of characters available.
7202  */
7203   if(gl->buff_curpos + count >= gl->ntotal)
7204     count = gl->ntotal - gl->buff_curpos;
7205   if(count < 0)
7206     count = 0;
7207 /*
7208  * Copy the characters to the cut buffer.
7209  */
7210   memcpy(gl->cutbuf, gl->line + gl->buff_curpos, count);
7211   gl->cutbuf[count] = '\0';
7212   return 0;
7213 }
7214 
7215 /*.......................................................................
7216  * Starting from the character before the cursor position and looking
7217  * backwards towards the start of the line, copy 'count' characters to
7218  * the cut buffer.
7219  */
7220 static KT_KEY_FN(gl_backward_copy_char)
7221 {
7222 /*
7223  * Limit the count to the number of characters available.
7224  */
7225   if(count > gl->buff_curpos)
7226     count = gl->buff_curpos;
7227   if(count < 0)
7228     count = 0;
7229   gl_place_cursor(gl, gl->buff_curpos - count);
7230 /*
7231  * Copy the characters to the cut buffer.
7232  */
7233   memcpy(gl->cutbuf, gl->line + gl->buff_curpos, count);
7234   gl->cutbuf[count] = '\0';
7235   return 0;
7236 }
7237 
7238 /*.......................................................................
7239  * Starting from the cursor position copy to the specified column into the
7240  * cut buffer.
7241  */
7242 static KT_KEY_FN(gl_copy_to_column)
7243 {
7244   if (--count >= gl->buff_curpos)
7245     return gl_forward_copy_char(gl, count - gl->buff_curpos, NULL);
7246   else
7247     return gl_backward_copy_char(gl, gl->buff_curpos - count, NULL);
7248 }
7249 
7250 /*.......................................................................
7251  * Starting from the cursor position copy characters up to a matching
7252  * parenthesis into the cut buffer.
7253  */
7254 static KT_KEY_FN(gl_copy_to_parenthesis)
7255 {
7256   int curpos = gl_index_of_matching_paren(gl);
7257   if(curpos >= 0) {
7258     gl_save_for_undo(gl);
7259     if(curpos >= gl->buff_curpos)
7260       return gl_forward_copy_char(gl, curpos - gl->buff_curpos + 1, NULL);
7261     else
7262       return gl_backward_copy_char(gl, ++gl->buff_curpos - curpos + 1, NULL);
7263   };
7264   return 0;
7265 }
7266 
7267 /*.......................................................................
7268  * Starting from the cursor position copy the rest of the line into the
7269  * cut buffer.
7270  */
7271 static KT_KEY_FN(gl_copy_rest_of_line)
7272 {
7273 /*
7274  * Copy the characters to the cut buffer.
7275  */
7276   memcpy(gl->cutbuf, gl->line + gl->buff_curpos, gl->ntotal - gl->buff_curpos);
7277   gl->cutbuf[gl->ntotal - gl->buff_curpos] = '\0';
7278   return 0;
7279 }
7280 
7281 /*.......................................................................
7282  * Copy from the beginning of the line to the cursor position into the
7283  * cut buffer.
7284  */
7285 static KT_KEY_FN(gl_copy_to_bol)
7286 {
7287 /*
7288  * Copy the characters to the cut buffer.
7289  */
7290   memcpy(gl->cutbuf, gl->line, gl->buff_curpos);
7291   gl->cutbuf[gl->buff_curpos] = '\0';
7292   gl_place_cursor(gl, 0);
7293   return 0;
7294 }
7295 
7296 /*.......................................................................
7297  * Copy the entire line into the cut buffer.
7298  */
7299 static KT_KEY_FN(gl_copy_line)
7300 {
7301 /*
7302  * Copy the characters to the cut buffer.
7303  */
7304   memcpy(gl->cutbuf, gl->line, gl->ntotal);
7305   gl->cutbuf[gl->ntotal] = '\0';
7306   return 0;
7307 }
7308 
7309 /*.......................................................................
7310  * Search forwards for the next character that the user enters.
7311  */
7312 static KT_KEY_FN(gl_forward_find_char)
7313 {
7314   int pos = gl_find_char(gl, count, 1, 1, '\0');
7315   return pos >= 0 && gl_place_cursor(gl, pos);
7316 }
7317 
7318 /*.......................................................................
7319  * Search backwards for the next character that the user enters.
7320  */
7321 static KT_KEY_FN(gl_backward_find_char)
7322 {
7323   int pos = gl_find_char(gl, count, 0, 1, '\0');
7324   return pos >= 0 && gl_place_cursor(gl, pos);
7325 }
7326 
7327 /*.......................................................................
7328  * Search forwards for the next character that the user enters. Move up to,
7329  * but not onto, the found character.
7330  */
7331 static KT_KEY_FN(gl_forward_to_char)
7332 {
7333   int pos = gl_find_char(gl, count, 1, 0, '\0');
7334   return pos >= 0 && gl_place_cursor(gl, pos);
7335 }
7336 
7337 /*.......................................................................
7338  * Search backwards for the next character that the user enters. Move back to,
7339  * but not onto, the found character.
7340  */
7341 static KT_KEY_FN(gl_backward_to_char)
7342 {
7343   int pos = gl_find_char(gl, count, 0, 0, '\0');
7344   return pos >= 0 && gl_place_cursor(gl, pos);
7345 }
7346 
7347 /*.......................................................................
7348  * Searching in a given direction, return the index of a given (or
7349  * read) character in the input line, or the character that precedes
7350  * it in the specified search direction. Return -1 if not found.
7351  *
7352  * Input:
7353  *  gl       GetLine *  The getline resource object.
7354  *  count        int    The number of times to search.
7355  *  forward      int    True if searching forward.
7356  *  onto         int    True if the search should end on top of the
7357  *                      character, false if the search should stop
7358  *                      one character before the character in the
7359  *                      specified search direction.
7360  *  c           char    The character to be sought, or '\0' if the
7361  *                      character should be read from the user.
7362  * Output:
7363  *  return       int    The index of the character in gl->line[], or
7364  *                      -1 if not found.
7365  */
7366 static int gl_find_char(GetLine *gl, int count, int forward, int onto, char c)
7367 {
7368   int pos;     /* The index reached in searching the input line */
7369   int i;
7370 /*
7371  * Get a character from the user?
7372  */
7373   if(!c) {
7374 /*
7375  * If we are in the process of repeating a previous change command, substitute
7376  * the last find character.
7377  */
7378     if(gl->vi.repeat.active) {
7379       c = gl->vi.find_char;
7380     } else {
7381       if(gl_read_terminal(gl, 1, &c))
7382 	return -1;
7383 /*
7384  * Record the details of the new search, for use by repeat finds.
7385  */
7386       gl->vi.find_forward = forward;
7387       gl->vi.find_onto = onto;
7388       gl->vi.find_char = c;
7389     };
7390   };
7391 /*
7392  * Which direction should we search?
7393  */
7394   if(forward) {
7395 /*
7396  * Search forwards 'count' times for the character, starting with the
7397  * character that follows the cursor.
7398  */
7399     for(i=0, pos=gl->buff_curpos; i<count && pos < gl->ntotal; i++) {
7400 /*
7401  * Advance past the last match (or past the current cursor position
7402  * on the first search).
7403  */
7404       pos++;
7405 /*
7406  * Search for the next instance of c.
7407  */
7408       for( ; pos<gl->ntotal && c!=gl->line[pos]; pos++)
7409 	;
7410     };
7411 /*
7412  * If the character was found and we have been requested to return the
7413  * position of the character that precedes the desired character, then
7414  * we have gone one character too far.
7415  */
7416     if(!onto && pos<gl->ntotal)
7417       pos--;
7418   } else {
7419 /*
7420  * Search backwards 'count' times for the character, starting with the
7421  * character that precedes the cursor.
7422  */
7423     for(i=0, pos=gl->buff_curpos; i<count && pos >= gl->insert_curpos; i++) {
7424 /*
7425  * Step back one from the last match (or from the current cursor
7426  * position on the first search).
7427  */
7428       pos--;
7429 /*
7430  * Search for the next instance of c.
7431  */
7432       for( ; pos>=gl->insert_curpos && c!=gl->line[pos]; pos--)
7433 	;
7434     };
7435 /*
7436  * If the character was found and we have been requested to return the
7437  * position of the character that precedes the desired character, then
7438  * we have gone one character too far.
7439  */
7440     if(!onto && pos>=gl->insert_curpos)
7441       pos++;
7442   };
7443 /*
7444  * If found, return the cursor position of the count'th match.
7445  * Otherwise ring the terminal bell.
7446  */
7447   if(pos >= gl->insert_curpos && pos < gl->ntotal) {
7448     return pos;
7449   } else {
7450     (void) gl_ring_bell(gl, 1, NULL);
7451     return -1;
7452   }
7453 }
7454 
7455 /*.......................................................................
7456  * Repeat the last character search in the same direction as the last
7457  * search.
7458  */
7459 static KT_KEY_FN(gl_repeat_find_char)
7460 {
7461   int pos = gl->vi.find_char ?
7462     gl_find_char(gl, count, gl->vi.find_forward, gl->vi.find_onto,
7463 		 gl->vi.find_char) : -1;
7464   return pos >= 0 && gl_place_cursor(gl, pos);
7465 }
7466 
7467 /*.......................................................................
7468  * Repeat the last character search in the opposite direction as the last
7469  * search.
7470  */
7471 static KT_KEY_FN(gl_invert_refind_char)
7472 {
7473   int pos = gl->vi.find_char ?
7474     gl_find_char(gl, count, !gl->vi.find_forward, gl->vi.find_onto,
7475 		 gl->vi.find_char) : -1;
7476   return pos >= 0 && gl_place_cursor(gl, pos);
7477 }
7478 
7479 /*.......................................................................
7480  * Search forward from the current position of the cursor for 'count'
7481  * word endings, returning the index of the last one found, or the end of
7482  * the line if there were less than 'count' words.
7483  *
7484  * Input:
7485  *  gl       GetLine *  The getline resource object.
7486  *  n            int    The number of word boundaries to search for.
7487  * Output:
7488  *  return       int    The buffer index of the located position.
7489  */
7490 static int gl_nth_word_end_forward(GetLine *gl, int n)
7491 {
7492   int bufpos;   /* The buffer index being checked. */
7493   int i;
7494 /*
7495  * In order to guarantee forward motion to the next word ending,
7496  * we need to start from one position to the right of the cursor
7497  * position, since this may already be at the end of a word.
7498  */
7499   bufpos = gl->buff_curpos + 1;
7500 /*
7501  * If we are at the end of the line, return the index of the last
7502  * real character on the line. Note that this will be -1 if the line
7503  * is empty.
7504  */
7505   if(bufpos >= gl->ntotal)
7506     return gl->ntotal - 1;
7507 /*
7508  * Search 'n' times, unless the end of the input line is reached first.
7509  */
7510   for(i=0; i<n && bufpos<gl->ntotal; i++) {
7511 /*
7512  * If we are not already within a word, skip to the start of the next word.
7513  */
7514     for( ; bufpos<gl->ntotal && !gl_is_word_char((int)gl->line[bufpos]);
7515 	bufpos++)
7516       ;
7517 /*
7518  * Find the end of the next word.
7519  */
7520     for( ; bufpos<gl->ntotal && gl_is_word_char((int)gl->line[bufpos]);
7521 	bufpos++)
7522       ;
7523   };
7524 /*
7525  * We will have overshot.
7526  */
7527   return bufpos > 0 ? bufpos-1 : bufpos;
7528 }
7529 
7530 /*.......................................................................
7531  * Search forward from the current position of the cursor for 'count'
7532  * word starts, returning the index of the last one found, or the end of
7533  * the line if there were less than 'count' words.
7534  *
7535  * Input:
7536  *  gl       GetLine *  The getline resource object.
7537  *  n            int    The number of word boundaries to search for.
7538  * Output:
7539  *  return       int    The buffer index of the located position.
7540  */
7541 static int gl_nth_word_start_forward(GetLine *gl, int n)
7542 {
7543   int bufpos;   /* The buffer index being checked. */
7544   int i;
7545 /*
7546  * Get the current cursor position.
7547  */
7548   bufpos = gl->buff_curpos;
7549 /*
7550  * Search 'n' times, unless the end of the input line is reached first.
7551  */
7552   for(i=0; i<n && bufpos<gl->ntotal; i++) {
7553 /*
7554  * Find the end of the current word.
7555  */
7556     for( ; bufpos<gl->ntotal && gl_is_word_char((int)gl->line[bufpos]);
7557 	bufpos++)
7558       ;
7559 /*
7560  * Skip to the start of the next word.
7561  */
7562     for( ; bufpos<gl->ntotal && !gl_is_word_char((int)gl->line[bufpos]);
7563 	bufpos++)
7564       ;
7565   };
7566   return bufpos;
7567 }
7568 
7569 /*.......................................................................
7570  * Search backward from the current position of the cursor for 'count'
7571  * word starts, returning the index of the last one found, or the start
7572  * of the line if there were less than 'count' words.
7573  *
7574  * Input:
7575  *  gl       GetLine *  The getline resource object.
7576  *  n            int    The number of word boundaries to search for.
7577  * Output:
7578  *  return       int    The buffer index of the located position.
7579  */
7580 static int gl_nth_word_start_backward(GetLine *gl, int n)
7581 {
7582   int bufpos;   /* The buffer index being checked. */
7583   int i;
7584 /*
7585  * Get the current cursor position.
7586  */
7587   bufpos = gl->buff_curpos;
7588 /*
7589  * Search 'n' times, unless the beginning of the input line (or vi insertion
7590  * point) is reached first.
7591  */
7592   for(i=0; i<n && bufpos > gl->insert_curpos; i++) {
7593 /*
7594  * Starting one character back from the last search, so as not to keep
7595  * settling on the same word-start, search backwards until finding a
7596  * word character.
7597  */
7598     while(--bufpos >= gl->insert_curpos &&
7599           !gl_is_word_char((int)gl->line[bufpos]))
7600       ;
7601 /*
7602  * Find the start of the word.
7603  */
7604     while(--bufpos >= gl->insert_curpos &&
7605           gl_is_word_char((int)gl->line[bufpos]))
7606       ;
7607 /*
7608  * We will have gone one character too far.
7609  */
7610     bufpos++;
7611   };
7612   return bufpos >= gl->insert_curpos ? bufpos : gl->insert_curpos;
7613 }
7614 
7615 /*.......................................................................
7616  * Copy one or more words into the cut buffer without moving the cursor
7617  * or deleting text.
7618  */
7619 static KT_KEY_FN(gl_forward_copy_word)
7620 {
7621 /*
7622  * Find the location of the count'th start or end of a word
7623  * after the cursor, depending on whether in emacs or vi mode.
7624  */
7625   int next = gl->editor == GL_EMACS_MODE ?
7626     gl_nth_word_end_forward(gl, count) :
7627     gl_nth_word_start_forward(gl, count);
7628 /*
7629  * How many characters are to be copied into the cut buffer?
7630  */
7631   int n = next - gl->buff_curpos;
7632 /*
7633  * Copy the specified segment and terminate the string.
7634  */
7635   memcpy(gl->cutbuf, gl->line + gl->buff_curpos, n);
7636   gl->cutbuf[n] = '\0';
7637   return 0;
7638 }
7639 
7640 /*.......................................................................
7641  * Copy one or more words preceding the cursor into the cut buffer,
7642  * without moving the cursor or deleting text.
7643  */
7644 static KT_KEY_FN(gl_backward_copy_word)
7645 {
7646 /*
7647  * Find the location of the count'th start of word before the cursor.
7648  */
7649   int next = gl_nth_word_start_backward(gl, count);
7650 /*
7651  * How many characters are to be copied into the cut buffer?
7652  */
7653   int n = gl->buff_curpos - next;
7654   gl_place_cursor(gl, next);
7655 /*
7656  * Copy the specified segment and terminate the string.
7657  */
7658   memcpy(gl->cutbuf, gl->line + next, n);
7659   gl->cutbuf[n] = '\0';
7660   return 0;
7661 }
7662 
7663 /*.......................................................................
7664  * Copy the characters between the cursor and the count'th instance of
7665  * a specified character in the input line, into the cut buffer.
7666  *
7667  * Input:
7668  *  gl       GetLine *  The getline resource object.
7669  *  count        int    The number of times to search.
7670  *  c           char    The character to be searched for, or '\0' if
7671  *                      the character should be read from the user.
7672  *  forward      int    True if searching forward.
7673  *  onto         int    True if the search should end on top of the
7674  *                      character, false if the search should stop
7675  *                      one character before the character in the
7676  *                      specified search direction.
7677  * Output:
7678  *  return       int    0 - OK.
7679  *                      1 - Error.
7680  *
7681  */
7682 static int gl_copy_find(GetLine *gl, int count, char c, int forward, int onto)
7683 {
7684   int n;  /* The number of characters in the cut buffer */
7685 /*
7686  * Search for the character, and abort the operation if not found.
7687  */
7688   int pos = gl_find_char(gl, count, forward, onto, c);
7689   if(pos < 0)
7690     return 0;
7691 /*
7692  * Copy the specified segment.
7693  */
7694   if(forward) {
7695     n = pos + 1 - gl->buff_curpos;
7696     memcpy(gl->cutbuf, gl->line + gl->buff_curpos, n);
7697   } else {
7698     n = gl->buff_curpos - pos;
7699     memcpy(gl->cutbuf, gl->line + pos, n);
7700     if(gl->editor == GL_VI_MODE)
7701       gl_place_cursor(gl, pos);
7702   }
7703 /*
7704  * Terminate the copy.
7705  */
7706   gl->cutbuf[n] = '\0';
7707   return 0;
7708 }
7709 
7710 /*.......................................................................
7711  * Copy a section up to and including a specified character into the cut
7712  * buffer without moving the cursor or deleting text.
7713  */
7714 static KT_KEY_FN(gl_forward_copy_find)
7715 {
7716   return gl_copy_find(gl, count, '\0', 1, 1);
7717 }
7718 
7719 /*.......................................................................
7720  * Copy a section back to and including a specified character into the cut
7721  * buffer without moving the cursor or deleting text.
7722  */
7723 static KT_KEY_FN(gl_backward_copy_find)
7724 {
7725   return gl_copy_find(gl, count, '\0', 0, 1);
7726 }
7727 
7728 /*.......................................................................
7729  * Copy a section up to and not including a specified character into the cut
7730  * buffer without moving the cursor or deleting text.
7731  */
7732 static KT_KEY_FN(gl_forward_copy_to)
7733 {
7734   return gl_copy_find(gl, count, '\0', 1, 0);
7735 }
7736 
7737 /*.......................................................................
7738  * Copy a section back to and not including a specified character into the cut
7739  * buffer without moving the cursor or deleting text.
7740  */
7741 static KT_KEY_FN(gl_backward_copy_to)
7742 {
7743   return gl_copy_find(gl, count, '\0', 0, 0);
7744 }
7745 
7746 /*.......................................................................
7747  * Copy to a character specified in a previous search into the cut
7748  * buffer without moving the cursor or deleting text.
7749  */
7750 static KT_KEY_FN(gl_copy_refind)
7751 {
7752   return gl_copy_find(gl, count, gl->vi.find_char, gl->vi.find_forward,
7753 		      gl->vi.find_onto);
7754 }
7755 
7756 /*.......................................................................
7757  * Copy to a character specified in a previous search, but in the opposite
7758  * direction, into the cut buffer without moving the cursor or deleting text.
7759  */
7760 static KT_KEY_FN(gl_copy_invert_refind)
7761 {
7762   return gl_copy_find(gl, count, gl->vi.find_char, !gl->vi.find_forward,
7763 		      gl->vi.find_onto);
7764 }
7765 
7766 /*.......................................................................
7767  * Set the position of the cursor in the line input buffer and the
7768  * terminal.
7769  *
7770  * Input:
7771  *  gl       GetLine *  The getline resource object.
7772  *  buff_curpos  int    The new buffer cursor position.
7773  * Output:
7774  *  return       int    0 - OK.
7775  *                      1 - Error.
7776  */
7777 static int gl_place_cursor(GetLine *gl, int buff_curpos)
7778 {
7779 /*
7780  * Don't allow the cursor position to go out of the bounds of the input
7781  * line.
7782  */
7783   if(buff_curpos >= gl->ntotal)
7784     buff_curpos = gl->vi.command ? gl->ntotal-1 : gl->ntotal;
7785   if(buff_curpos < 0)
7786     buff_curpos = 0;
7787 /*
7788  * Record the new buffer position.
7789  */
7790   gl->buff_curpos = buff_curpos;
7791 /*
7792  * Move the terminal cursor to the corresponding character.
7793  */
7794   return gl_set_term_curpos(gl, gl->prompt_len +
7795     gl_displayed_string_width(gl, gl->line, buff_curpos, gl->prompt_len));
7796 }
7797 
7798 /*.......................................................................
7799  * In vi command mode, this function saves the current line to the
7800  * historical buffer needed by the undo command. In emacs mode it does
7801  * nothing. In order to allow action functions to call other action
7802  * functions, gl_interpret_char() sets gl->vi.undo.saved to 0 before
7803  * invoking an action, and thereafter once any call to this function
7804  * has set it to 1, further calls are ignored.
7805  *
7806  * Input:
7807  *  gl       GetLine *  The getline resource object.
7808  */
7809 static void gl_save_for_undo(GetLine *gl)
7810 {
7811   if(gl->vi.command && !gl->vi.undo.saved) {
7812     strlcpy(gl->vi.undo.line, gl->line, gl->linelen);
7813     gl->vi.undo.buff_curpos = gl->buff_curpos;
7814     gl->vi.undo.ntotal = gl->ntotal;
7815     gl->vi.undo.saved = 1;
7816   };
7817   if(gl->vi.command && !gl->vi.repeat.saved &&
7818      gl->current_action.fn != gl_vi_repeat_change) {
7819     gl->vi.repeat.action = gl->current_action;
7820     gl->vi.repeat.count = gl->current_count;
7821     gl->vi.repeat.saved = 1;
7822   };
7823   return;
7824 }
7825 
7826 /*.......................................................................
7827  * In vi mode, restore the line to the way it was before the last command
7828  * mode operation, storing the current line in the buffer so that the
7829  * undo operation itself can subsequently be undone.
7830  */
7831 static KT_KEY_FN(gl_vi_undo)
7832 {
7833 /*
7834  * Get pointers into the two lines.
7835  */
7836   char *undo_ptr = gl->vi.undo.line;
7837   char *line_ptr = gl->line;
7838 /*
7839  * Swap the characters of the two buffers up to the length of the shortest
7840  * line.
7841  */
7842   while(*undo_ptr && *line_ptr) {
7843     char c = *undo_ptr;
7844     *undo_ptr++ = *line_ptr;
7845     *line_ptr++ = c;
7846   };
7847 /*
7848  * Copy the rest directly.
7849  */
7850   if(gl->ntotal > gl->vi.undo.ntotal) {
7851     strlcpy(undo_ptr, line_ptr, gl->linelen);
7852     *line_ptr = '\0';
7853   } else {
7854     strlcpy(line_ptr, undo_ptr, gl->linelen);
7855     *undo_ptr = '\0';
7856   };
7857 /*
7858  * Record the length of the stored string.
7859  */
7860   gl->vi.undo.ntotal = gl->ntotal;
7861 /*
7862  * Accomodate the new contents of gl->line[].
7863  */
7864   gl_update_buffer(gl);
7865 /*
7866  * Set both cursor positions to the leftmost of the saved and current
7867  * cursor positions to emulate what vi does.
7868  */
7869   if(gl->buff_curpos < gl->vi.undo.buff_curpos)
7870     gl->vi.undo.buff_curpos = gl->buff_curpos;
7871   else
7872     gl->buff_curpos = gl->vi.undo.buff_curpos;
7873 /*
7874  * Since we have bipassed calling gl_save_for_undo(), record repeat
7875  * information inline.
7876  */
7877   gl->vi.repeat.action.fn = gl_vi_undo;
7878   gl->vi.repeat.action.data = NULL;
7879   gl->vi.repeat.count = 1;
7880 /*
7881  * Display the restored line.
7882  */
7883   gl_queue_redisplay(gl);
7884   return 0;
7885 }
7886 
7887 /*.......................................................................
7888  * Delete the following word and leave the user in vi insert mode.
7889  */
7890 static KT_KEY_FN(gl_vi_forward_change_word)
7891 {
7892   gl_save_for_undo(gl);
7893   gl->vi.command = 0;	/* Allow cursor at EOL */
7894   return gl_forward_delete_word(gl, count, NULL) || gl_vi_insert(gl, 0, NULL);
7895 }
7896 
7897 /*.......................................................................
7898  * Delete the preceding word and leave the user in vi insert mode.
7899  */
7900 static KT_KEY_FN(gl_vi_backward_change_word)
7901 {
7902   return gl_backward_delete_word(gl, count, NULL) || gl_vi_insert(gl, 0, NULL);
7903 }
7904 
7905 /*.......................................................................
7906  * Delete the following section and leave the user in vi insert mode.
7907  */
7908 static KT_KEY_FN(gl_vi_forward_change_find)
7909 {
7910   return gl_delete_find(gl, count, '\0', 1, 1, 1);
7911 }
7912 
7913 /*.......................................................................
7914  * Delete the preceding section and leave the user in vi insert mode.
7915  */
7916 static KT_KEY_FN(gl_vi_backward_change_find)
7917 {
7918   return gl_delete_find(gl, count, '\0', 0, 1, 1);
7919 }
7920 
7921 /*.......................................................................
7922  * Delete the following section and leave the user in vi insert mode.
7923  */
7924 static KT_KEY_FN(gl_vi_forward_change_to)
7925 {
7926   return gl_delete_find(gl, count, '\0', 1, 0, 1);
7927 }
7928 
7929 /*.......................................................................
7930  * Delete the preceding section and leave the user in vi insert mode.
7931  */
7932 static KT_KEY_FN(gl_vi_backward_change_to)
7933 {
7934   return gl_delete_find(gl, count, '\0', 0, 0, 1);
7935 }
7936 
7937 /*.......................................................................
7938  * Delete to a character specified by a previous search and leave the user
7939  * in vi insert mode.
7940  */
7941 static KT_KEY_FN(gl_vi_change_refind)
7942 {
7943   return gl_delete_find(gl, count, gl->vi.find_char, gl->vi.find_forward,
7944 			gl->vi.find_onto, 1);
7945 }
7946 
7947 /*.......................................................................
7948  * Delete to a character specified by a previous search, but in the opposite
7949  * direction, and leave the user in vi insert mode.
7950  */
7951 static KT_KEY_FN(gl_vi_change_invert_refind)
7952 {
7953   return gl_delete_find(gl, count, gl->vi.find_char, !gl->vi.find_forward,
7954 			gl->vi.find_onto, 1);
7955 }
7956 
7957 /*.......................................................................
7958  * Delete the following character and leave the user in vi insert mode.
7959  */
7960 static KT_KEY_FN(gl_vi_forward_change_char)
7961 {
7962   gl_save_for_undo(gl);
7963   gl->vi.command = 0;	/* Allow cursor at EOL */
7964   return gl_delete_chars(gl, count, 1) || gl_vi_insert(gl, 0, NULL);
7965 }
7966 
7967 /*.......................................................................
7968  * Delete the preceding character and leave the user in vi insert mode.
7969  */
7970 static KT_KEY_FN(gl_vi_backward_change_char)
7971 {
7972   return gl_backward_delete_char(gl, count, NULL) || gl_vi_insert(gl, 0, NULL);
7973 }
7974 
7975 /*.......................................................................
7976  * Starting from the cursor position change characters to the specified column.
7977  */
7978 static KT_KEY_FN(gl_vi_change_to_column)
7979 {
7980   if (--count >= gl->buff_curpos)
7981     return gl_vi_forward_change_char(gl, count - gl->buff_curpos, NULL);
7982   else
7983     return gl_vi_backward_change_char(gl, gl->buff_curpos - count, NULL);
7984 }
7985 
7986 /*.......................................................................
7987  * Starting from the cursor position change characters to a matching
7988  * parenthesis.
7989  */
7990 static KT_KEY_FN(gl_vi_change_to_parenthesis)
7991 {
7992   int curpos = gl_index_of_matching_paren(gl);
7993   if(curpos >= 0) {
7994     gl_save_for_undo(gl);
7995     if(curpos >= gl->buff_curpos)
7996       return gl_vi_forward_change_char(gl, curpos - gl->buff_curpos + 1, NULL);
7997     else
7998       return gl_vi_backward_change_char(gl, ++gl->buff_curpos - curpos + 1,
7999 					NULL);
8000   };
8001   return 0;
8002 }
8003 
8004 /*.......................................................................
8005  * If in vi mode, switch to vi command mode.
8006  *
8007  * Input:
8008  *  gl       GetLine *  The getline resource object.
8009  */
8010 static void gl_vi_command_mode(GetLine *gl)
8011 {
8012   if(gl->editor == GL_VI_MODE && !gl->vi.command) {
8013     gl->insert = 1;
8014     gl->vi.command = 1;
8015     gl->vi.repeat.input_curpos = gl->insert_curpos;
8016     gl->vi.repeat.command_curpos = gl->buff_curpos;
8017     gl->insert_curpos = 0;	 /* unrestrict left motion boundary */
8018     gl_cursor_left(gl, 1, NULL); /* Vi moves 1 left on entering command mode */
8019   };
8020 }
8021 
8022 /*.......................................................................
8023  * This is an action function which rings the terminal bell.
8024  */
8025 static KT_KEY_FN(gl_ring_bell)
8026 {
8027   return gl->silence_bell ? 0 :
8028     gl_print_control_sequence(gl, 1, gl->sound_bell);
8029 }
8030 
8031 /*.......................................................................
8032  * This is the action function which implements the vi-repeat-change
8033  * action.
8034  */
8035 static KT_KEY_FN(gl_vi_repeat_change)
8036 {
8037   int status;   /* The return status of the repeated action function */
8038   int i;
8039 /*
8040  * Nothing to repeat?
8041  */
8042   if(!gl->vi.repeat.action.fn)
8043     return gl_ring_bell(gl, 1, NULL);
8044 /*
8045  * Provide a way for action functions to know whether they are being
8046  * called by us.
8047  */
8048   gl->vi.repeat.active = 1;
8049 /*
8050  * Re-run the recorded function.
8051  */
8052   status = gl->vi.repeat.action.fn(gl, gl->vi.repeat.count,
8053 				   gl->vi.repeat.action.data);
8054 /*
8055  * Mark the repeat as completed.
8056  */
8057   gl->vi.repeat.active = 0;
8058 /*
8059  * Is we are repeating a function that has just switched to input
8060  * mode to allow the user to type, re-enter the text that the user
8061  * previously entered.
8062  */
8063   if(status==0 && !gl->vi.command) {
8064 /*
8065  * Make sure that the current line has been saved.
8066  */
8067     gl_save_for_undo(gl);
8068 /*
8069  * Repeat a previous insertion or overwrite?
8070  */
8071     if(gl->vi.repeat.input_curpos >= 0 &&
8072        gl->vi.repeat.input_curpos <= gl->vi.repeat.command_curpos &&
8073        gl->vi.repeat.command_curpos <= gl->vi.undo.ntotal) {
8074 /*
8075  * Using the current line which is saved in the undo buffer, plus
8076  * the range of characters therein, as recorded by gl_vi_command_mode(),
8077  * add the characters that the user previously entered, to the input
8078  * line.
8079  */
8080       for(i=gl->vi.repeat.input_curpos; i<gl->vi.repeat.command_curpos; i++) {
8081 	if(gl_add_char_to_line(gl, gl->vi.undo.line[i]))
8082 	  return 1;
8083       };
8084     };
8085 /*
8086  * Switch back to command mode, now that the insertion has been repeated.
8087  */
8088     gl_vi_command_mode(gl);
8089   };
8090   return status;
8091 }
8092 
8093 /*.......................................................................
8094  * If the cursor is currently over a parenthesis character, return the
8095  * index of its matching parenthesis. If not currently over a parenthesis
8096  * character, return the next close parenthesis character to the right of
8097  * the cursor. If the respective parenthesis character isn't found,
8098  * ring the terminal bell and return -1.
8099  *
8100  * Input:
8101  *  gl       GetLine *  The getline resource object.
8102  * Output:
8103  *  return       int    Either the index of the matching parenthesis,
8104  *                      or -1 if not found.
8105  */
8106 static int gl_index_of_matching_paren(GetLine *gl)
8107 {
8108   int i;
8109 /*
8110  * List the recognized parentheses, and their matches.
8111  */
8112   const char *o_paren = "([{";
8113   const char *c_paren = ")]}";
8114   const char *cptr;
8115 /*
8116  * Get the character that is currently under the cursor.
8117  */
8118   char c = gl->line[gl->buff_curpos];
8119 /*
8120  * If the character under the cursor is an open parenthesis, look forward
8121  * for the matching close parenthesis.
8122  */
8123   if((cptr=strchr(o_paren, c))) {
8124     char match = c_paren[cptr - o_paren];
8125     int matches_needed = 1;
8126     for(i=gl->buff_curpos+1; i<gl->ntotal; i++) {
8127       if(gl->line[i] == c)
8128 	matches_needed++;
8129       else if(gl->line[i] == match && --matches_needed==0)
8130 	return i;
8131     };
8132 /*
8133  * If the character under the cursor is an close parenthesis, look forward
8134  * for the matching open parenthesis.
8135  */
8136   } else if((cptr=strchr(c_paren, c))) {
8137     char match = o_paren[cptr - c_paren];
8138     int matches_needed = 1;
8139     for(i=gl->buff_curpos-1; i>=0; i--) {
8140       if(gl->line[i] == c)
8141 	matches_needed++;
8142       else if(gl->line[i] == match && --matches_needed==0)
8143 	return i;
8144     };
8145 /*
8146  * If not currently over a parenthesis character, search forwards for
8147  * the first close parenthesis (this is what the vi % binding does).
8148  */
8149   } else {
8150     for(i=gl->buff_curpos+1; i<gl->ntotal; i++)
8151       if(strchr(c_paren, gl->line[i]) != NULL)
8152 	return i;
8153   };
8154 /*
8155  * Not found.
8156  */
8157   (void) gl_ring_bell(gl, 1, NULL);
8158   return -1;
8159 }
8160 
8161 /*.......................................................................
8162  * If the cursor is currently over a parenthesis character, this action
8163  * function moves the cursor to its matching parenthesis.
8164  */
8165 static KT_KEY_FN(gl_find_parenthesis)
8166 {
8167   int curpos = gl_index_of_matching_paren(gl);
8168   if(curpos >= 0)
8169     return gl_place_cursor(gl, curpos);
8170   return 0;
8171 }
8172 
8173 /*.......................................................................
8174  * Handle the receipt of the potential start of a new key-sequence from
8175  * the user.
8176  *
8177  * Input:
8178  *  gl      GetLine *   The resource object of this library.
8179  *  first_char char     The first character of the sequence.
8180  * Output:
8181  *  return      int     0 - OK.
8182  *                      1 - Error.
8183  */
8184 static int gl_interpret_char(GetLine *gl, char first_char)
8185 {
8186   char keyseq[GL_KEY_MAX+1]; /* A special key sequence being read */
8187   int nkey=0;                /* The number of characters in the key sequence */
8188   int count;                 /* The repeat count of an action function */
8189   int ret;                   /* The return value of an action function */
8190   int i;
8191 /*
8192  * Get the first character.
8193  */
8194   char c = first_char;
8195 /*
8196  * If editing is disabled, just add newly entered characters to the
8197  * input line buffer, and watch for the end of the line.
8198  */
8199   if(gl->editor == GL_NO_EDITOR) {
8200     gl_discard_chars(gl, 1);
8201     if(gl->ntotal >= gl->linelen)
8202       return 0;
8203     if(c == '\n' || c == '\r')
8204       return gl_newline(gl, 1, NULL);
8205     gl_buffer_char(gl, c, gl->ntotal);
8206     return 0;
8207   };
8208 /*
8209  * If the user is in the process of specifying a repeat count and the
8210  * new character is a digit, increment the repeat count accordingly.
8211  */
8212   if(gl->number >= 0 && isdigit((int)(unsigned char) c)) {
8213     gl_discard_chars(gl, 1);
8214     return gl_digit_argument(gl, c, NULL);
8215 /*
8216  * In vi command mode, all key-sequences entered need to be
8217  * either implicitly or explicitly prefixed with an escape character.
8218  */
8219   } else if(gl->vi.command && c != GL_ESC_CHAR) {
8220     keyseq[nkey++] = GL_ESC_CHAR;
8221 /*
8222  * If the first character of the sequence is a printable character,
8223  * then to avoid confusion with the special "up", "down", "left"
8224  * or "right" cursor key bindings, we need to prefix the
8225  * printable character with a backslash escape before looking it up.
8226  */
8227   } else if(!IS_META_CHAR(c) && !IS_CTRL_CHAR(c)) {
8228     keyseq[nkey++] = '\\';
8229   };
8230 /*
8231  * Compose a potentially multiple key-sequence in gl->keyseq.
8232  */
8233   while(nkey < GL_KEY_MAX) {
8234     KtAction *action; /* An action function */
8235     KeySym *keysym;   /* The symbol-table entry of a key-sequence */
8236     int nsym;         /* The number of ambiguously matching key-sequences */
8237 /*
8238  * If the character is an unprintable meta character, split it
8239  * into two characters, an escape character and the character
8240  * that was modified by the meta key.
8241  */
8242     if(IS_META_CHAR(c)) {
8243       keyseq[nkey++] = GL_ESC_CHAR;
8244       c = META_TO_CHAR(c);
8245       continue;
8246     };
8247 /*
8248  * Append the latest character to the key sequence.
8249  */
8250     keyseq[nkey++] = c;
8251 /*
8252  * When doing vi-style editing, an escape at the beginning of any binding
8253  * switches to command mode.
8254  */
8255     if(keyseq[0] == GL_ESC_CHAR && !gl->vi.command)
8256       gl_vi_command_mode(gl);
8257 /*
8258  * Lookup the key sequence.
8259  */
8260     switch(_kt_lookup_keybinding(gl->bindings, keyseq, nkey, &keysym, &nsym)) {
8261     case KT_EXACT_MATCH:
8262 /*
8263  * Get the matching action function.
8264  */
8265       action = keysym->actions + keysym->binder;
8266 /*
8267  * Get the repeat count, passing the last keystroke if executing the
8268  * digit-argument action.
8269  */
8270       if(action->fn == gl_digit_argument) {
8271 	count = c;
8272       } else {
8273 	count = gl->number >= 0 ? gl->number : 1;
8274       };
8275 /*
8276  * Record the function that is being invoked.
8277  */
8278       gl->current_action = *action;
8279       gl->current_count = count;
8280 /*
8281  * Mark the current line as not yet preserved for use by the vi undo command.
8282  */
8283       gl->vi.undo.saved = 0;
8284       gl->vi.repeat.saved = 0;
8285 /*
8286  * Execute the action function. Note the action function can tell
8287  * whether the provided repeat count was defaulted or specified
8288  * explicitly by looking at whether gl->number is -1 or not. If
8289  * it is negative, then no repeat count was specified by the user.
8290  */
8291       ret = action->fn(gl, count, action->data);
8292 /*
8293  * In server mode, the action will return immediately if it tries to
8294  * read input from the terminal, and no input is currently available.
8295  * If this happens, abort. Note that gl_get_input_line() will rewind
8296  * the read-ahead buffer to allow the next call to redo the function
8297  * from scratch.
8298  */
8299       if(gl->rtn_status == GLR_BLOCKED && gl->pending_io==GLP_READ)
8300 	return 1;
8301 /*
8302  * Discard the now processed characters from the key sequence buffer.
8303  */
8304       gl_discard_chars(gl, gl->nread);
8305 /*
8306  * If the latest action function wasn't a history action, cancel any
8307  * current history search.
8308  */
8309       if(gl->last_search != gl->keyseq_count)
8310 	_glh_cancel_search(gl->glh);
8311 /*
8312  * Reset the repeat count after running action functions.
8313  */
8314       if(action->fn != gl_digit_argument)
8315 	gl->number = -1;
8316       return ret ? 1 : 0;
8317       break;
8318     case KT_AMBIG_MATCH:    /* Ambiguous match - so read the next character */
8319       if(gl_read_terminal(gl, 1, &c))
8320 	return 1;
8321       break;
8322     case KT_NO_MATCH:
8323 /*
8324  * If the first character looked like it might be a prefix of a key-sequence
8325  * but it turned out not to be, ring the bell to tell the user that it
8326  * wasn't recognised.
8327  */
8328       if(keyseq[0] != '\\' && keyseq[0] != '\t') {
8329 	gl_ring_bell(gl, 1, NULL);
8330       } else {
8331 /*
8332  * The user typed a single printable character that doesn't match
8333  * the start of any keysequence, so add it to the line in accordance
8334  * with the current repeat count.
8335  */
8336 	count = gl->number >= 0 ? gl->number : 1;
8337 	for(i=0; i<count; i++)
8338 	  gl_add_char_to_line(gl, first_char);
8339 	gl->number = -1;
8340       };
8341       gl_discard_chars(gl, 1);
8342       _glh_cancel_search(gl->glh);
8343       return 0;
8344       break;
8345     case KT_BAD_MATCH:
8346       gl_ring_bell(gl, 1, NULL);
8347       gl_discard_chars(gl, gl->nread);
8348       _glh_cancel_search(gl->glh);
8349       return 1;
8350       break;
8351     };
8352   };
8353 /*
8354  * If the key sequence was too long to match, ring the bell, then
8355  * discard the first character, so that the next attempt to match a
8356  * key-sequence continues with the next key press. In practice this
8357  * shouldn't happen, since one isn't allowed to bind action functions
8358  * to keysequences that are longer than GL_KEY_MAX.
8359  */
8360   gl_ring_bell(gl, 1, NULL);
8361   gl_discard_chars(gl, 1);
8362   return 0;
8363 }
8364 
8365 /*.......................................................................
8366  * Configure the application and/or user-specific behavior of
8367  * gl_get_line().
8368  *
8369  * Note that calling this function between calling new_GetLine() and
8370  * the first call to gl_get_line(), disables the otherwise automatic
8371  * reading of ~/.teclarc on the first call to gl_get_line().
8372  *
8373  * Input:
8374  *  gl             GetLine *  The resource object of this library.
8375  *  app_string  const char *  Either NULL, or a string containing one
8376  *                            or more .teclarc command lines, separated
8377  *                            by newline characters. This can be used to
8378  *                            establish an application-specific
8379  *                            configuration, without the need for an external
8380  *                            file. This is particularly useful in embedded
8381  *                            environments where there is no filesystem.
8382  *  app_file    const char *  Either NULL, or the pathname of an
8383  *                            application-specific .teclarc file. The
8384  *                            contents of this file, if provided, are
8385  *                            read after the contents of app_string[].
8386  *  user_file   const char *  Either NULL, or the pathname of a
8387  *                            user-specific .teclarc file. Except in
8388  *                            embedded applications, this should
8389  *                            usually be "~/.teclarc".
8390  * Output:
8391  *  return             int    0 - OK.
8392  *                            1 - Bad argument(s).
8393  */
8394 int gl_configure_getline(GetLine *gl, const char *app_string,
8395 			 const char *app_file, const char *user_file)
8396 {
8397   sigset_t oldset; /* The signals that were blocked on entry to this function */
8398   int status;      /* The return status of _gl_configure_getline() */
8399 /*
8400  * Check the arguments.
8401  */
8402   if(!gl) {
8403     errno = EINVAL;
8404     return 1;
8405   };
8406 /*
8407  * Block all signals.
8408  */
8409   if(gl_mask_signals(gl, &oldset))
8410     return 1;
8411 /*
8412  * Execute the private body of the function while signals are blocked.
8413  */
8414   status = _gl_configure_getline(gl, app_string, app_file, user_file);
8415 /*
8416  * Restore the process signal mask.
8417  */
8418   gl_unmask_signals(gl, &oldset);
8419   return status;
8420 }
8421 
8422 /*.......................................................................
8423  * This is the private body of the gl_configure_getline() function. It
8424  * assumes that the caller has checked its arguments and blocked the
8425  * delivery of signals.
8426  */
8427 static int _gl_configure_getline(GetLine *gl, const char *app_string,
8428 				 const char *app_file, const char *user_file)
8429 {
8430 /*
8431  * Mark getline as having been explicitly configured.
8432  */
8433   gl->configured = 1;
8434 /*
8435  * Start by parsing the configuration string, if provided.
8436  */
8437   if(app_string)
8438     (void) _gl_read_config_string(gl, app_string, KTB_NORM);
8439 /*
8440  * Now parse the application-specific configuration file, if provided.
8441  */
8442   if(app_file)
8443     (void) _gl_read_config_file(gl, app_file, KTB_NORM);
8444 /*
8445  * Finally, parse the user-specific configuration file, if provided.
8446  */
8447   if(user_file)
8448     (void) _gl_read_config_file(gl, user_file, KTB_USER);
8449 /*
8450  * Record the names of the configuration files to allow them to
8451  * be re-read if requested at a later time.
8452  */
8453   if(gl_record_string(&gl->app_file, app_file) ||
8454      gl_record_string(&gl->user_file, user_file)) {
8455     errno = ENOMEM;
8456     _err_record_msg(gl->err,
8457 	   "Insufficient memory to record tecla configuration file names",
8458 	   END_ERR_MSG);
8459     return 1;
8460   };
8461   return 0;
8462 }
8463 
8464 /*.......................................................................
8465  * Replace a malloc'd string (or NULL), with another malloc'd copy of
8466  * a string (or NULL).
8467  *
8468  * Input:
8469  *  sptr          char **  On input if *sptr!=NULL, *sptr will be
8470  *                         free'd and *sptr will be set to NULL. Then,
8471  *                         on output, if string!=NULL a malloc'd copy
8472  *                         of this string will be assigned to *sptr.
8473  *  string  const char *   The string to be copied, or NULL to simply
8474  *                         discard any existing string.
8475  * Output:
8476  *  return         int     0 - OK.
8477  *                         1 - Malloc failure (no error message is generated).
8478  */
8479 static int gl_record_string(char **sptr, const char *string)
8480 {
8481 /*
8482  * If the original string is the same string, don't do anything.
8483  */
8484   if(*sptr == string || (*sptr && string && strcmp(*sptr, string)==0))
8485     return 0;
8486 /*
8487  * Discard any existing cached string.
8488  */
8489   if(*sptr) {
8490     free(*sptr);
8491     *sptr = NULL;
8492   };
8493 /*
8494  * Allocate memory for a copy of the specified string.
8495  */
8496   if(string) {
8497     size_t ssz = strlen(string) + 1;
8498     *sptr = (char *) malloc(ssz);
8499     if(!*sptr)
8500       return 1;
8501 /*
8502  * Copy the string.
8503  */
8504     strlcpy(*sptr, string, ssz);
8505   };
8506   return 0;
8507 }
8508 
8509 #ifndef HIDE_FILE_SYSTEM
8510 /*.......................................................................
8511  * Re-read any application-specific and user-specific files previously
8512  * specified via the gl_configure_getline() function.
8513  */
8514 static KT_KEY_FN(gl_read_init_files)
8515 {
8516   return _gl_configure_getline(gl, NULL, gl->app_file, gl->user_file);
8517 }
8518 #endif
8519 
8520 /*.......................................................................
8521  * Save the contents of the history buffer to a given new file.
8522  *
8523  * Input:
8524  *  gl             GetLine *  The resource object of this library.
8525  *  filename    const char *  The name of the new file to write to.
8526  *  comment     const char *  Extra information such as timestamps will
8527  *                            be recorded on a line started with this
8528  *                            string, the idea being that the file can
8529  *                            double as a command file. Specify "" if
8530  *                            you don't care.
8531  *  max_lines          int    The maximum number of lines to save, or -1
8532  *                            to save all of the lines in the history
8533  *                            list.
8534  * Output:
8535  *  return             int     0 - OK.
8536  *                             1 - Error.
8537  */
8538 int gl_save_history(GetLine *gl, const char *filename, const char *comment,
8539 		    int max_lines)
8540 {
8541   sigset_t oldset; /* The signals that were blocked on entry to this function */
8542   int status;      /* The return status of _gl_save_history() */
8543 /*
8544  * Check the arguments.
8545  */
8546   if(!gl || !filename || !comment) {
8547     if(gl)
8548       _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
8549     errno = EINVAL;
8550     return 1;
8551   };
8552 /*
8553  * Block all signals.
8554  */
8555   if(gl_mask_signals(gl, &oldset))
8556     return 1;
8557 /*
8558  * Execute the private body of the function while signals are blocked.
8559  */
8560   status = _gl_save_history(gl, filename, comment, max_lines);
8561 /*
8562  * Restore the process signal mask.
8563  */
8564   gl_unmask_signals(gl, &oldset);
8565   return status;
8566 }
8567 
8568 /*.......................................................................
8569  * This is the private body of the gl_save_history() function. It
8570  * assumes that the caller has checked its arguments and blocked the
8571  * delivery of signals.
8572  */
8573 static int _gl_save_history(GetLine *gl, const char *filename,
8574 			    const char *comment, int max_lines)
8575 {
8576 /*
8577  * If filesystem access is to be excluded, then history files can't
8578  * be written.
8579  */
8580 #ifdef WITHOUT_FILE_SYSTEM
8581   _err_record_msg(gl->err, "Can't save history without filesystem access",
8582 		  END_ERR_MSG);
8583   errno = EINVAL;
8584   return 1;
8585 #else
8586   FileExpansion *expansion; /* The expansion of the filename */
8587 /*
8588  * Expand the filename.
8589  */
8590   expansion = ef_expand_file(gl->ef, filename, -1);
8591   if(!expansion) {
8592     gl_print_info(gl, "Unable to expand ", filename, " (",
8593 		  ef_last_error(gl->ef), ").", GL_END_INFO);
8594     return 1;
8595   };
8596 /*
8597  * Attempt to save to the specified file.
8598  */
8599   if(_glh_save_history(gl->glh, expansion->files[0], comment, max_lines)) {
8600     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
8601     return 1;
8602   };
8603   return 0;
8604 #endif
8605 }
8606 
8607 /*.......................................................................
8608  * Restore the contents of the history buffer from a given new file.
8609  *
8610  * Input:
8611  *  gl             GetLine *  The resource object of this library.
8612  *  filename    const char *  The name of the new file to write to.
8613  *  comment     const char *  This must be the same string that was
8614  *                            passed to gl_save_history() when the file
8615  *                            was written.
8616  * Output:
8617  *  return             int     0 - OK.
8618  *                             1 - Error.
8619  */
8620 int gl_load_history(GetLine *gl, const char *filename, const char *comment)
8621 {
8622   sigset_t oldset; /* The signals that were blocked on entry to this function */
8623   int status;      /* The return status of _gl_load_history() */
8624 /*
8625  * Check the arguments.
8626  */
8627   if(!gl || !filename || !comment) {
8628     if(gl)
8629       _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
8630     errno = EINVAL;
8631     return 1;
8632   };
8633 /*
8634  * Block all signals.
8635  */
8636   if(gl_mask_signals(gl, &oldset))
8637     return 1;
8638 /*
8639  * Execute the private body of the function while signals are blocked.
8640  */
8641   status = _gl_load_history(gl, filename, comment);
8642 /*
8643  * Restore the process signal mask.
8644  */
8645   gl_unmask_signals(gl, &oldset);
8646   return status;
8647 }
8648 
8649 /*.......................................................................
8650  * This is the private body of the gl_load_history() function. It
8651  * assumes that the caller has checked its arguments and blocked the
8652  * delivery of signals.
8653  */
8654 static int _gl_load_history(GetLine *gl, const char *filename,
8655 			    const char *comment)
8656 {
8657 /*
8658  * If filesystem access is to be excluded, then history files can't
8659  * be read.
8660  */
8661 #ifdef WITHOUT_FILE_SYSTEM
8662   _err_record_msg(gl->err, "Can't load history without filesystem access",
8663 		  END_ERR_MSG);
8664   errno = EINVAL;
8665   return 1;
8666 #else
8667   FileExpansion *expansion; /* The expansion of the filename */
8668 /*
8669  * Expand the filename.
8670  */
8671   expansion = ef_expand_file(gl->ef, filename, -1);
8672   if(!expansion) {
8673     gl_print_info(gl, "Unable to expand ", filename, " (",
8674 		  ef_last_error(gl->ef), ").", GL_END_INFO);
8675     return 1;
8676   };
8677 /*
8678  * Attempt to load from the specified file.
8679  */
8680   if(_glh_load_history(gl->glh, expansion->files[0], comment,
8681 		       gl->cutbuf, gl->linelen+1)) {
8682     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
8683     gl->cutbuf[0] = '\0';
8684     return 1;
8685   };
8686   gl->cutbuf[0] = '\0';
8687   return 0;
8688 #endif
8689 }
8690 
8691 /*.......................................................................
8692  * Where possible, register a function and associated data to be called
8693  * whenever a specified event is seen on a file descriptor.
8694  *
8695  * Input:
8696  *  gl            GetLine *  The resource object of the command-line input
8697  *                           module.
8698  *  fd                int    The file descriptor to watch.
8699  *  event       GlFdEvent    The type of activity to watch for.
8700  *  callback  GlFdEventFn *  The function to call when the specified
8701  *                           event occurs. Setting this to 0 removes
8702  *                           any existing callback.
8703  *  data             void *  A pointer to arbitrary data to pass to the
8704  *                           callback function.
8705  * Output:
8706  *  return            int    0 - OK.
8707  *                           1 - Either gl==NULL, or this facility isn't
8708  *                               available on the the host system
8709  *                               (ie. select() isn't available). No
8710  *                               error message is generated in the latter
8711  *                               case.
8712  */
8713 int gl_watch_fd(GetLine *gl, int fd, GlFdEvent event,
8714 		GlFdEventFn *callback, void *data)
8715 {
8716   sigset_t oldset; /* The signals that were blocked on entry to this function */
8717   int status;      /* The return status of _gl_watch_fd() */
8718 /*
8719  * Check the arguments.
8720  */
8721   if(!gl) {
8722     errno = EINVAL;
8723     return 1;
8724   };
8725   if(fd < 0) {
8726     _err_record_msg(gl->err, "Error: fd < 0", END_ERR_MSG);
8727     errno = EINVAL;
8728     return 1;
8729   };
8730 /*
8731  * Block all signals.
8732  */
8733   if(gl_mask_signals(gl, &oldset))
8734     return 1;
8735 /*
8736  * Execute the private body of the function while signals are blocked.
8737  */
8738   status = _gl_watch_fd(gl, fd, event, callback, data);
8739 /*
8740  * Restore the process signal mask.
8741  */
8742   gl_unmask_signals(gl, &oldset);
8743   return status;
8744 }
8745 
8746 /*.......................................................................
8747  * This is the private body of the gl_watch_fd() function. It
8748  * assumes that the caller has checked its arguments and blocked the
8749  * delivery of signals.
8750  */
8751 static int _gl_watch_fd(GetLine *gl, int fd, GlFdEvent event,
8752 			GlFdEventFn *callback, void *data)
8753 #if !defined(HAVE_SELECT)
8754 {return 1;}               /* The facility isn't supported on this system */
8755 #else
8756 {
8757   GlFdNode *prev;  /* The node that precedes 'node' in gl->fd_nodes */
8758   GlFdNode *node;  /* The file-descriptor node being checked */
8759 /*
8760  * Search the list of already registered fd activity nodes for the specified
8761  * file descriptor.
8762  */
8763   for(prev=NULL,node=gl->fd_nodes; node && node->fd != fd;
8764       prev=node, node=node->next)
8765     ;
8766 /*
8767  * Hasn't a node been allocated for this fd yet?
8768  */
8769   if(!node) {
8770 /*
8771  * If there is no callback to record, just ignore the call.
8772  */
8773     if(!callback)
8774       return 0;
8775 /*
8776  * Allocate the new node.
8777  */
8778     node = (GlFdNode *) _new_FreeListNode(gl->fd_node_mem);
8779     if(!node) {
8780       errno = ENOMEM;
8781       _err_record_msg(gl->err, "Insufficient memory", END_ERR_MSG);
8782       return 1;
8783     };
8784 /*
8785  * Prepend the node to the list.
8786  */
8787     node->next = gl->fd_nodes;
8788     gl->fd_nodes = node;
8789 /*
8790  * Initialize the node.
8791  */
8792     node->fd = fd;
8793     node->rd.fn = 0;
8794     node->rd.data = NULL;
8795     node->ur = node->wr = node->rd;
8796   };
8797 /*
8798  * Record the new callback.
8799  */
8800   switch(event) {
8801   case GLFD_READ:
8802     node->rd.fn = callback;
8803     node->rd.data = data;
8804     if(callback)
8805       FD_SET(fd, &gl->rfds);
8806     else
8807       FD_CLR(fd, &gl->rfds);
8808     break;
8809   case GLFD_WRITE:
8810     node->wr.fn = callback;
8811     node->wr.data = data;
8812     if(callback)
8813       FD_SET(fd, &gl->wfds);
8814     else
8815       FD_CLR(fd, &gl->wfds);
8816     break;
8817   case GLFD_URGENT:
8818     node->ur.fn = callback;
8819     node->ur.data = data;
8820     if(callback)
8821       FD_SET(fd, &gl->ufds);
8822     else
8823       FD_CLR(fd, &gl->ufds);
8824     break;
8825   };
8826 /*
8827  * Keep a record of the largest file descriptor being watched.
8828  */
8829   if(fd > gl->max_fd)
8830     gl->max_fd = fd;
8831 /*
8832  * If we are deleting an existing callback, also delete the parent
8833  * activity node if no callbacks are registered to the fd anymore.
8834  */
8835   if(!callback) {
8836     if(!node->rd.fn && !node->wr.fn && !node->ur.fn) {
8837       if(prev)
8838 	prev->next = node->next;
8839       else
8840 	gl->fd_nodes = node->next;
8841       node = (GlFdNode *) _del_FreeListNode(gl->fd_node_mem, node);
8842     };
8843   };
8844   return 0;
8845 }
8846 #endif
8847 
8848 /*.......................................................................
8849  * On systems with the select() system call, the gl_inactivity_timeout()
8850  * function provides the option of setting (or cancelling) an
8851  * inactivity timeout. Inactivity, in this case, refers both to
8852  * terminal input received from the user, and to I/O on any file
8853  * descriptors registered by calls to gl_watch_fd(). If at any time,
8854  * no activity is seen for the requested time period, the specified
8855  * timeout callback function is called. On returning, this callback
8856  * returns a code which tells gl_get_line() what to do next. Note that
8857  * each call to gl_inactivity_timeout() replaces any previously installed
8858  * timeout callback, and that specifying a callback of 0, turns off
8859  * inactivity timing.
8860  *
8861  * Beware that although the timeout argument includes a nano-second
8862  * component, few computer clocks presently have resolutions finer
8863  * than a few milliseconds, so asking for less than a few milliseconds
8864  * is equivalent to zero on a lot of systems.
8865  *
8866  * Input:
8867  *  gl            GetLine *  The resource object of the command-line input
8868  *                           module.
8869  *  callback  GlTimeoutFn *  The function to call when the inactivity
8870  *                           timeout is exceeded. To turn off
8871  *                           inactivity timeouts altogether, send 0.
8872  *  data             void *  A pointer to arbitrary data to pass to the
8873  *                           callback function.
8874  *  sec     unsigned long    The number of whole seconds in the timeout.
8875  *  nsec    unsigned long    The fractional number of seconds in the
8876  *                           timeout, expressed in nano-seconds (see
8877  *                           the caveat above).
8878  * Output:
8879  *  return            int    0 - OK.
8880  *                           1 - Either gl==NULL, or this facility isn't
8881  *                               available on the the host system
8882  *                               (ie. select() isn't available). No
8883  *                               error message is generated in the latter
8884  *                               case.
8885  */
8886 int gl_inactivity_timeout(GetLine *gl, GlTimeoutFn *timeout_fn, void *data,
8887 		   unsigned long sec, unsigned long nsec)
8888 #if !defined(HAVE_SELECT)
8889 {return 1;}               /* The facility isn't supported on this system */
8890 #else
8891 {
8892   sigset_t oldset; /* The signals that were blocked on entry to this function */
8893 /*
8894  * Check the arguments.
8895  */
8896   if(!gl) {
8897     errno = EINVAL;
8898     return 1;
8899   };
8900 /*
8901  * Block all signals.
8902  */
8903   if(gl_mask_signals(gl, &oldset))
8904     return 1;
8905 /*
8906  * Install a new timeout?
8907  */
8908   if(timeout_fn) {
8909     gl->timer.dt.tv_sec = sec;
8910     gl->timer.dt.tv_usec = nsec / 1000;
8911     gl->timer.fn = timeout_fn;
8912     gl->timer.data = data;
8913   } else {
8914     gl->timer.fn = 0;
8915     gl->timer.data = NULL;
8916   };
8917 /*
8918  * Restore the process signal mask.
8919  */
8920   gl_unmask_signals(gl, &oldset);
8921   return 0;
8922 }
8923 #endif
8924 
8925 /*.......................................................................
8926  * When select() is available, this is a private function of
8927  * gl_read_input() which responds to file-descriptor events registered by
8928  * the caller. Note that it assumes that it is being called from within
8929  * gl_read_input()'s sigsetjump() clause.
8930  *
8931  * Input:
8932  *  gl    GetLine *  The resource object of this module.
8933  *  fd        int    The file descriptor to be watched for user input.
8934  * Output:
8935  *  return    int    0 - OK.
8936  *                   1 - An error occurred.
8937  */
8938 static int gl_event_handler(GetLine *gl, int fd)
8939 {
8940 #if !defined(HAVE_SELECT)
8941   return 0;
8942 #else
8943 /*
8944  * Set up a zero-second timeout.
8945  */
8946   struct timeval zero;
8947   zero.tv_sec = zero.tv_usec = 0;
8948 /*
8949  * If at any time no external callbacks remain, quit the loop return,
8950  * so that we can simply wait in read(). This is designed as an
8951  * optimization for when no callbacks have been registered on entry to
8952  * this function, but since callbacks can delete themselves, it can
8953  * also help later.
8954  */
8955   while(gl->fd_nodes || gl->timer.fn) {
8956     int nready;   /* The number of file descriptors that are ready for I/O */
8957 /*
8958  * Get the set of descriptors to be watched.
8959  */
8960     fd_set rfds = gl->rfds;
8961     fd_set wfds = gl->wfds;
8962     fd_set ufds = gl->ufds;
8963 /*
8964  * Get the appropriate timeout.
8965  */
8966     struct timeval dt = gl->timer.fn ? gl->timer.dt : zero;
8967 /*
8968  * Add the specified user-input file descriptor to the set that is to
8969  * be watched.
8970  */
8971     FD_SET(fd, &rfds);
8972 /*
8973  * Unblock the signals that we are watching, while select is blocked
8974  * waiting for I/O.
8975  */
8976     gl_catch_signals(gl);
8977 /*
8978  * Wait for activity on any of the file descriptors.
8979  */
8980     nready = select(gl->max_fd+1, &rfds, &wfds, &ufds,
8981 	    (gl->timer.fn || gl->io_mode==GL_SERVER_MODE) ? &dt : NULL);
8982 /*
8983  * We don't want to do a longjmp in the middle of a callback that
8984  * might be modifying global or heap data, so block all the signals
8985  * that we are trapping before executing callback functions. Note that
8986  * the caller will unblock them again when it needs to, so there is
8987  * no need to undo this before returning.
8988  */
8989     gl_mask_signals(gl, NULL);
8990 /*
8991  * If select() returns but none of the file descriptors are reported
8992  * to have activity, then select() timed out.
8993  */
8994     if(nready == 0) {
8995 /*
8996  * Note that in non-blocking server mode, the inactivity timer is used
8997  * to allow I/O to block for a specified amount of time, so in this
8998  * mode we return the postponed blocked status when an abort is
8999  * requested.
9000  */
9001       if(gl_call_timeout_handler(gl)) {
9002 	return 1;
9003       } else if(gl->io_mode == GL_SERVER_MODE) {
9004 	gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO);
9005 	return 1;
9006       };
9007 /*
9008  * If nready < 0, this means an error occurred.
9009  */
9010     } else if(nready < 0) {
9011       if(errno != EINTR) {
9012 	gl_record_status(gl, GLR_ERROR, errno);
9013 	return 1;
9014       };
9015 /*
9016  * If the user-input file descriptor has data available, return.
9017  */
9018     } else if(FD_ISSET(fd, &rfds)) {
9019       return 0;
9020 /*
9021  * Check for activity on any of the file descriptors registered by the
9022  * calling application, and call the associated callback functions.
9023  */
9024     } else {
9025       GlFdNode *node;   /* The fd event node being checked */
9026 /*
9027  * Search the list for the file descriptor that caused select() to return.
9028  */
9029       for(node=gl->fd_nodes; node; node=node->next) {
9030 /*
9031  * Is there urgent out of band data waiting to be read on fd?
9032  */
9033 	if(node->ur.fn && FD_ISSET(node->fd, &ufds)) {
9034 	  if(gl_call_fd_handler(gl, &node->ur, node->fd, GLFD_URGENT))
9035 	    return 1;
9036 	  break;  /* The callback may have changed the list of nodes */
9037 /*
9038  * Is the fd readable?
9039  */
9040 	} else if(node->rd.fn && FD_ISSET(node->fd, &rfds)) {
9041 	  if(gl_call_fd_handler(gl, &node->rd, node->fd, GLFD_READ))
9042 	    return 1;
9043 	  break;  /* The callback may have changed the list of nodes */
9044 /*
9045  * Is the fd writable?
9046  */
9047 	} else if(node->wr.fn && FD_ISSET(node->fd, &wfds)) {
9048 	  if(gl_call_fd_handler(gl, &node->wr, node->fd, GLFD_WRITE))
9049 	    return 1;
9050 	  break;  /* The callback may have changed the list of nodes */
9051 	};
9052       };
9053     };
9054 /*
9055  * Just in case the above event handlers asked for the input line to
9056  * be redrawn, flush any pending output.
9057  */
9058     if(gl_flush_output(gl))
9059       return 1;
9060   };
9061   return 0;
9062 }
9063 #endif
9064 
9065 #if defined(HAVE_SELECT)
9066 /*.......................................................................
9067  * This is a private function of gl_event_handler(), used to call a
9068  * file-descriptor callback.
9069  *
9070  * Input:
9071  *  gl       GetLine *  The resource object of gl_get_line().
9072  *  gfh  GlFdHandler *  The I/O handler.
9073  *  fd           int    The file-descriptor being reported.
9074  *  event  GlFdEvent    The I/O event being reported.
9075  * Output:
9076  *  return       int    0 - OK.
9077  *                      1 - Error.
9078  */
9079 static int gl_call_fd_handler(GetLine *gl, GlFdHandler *gfh, int fd,
9080 			      GlFdEvent event)
9081 {
9082   Termios attr;       /* The terminal attributes */
9083   int waserr = 0;     /* True after any error */
9084 /*
9085  * Re-enable conversion of newline characters to carriage-return/linefeed,
9086  * so that the callback can write to the terminal without having to do
9087  * anything special.
9088  */
9089   if(tcgetattr(gl->input_fd, &attr)) {
9090     _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG);
9091     return 1;
9092   };
9093   attr.c_oflag |= OPOST;
9094   while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) {
9095     if(errno != EINTR) {
9096       _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
9097       return 1;
9098     };
9099   };
9100 /*
9101  * Invoke the application's callback function.
9102  */
9103   switch(gfh->fn(gl, gfh->data, fd, event)) {
9104   default:
9105   case GLFD_ABORT:
9106     gl_record_status(gl, GLR_FDABORT, 0);
9107     waserr = 1;
9108     break;
9109   case GLFD_REFRESH:
9110     gl_queue_redisplay(gl);
9111     break;
9112   case GLFD_CONTINUE:
9113     break;
9114   };
9115 /*
9116  * Disable conversion of newline characters to carriage-return/linefeed.
9117  */
9118   attr.c_oflag &= ~(OPOST);
9119   while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) {
9120     if(errno != EINTR) {
9121       _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
9122       return 1;
9123     };
9124   };
9125   return waserr;
9126 }
9127 
9128 /*.......................................................................
9129  * This is a private function of gl_event_handler(), used to call a
9130  * inactivity timer callbacks.
9131  *
9132  * Input:
9133  *  gl       GetLine *  The resource object of gl_get_line().
9134  * Output:
9135  *  return       int    0 - OK.
9136  *                      1 - Error.
9137  */
9138 static int gl_call_timeout_handler(GetLine *gl)
9139 {
9140   Termios attr;       /* The terminal attributes */
9141   int waserr = 0;     /* True after any error */
9142 /*
9143  * Make sure that there is an inactivity timeout callback.
9144  */
9145   if(!gl->timer.fn)
9146     return 0;
9147 /*
9148  * Re-enable conversion of newline characters to carriage-return/linefeed,
9149  * so that the callback can write to the terminal without having to do
9150  * anything special.
9151  */
9152   if(tcgetattr(gl->input_fd, &attr)) {
9153     _err_record_msg(gl->err, "tcgetattr error", END_ERR_MSG);
9154     return 1;
9155   };
9156   attr.c_oflag |= OPOST;
9157   while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) {
9158     if(errno != EINTR) {
9159       _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
9160       return 1;
9161     };
9162   };
9163 /*
9164  * Invoke the application's callback function.
9165  */
9166   switch(gl->timer.fn(gl, gl->timer.data)) {
9167   default:
9168   case GLTO_ABORT:
9169     gl_record_status(gl, GLR_TIMEOUT, 0);
9170     waserr = 1;
9171     break;
9172   case GLTO_REFRESH:
9173     gl_queue_redisplay(gl);
9174     break;
9175   case GLTO_CONTINUE:
9176     break;
9177   };
9178 /*
9179  * Disable conversion of newline characters to carriage-return/linefeed.
9180  */
9181   attr.c_oflag &= ~(OPOST);
9182   while(tcsetattr(gl->input_fd, TCSADRAIN, &attr)) {
9183     if(errno != EINTR) {
9184       _err_record_msg(gl->err, "tcsetattr error", END_ERR_MSG);
9185       return 1;
9186     };
9187   };
9188   return waserr;
9189 }
9190 #endif  /* HAVE_SELECT */
9191 
9192 /*.......................................................................
9193  * Switch history groups. History groups represent separate history
9194  * lists recorded within a single history buffer. Different groups
9195  * are distinguished by integer identifiers chosen by the calling
9196  * appplicaton. Initially new_GetLine() sets the group identifier to
9197  * 0. Whenever a new line is appended to the history list, the current
9198  * group identifier is recorded with it, and history lookups only
9199  * consider lines marked with the current group identifier.
9200  *
9201  * Input:
9202  *  gl      GetLine *  The resource object of gl_get_line().
9203  *  id     unsigned    The new history group identifier.
9204  * Output:
9205  *  return      int    0 - OK.
9206  *                     1 - Error.
9207  */
9208 int gl_group_history(GetLine *gl, unsigned id)
9209 {
9210   sigset_t oldset; /* The signals that were blocked on entry to this function */
9211   int status;      /* The return status of this function */
9212 /*
9213  * Check the arguments.
9214  */
9215   if(!gl) {
9216     errno = EINVAL;
9217     return 1;
9218   };
9219 /*
9220  * Block all signals while we install the new configuration.
9221  */
9222   if(gl_mask_signals(gl, &oldset))
9223     return 1;
9224 /*
9225  * If the group isn't being changed, do nothing.
9226  */
9227   if(_glh_get_group(gl->glh) == id) {
9228     status = 0;
9229 /*
9230  * Establish the new group.
9231  */
9232   } else if(_glh_set_group(gl->glh, id)) {
9233     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
9234     status = 1;
9235 /*
9236  * Prevent history information from the previous group being
9237  * inappropriately used by the next call to gl_get_line().
9238  */
9239   } else {
9240     gl->preload_history = 0;
9241     gl->last_search = -1;
9242     status = 0;
9243   };
9244 /*
9245  * Restore the process signal mask.
9246  */
9247   gl_unmask_signals(gl, &oldset);
9248   return status;
9249 }
9250 
9251 /*.......................................................................
9252  * Display the contents of the history list.
9253  *
9254  * Input:
9255  *  gl      GetLine *  The resource object of gl_get_line().
9256  *  fp         FILE *  The stdio output stream to write to.
9257  *  fmt  const char *  A format string. This containing characters to be
9258  *                     written verbatim, plus any of the following
9259  *                     format directives:
9260  *                       %D  -  The date, formatted like 2001-11-20
9261  *                       %T  -  The time of day, formatted like 23:59:59
9262  *                       %N  -  The sequential entry number of the
9263  *                              line in the history buffer.
9264  *                       %G  -  The number of the history group that
9265  *                              the line belongs to.
9266  *                       %%  -  A literal % character.
9267  *                       %H  -  The history line itself.
9268  *                     Note that a '\n' newline character is not
9269  *                     appended by default.
9270  *  all_groups  int    If true, display history lines from all
9271  *                     history groups. Otherwise only display
9272  *                     those of the current history group.
9273  *  max_lines   int    If max_lines is < 0, all available lines
9274  *                     are displayed. Otherwise only the most
9275  *                     recent max_lines lines will be displayed.
9276  * Output:
9277  *  return      int    0 - OK.
9278  *                     1 - Error.
9279  */
9280 int gl_show_history(GetLine *gl, FILE *fp, const char *fmt, int all_groups,
9281 		    int max_lines)
9282 {
9283   sigset_t oldset; /* The signals that were blocked on entry to this function */
9284   int status;      /* The return status of this function */
9285 /*
9286  * Check the arguments.
9287  */
9288   if(!gl || !fp || !fmt) {
9289     if(gl)
9290       _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
9291     errno = EINVAL;
9292     return 1;
9293   };
9294 /*
9295  * Block all signals.
9296  */
9297   if(gl_mask_signals(gl, &oldset))
9298     return 1;
9299 /*
9300  * Display the specified history group(s) while signals are blocked.
9301  */
9302   status = _glh_show_history(gl->glh, _io_write_stdio, fp, fmt, all_groups,
9303 			     max_lines) || fflush(fp)==EOF;
9304   if(!status)
9305     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
9306 /*
9307  * Restore the process signal mask.
9308  */
9309   gl_unmask_signals(gl, &oldset);
9310   return status;
9311 }
9312 
9313 /*.......................................................................
9314  * Update if necessary, and return the current size of the terminal.
9315  *
9316  * Input:
9317  *  gl            GetLine *  The resource object of gl_get_line().
9318  *  def_ncolumn       int    If the number of columns in the terminal
9319  *                           can't be determined, substitute this number.
9320  *  def_nline         int    If the number of lines in the terminal can't
9321  *                           be determined, substitute this number.
9322  * Output:
9323  *  return GlTerminalSize    The current terminal size.
9324  */
9325 GlTerminalSize gl_terminal_size(GetLine *gl, int def_ncolumn, int def_nline)
9326 {
9327   GlTerminalSize size;  /* The object to be returned */
9328   sigset_t oldset;      /* The signals that were blocked on entry */
9329                         /*  to this function */
9330 /*
9331  * Block all signals while accessing gl.
9332  */
9333   gl_mask_signals(gl, &oldset);
9334 /*
9335  * Lookup/configure the terminal size.
9336  */
9337   _gl_terminal_size(gl, def_ncolumn, def_nline, &size);
9338 /*
9339  * Restore the process signal mask before returning.
9340  */
9341   gl_unmask_signals(gl, &oldset);
9342   return size;
9343 }
9344 
9345 /*.......................................................................
9346  * This is the private body of the gl_terminal_size() function. It
9347  * assumes that the caller has checked its arguments and blocked the
9348  * delivery of signals.
9349  */
9350 static void _gl_terminal_size(GetLine *gl, int def_ncolumn, int def_nline,
9351 			      GlTerminalSize *size)
9352 {
9353   const char *env;      /* The value of an environment variable */
9354   int n;                /* A number read from env[] */
9355 /*
9356  * Set the number of lines and columns to non-sensical values so that
9357  * we know later if they have been set.
9358  */
9359   gl->nline = 0;
9360   gl->ncolumn = 0;
9361 /*
9362  * Are we reading from a terminal?
9363  */
9364   if(gl->is_term) {
9365 /*
9366  * Ask the terminal directly if possible.
9367  */
9368     (void) _gl_update_size(gl);
9369 /*
9370  * If gl_update_size() couldn't ask the terminal, it will have
9371  * left gl->nrow and gl->ncolumn unchanged. If these values haven't
9372  * been changed from their initial values of zero, we need to find
9373  * a different method to get the terminal size.
9374  *
9375  * If the number of lines isn't known yet, first see if the
9376  * LINES environment ariable exists and specifies a believable number.
9377  * If this doesn't work, look up the default size in the terminal
9378  * information database.
9379  */
9380     if(gl->nline < 1) {
9381       if((env = getenv("LINES")) && (n=atoi(env)) > 0)
9382 	gl->nline = n;
9383 #ifdef USE_TERMINFO
9384       else
9385 	gl->nline = tigetnum((char *)"lines");
9386 #elif defined(USE_TERMCAP)
9387       else
9388         gl->nline = tgetnum("li");
9389 #endif
9390     };
9391 /*
9392  * If the number of lines isn't known yet, first see if the COLUMNS
9393  * environment ariable exists and specifies a believable number.  If
9394  * this doesn't work, look up the default size in the terminal
9395  * information database.
9396  */
9397     if(gl->ncolumn < 1) {
9398       if((env = getenv("COLUMNS")) && (n=atoi(env)) > 0)
9399 	gl->ncolumn = n;
9400 #ifdef USE_TERMINFO
9401       else
9402 	gl->ncolumn = tigetnum((char *)"cols");
9403 #elif defined(USE_TERMCAP)
9404       else
9405 	gl->ncolumn = tgetnum("co");
9406 #endif
9407     };
9408   };
9409 /*
9410  * If we still haven't been able to acquire reasonable values, substitute
9411  * the default values specified by the caller.
9412  */
9413   if(gl->nline <= 0)
9414     gl->nline = def_nline;
9415   if(gl->ncolumn <= 0)
9416     gl->ncolumn = def_ncolumn;
9417 /*
9418  * Copy the new size into the return value.
9419  */
9420   if(size) {
9421     size->nline = gl->nline;
9422     size->ncolumn = gl->ncolumn;
9423   };
9424   return;
9425 }
9426 
9427 /*.......................................................................
9428  * Resize or delete the history buffer.
9429  *
9430  * Input:
9431  *  gl      GetLine *  The resource object of gl_get_line().
9432  *  bufsize  size_t    The number of bytes in the history buffer, or 0
9433  *                     to delete the buffer completely.
9434  * Output:
9435  *  return      int    0 - OK.
9436  *                     1 - Insufficient memory (the previous buffer
9437  *                         will have been retained). No error message
9438  *                         will be displayed.
9439  */
9440 int gl_resize_history(GetLine *gl, size_t bufsize)
9441 {
9442   sigset_t oldset; /* The signals that were blocked on entry to this function */
9443   int status;      /* The return status of this function */
9444 /*
9445  * Check the arguments.
9446  */
9447   if(!gl)
9448     return 1;
9449 /*
9450  * Block all signals while modifying the contents of gl.
9451  */
9452   if(gl_mask_signals(gl, &oldset))
9453     return 1;
9454 /*
9455  * Perform the resize while signals are blocked.
9456  */
9457   status = _glh_resize_history(gl->glh, bufsize);
9458   if(status)
9459     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
9460 /*
9461  * Restore the process signal mask before returning.
9462  */
9463   gl_unmask_signals(gl, &oldset);
9464   return status;
9465 }
9466 
9467 /*.......................................................................
9468  * Set an upper limit to the number of lines that can be recorded in the
9469  * history list, or remove a previously specified limit.
9470  *
9471  * Input:
9472  *  gl      GetLine *  The resource object of gl_get_line().
9473  *  max_lines   int    The maximum number of lines to allow, or -1 to
9474  *                     cancel a previous limit and allow as many lines
9475  *                     as will fit in the current history buffer size.
9476  */
9477 void gl_limit_history(GetLine *gl, int max_lines)
9478 {
9479   if(gl) {
9480     sigset_t oldset; /* The signals that were blocked on entry to this block */
9481 /*
9482  * Temporarily block all signals.
9483  */
9484     gl_mask_signals(gl, &oldset);
9485 /*
9486  * Apply the limit while signals are blocked.
9487  */
9488     _glh_limit_history(gl->glh, max_lines);
9489 /*
9490  * Restore the process signal mask before returning.
9491  */
9492     gl_unmask_signals(gl, &oldset);
9493   };
9494 }
9495 
9496 /*.......................................................................
9497  * Discard either all historical lines, or just those associated with the
9498  * current history group.
9499  *
9500  * Input:
9501  *  gl      GetLine *  The resource object of gl_get_line().
9502  *  all_groups  int    If true, clear all of the history. If false,
9503  *                     clear only the stored lines associated with the
9504  *                     currently selected history group.
9505  */
9506 void gl_clear_history(GetLine *gl, int all_groups)
9507 {
9508   if(gl) {
9509     sigset_t oldset; /* The signals that were blocked on entry to this block */
9510 /*
9511  * Temporarily block all signals.
9512  */
9513     gl_mask_signals(gl, &oldset);
9514 /*
9515  * Clear the history buffer while signals are blocked.
9516  */
9517     _glh_clear_history(gl->glh, all_groups);
9518 /*
9519  * Restore the process signal mask before returning.
9520  */
9521     gl_unmask_signals(gl, &oldset);
9522   };
9523 }
9524 
9525 /*.......................................................................
9526  * Temporarily enable or disable the gl_get_line() history mechanism.
9527  *
9528  * Input:
9529  *  gl      GetLine *  The resource object of gl_get_line().
9530  *  enable      int    If true, turn on the history mechanism. If
9531  *                     false, disable it.
9532  */
9533 void gl_toggle_history(GetLine *gl, int enable)
9534 {
9535   if(gl) {
9536     sigset_t oldset; /* The signals that were blocked on entry to this block */
9537 /*
9538  * Temporarily block all signals.
9539  */
9540     gl_mask_signals(gl, &oldset);
9541 /*
9542  * Change the history recording mode while signals are blocked.
9543  */
9544     _glh_toggle_history(gl->glh, enable);
9545 /*
9546  * Restore the process signal mask before returning.
9547  */
9548     gl_unmask_signals(gl, &oldset);
9549   };
9550 }
9551 
9552 /*.......................................................................
9553  * Lookup a history line by its sequential number of entry in the
9554  * history buffer.
9555  *
9556  * Input:
9557  *  gl            GetLine *  The resource object of gl_get_line().
9558  *  id      unsigned long    The identification number of the line to
9559  *                           be returned, where 0 denotes the first line
9560  *                           that was entered in the history list, and
9561  *                           each subsequently added line has a number
9562  *                           one greater than the previous one. For
9563  *                           the range of lines currently in the list,
9564  *                           see the gl_range_of_history() function.
9565  * Input/Output:
9566  *  line    GlHistoryLine *  A pointer to the variable in which to
9567  *                           return the details of the line.
9568  * Output:
9569  *  return            int    0 - The line is no longer in the history
9570  *                               list, and *line has not been changed.
9571  *                           1 - The requested line can be found in
9572  *                               *line. Note that line->line is part
9573  *                               of the history buffer, so a
9574  *                               private copy should be made if you
9575  *                               wish to use it after subsequent calls
9576  *                               to any functions that take *gl as an
9577  *                               argument.
9578  */
9579 int gl_lookup_history(GetLine *gl, unsigned long id, GlHistoryLine *line)
9580 {
9581   sigset_t oldset; /* The signals that were blocked on entry to this function */
9582   int status;      /* The return status of this function */
9583 /*
9584  * Check the arguments.
9585  */
9586   if(!gl)
9587     return 0;
9588 /*
9589  * Block all signals while modifying the contents of gl.
9590  */
9591   if(gl_mask_signals(gl, &oldset))
9592     return 1;
9593 /*
9594  * Perform the lookup while signals are blocked.
9595  */
9596   status = _glh_lookup_history(gl->glh, (GlhLineID) id, &line->line,
9597 			       &line->group, &line->timestamp);
9598   if(status)
9599     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
9600 /*
9601  * Restore the process signal mask before returning.
9602  */
9603   gl_unmask_signals(gl, &oldset);
9604   return status;
9605 }
9606 
9607 /*.......................................................................
9608  * Query the state of the history list. Note that any of the input/output
9609  * pointers can be specified as NULL.
9610  *
9611  * Input:
9612  *  gl            GetLine *  The resource object of gl_get_line().
9613  * Input/Output:
9614  *  state  GlHistoryState *  A pointer to the variable in which to record
9615  *                           the return values.
9616  */
9617 void gl_state_of_history(GetLine *gl, GlHistoryState *state)
9618 {
9619   if(gl && state) {
9620     sigset_t oldset; /* The signals that were blocked on entry to this block */
9621 /*
9622  * Temporarily block all signals.
9623  */
9624     gl_mask_signals(gl, &oldset);
9625 /*
9626  * Lookup the status while signals are blocked.
9627  */
9628     _glh_state_of_history(gl->glh, &state->enabled, &state->group,
9629 			  &state->max_lines);
9630 /*
9631  * Restore the process signal mask before returning.
9632  */
9633     gl_unmask_signals(gl, &oldset);
9634   };
9635 }
9636 
9637 /*.......................................................................
9638  * Query the number and range of lines in the history buffer.
9639  *
9640  * Input:
9641  *  gl            GetLine *  The resource object of gl_get_line().
9642  *  range  GlHistoryRange *  A pointer to the variable in which to record
9643  *                           the return values. If range->nline=0, the
9644  *                           range of lines will be given as 0-0.
9645  */
9646 void gl_range_of_history(GetLine *gl, GlHistoryRange *range)
9647 {
9648   if(gl && range) {
9649     sigset_t oldset; /* The signals that were blocked on entry to this block */
9650 /*
9651  * Temporarily block all signals.
9652  */
9653     gl_mask_signals(gl, &oldset);
9654 /*
9655  * Lookup the information while signals are blocked.
9656  */
9657     _glh_range_of_history(gl->glh, &range->oldest, &range->newest,
9658 			  &range->nlines);
9659 /*
9660  * Restore the process signal mask before returning.
9661  */
9662     gl_unmask_signals(gl, &oldset);
9663   };
9664 }
9665 
9666 /*.......................................................................
9667  * Return the size of the history buffer and the amount of the
9668  * buffer that is currently in use.
9669  *
9670  * Input:
9671  *  gl         GetLine *  The gl_get_line() resource object.
9672  * Input/Output:
9673  *  GlHistorySize size *  A pointer to the variable in which to return
9674  *                        the results.
9675  */
9676 void gl_size_of_history(GetLine *gl, GlHistorySize *size)
9677 {
9678   if(gl && size) {
9679     sigset_t oldset; /* The signals that were blocked on entry to this block */
9680 /*
9681  * Temporarily block all signals.
9682  */
9683     gl_mask_signals(gl, &oldset);
9684 /*
9685  * Lookup the information while signals are blocked.
9686  */
9687     _glh_size_of_history(gl->glh, &size->size, &size->used);
9688 /*
9689  * Restore the process signal mask before returning.
9690  */
9691     gl_unmask_signals(gl, &oldset);
9692   };
9693 }
9694 
9695 /*.......................................................................
9696  * This is the action function that lists the contents of the history
9697  * list.
9698  */
9699 static KT_KEY_FN(gl_list_history)
9700 {
9701 /*
9702  * Start a new line.
9703  */
9704   if(gl_start_newline(gl, 1))
9705     return 1;
9706 /*
9707  * List history lines that belong to the current group.
9708  */
9709   _glh_show_history(gl->glh, gl_write_fn, gl, "%N  %T   %H\r\n", 0,
9710 		    count<=1 ? -1 : count);
9711 /*
9712  * Arrange for the input line to be redisplayed.
9713  */
9714   gl_queue_redisplay(gl);
9715   return 0;
9716 }
9717 
9718 /*.......................................................................
9719  * Specify whether text that users type should be displayed or hidden.
9720  * In the latter case, only the prompt is displayed, and the final
9721  * input line is not archived in the history list.
9722  *
9723  * Input:
9724  *  gl         GetLine *  The gl_get_line() resource object.
9725  *  enable         int     0 - Disable echoing.
9726  *                         1 - Enable echoing.
9727  *                        -1 - Just query the mode without changing it.
9728  * Output:
9729  *  return         int    The echoing disposition that was in effect
9730  *                        before this function was called:
9731  *                         0 - Echoing was disabled.
9732  *                         1 - Echoing was enabled.
9733  */
9734 int gl_echo_mode(GetLine *gl, int enable)
9735 {
9736   if(gl) {
9737     sigset_t oldset; /* The signals that were blocked on entry to this block */
9738     int was_echoing; /* The echoing disposition on entry to this function */
9739 /*
9740  * Temporarily block all signals.
9741  */
9742     gl_mask_signals(gl, &oldset);
9743 /*
9744  * Install the new disposition while signals are blocked.
9745  */
9746     was_echoing = gl->echo;
9747     if(enable >= 0)
9748       gl->echo = enable;
9749 /*
9750  * Restore the process signal mask before returning.
9751  */
9752     gl_unmask_signals(gl, &oldset);
9753 /*
9754  * Return the original echoing disposition.
9755  */
9756     return was_echoing;
9757   };
9758   return 1;
9759 }
9760 
9761 /*.......................................................................
9762  * Display the prompt.
9763  *
9764  * Input:
9765  *  gl         GetLine *  The resource object of gl_get_line().
9766  * Output:
9767  *  return         int    0 - OK.
9768  *                        1 - Error.
9769  */
9770 static int gl_display_prompt(GetLine *gl)
9771 {
9772   const char *pptr;       /* A pointer into gl->prompt[] */
9773   unsigned old_attr=0;    /* The current text display attributes */
9774   unsigned new_attr=0;    /* The requested text display attributes */
9775 /*
9776  * Temporarily switch to echoing output characters.
9777  */
9778   int kept_echo = gl->echo;
9779   gl->echo = 1;
9780 /*
9781  * In case the screen got messed up, send a carriage return to
9782  * put the cursor at the beginning of the current terminal line.
9783  */
9784   if(gl_print_control_sequence(gl, 1, gl->bol))
9785     return 1;
9786 /*
9787  * Mark the line as partially displayed.
9788  */
9789   gl->displayed = 1;
9790 /*
9791  * Write the prompt, using the currently selected prompt style.
9792  */
9793   switch(gl->prompt_style) {
9794   case GL_LITERAL_PROMPT:
9795     if(gl_print_string(gl, gl->prompt, '\0'))
9796       return 1;
9797     break;
9798   case GL_FORMAT_PROMPT:
9799     for(pptr=gl->prompt; *pptr; pptr++) {
9800 /*
9801  * Does the latest character appear to be the start of a directive?
9802  */
9803       if(*pptr == '%') {
9804 /*
9805  * Check for and act on attribute changing directives.
9806  */
9807 	switch(pptr[1]) {
9808 /*
9809  * Add or remove a text attribute from the new set of attributes.
9810  */
9811 	case 'B': case 'U': case 'S': case 'P': case 'F': case 'V':
9812 	case 'b': case 'u': case 's': case 'p': case 'f': case 'v':
9813 	  switch(*++pptr) {
9814 	  case 'B':           /* Switch to a bold font */
9815 	    new_attr |= GL_TXT_BOLD;
9816 	    break;
9817 	  case 'b':           /* Switch to a non-bold font */
9818 	    new_attr &= ~GL_TXT_BOLD;
9819 	    break;
9820 	  case 'U':           /* Start underlining */
9821 	    new_attr |= GL_TXT_UNDERLINE;
9822 	    break;
9823 	  case 'u':           /* Stop underlining */
9824 	    new_attr &= ~GL_TXT_UNDERLINE;
9825 	    break;
9826 	  case 'S':           /* Start highlighting */
9827 	    new_attr |= GL_TXT_STANDOUT;
9828 	    break;
9829 	  case 's':           /* Stop highlighting */
9830 	    new_attr &= ~GL_TXT_STANDOUT;
9831 	    break;
9832 	  case 'P':           /* Switch to a pale font */
9833 	    new_attr |= GL_TXT_DIM;
9834 	    break;
9835 	  case 'p':           /* Switch to a non-pale font */
9836 	    new_attr &= ~GL_TXT_DIM;
9837 	    break;
9838 	  case 'F':           /* Switch to a flashing font */
9839 	    new_attr |= GL_TXT_BLINK;
9840 	    break;
9841 	  case 'f':           /* Switch to a steady font */
9842 	    new_attr &= ~GL_TXT_BLINK;
9843 	    break;
9844 	  case 'V':           /* Switch to reverse video */
9845 	    new_attr |= GL_TXT_REVERSE;
9846 	    break;
9847 	  case 'v':           /* Switch out of reverse video */
9848 	    new_attr &= ~GL_TXT_REVERSE;
9849 	    break;
9850 	  };
9851 	  continue;
9852 /*
9853  * A literal % is represented by %%. Skip the leading %.
9854  */
9855 	case '%':
9856 	  pptr++;
9857 	  break;
9858 	};
9859       };
9860 /*
9861  * Many terminals, when asked to turn off a single text attribute, turn
9862  * them all off, so the portable way to turn one off individually is to
9863  * explicitly turn them all off, then specify those that we want from
9864  * scratch.
9865  */
9866       if(old_attr & ~new_attr) {
9867 	if(gl_print_control_sequence(gl, 1, gl->text_attr_off))
9868 	  return 1;
9869 	old_attr = 0;
9870       };
9871 /*
9872  * Install new text attributes?
9873  */
9874       if(new_attr != old_attr) {
9875 	if(new_attr & GL_TXT_BOLD && !(old_attr & GL_TXT_BOLD) &&
9876 	   gl_print_control_sequence(gl, 1, gl->bold))
9877 	  return 1;
9878 	if(new_attr & GL_TXT_UNDERLINE && !(old_attr & GL_TXT_UNDERLINE) &&
9879 	   gl_print_control_sequence(gl, 1, gl->underline))
9880 	  return 1;
9881 	if(new_attr & GL_TXT_STANDOUT && !(old_attr & GL_TXT_STANDOUT) &&
9882 	   gl_print_control_sequence(gl, 1, gl->standout))
9883 	  return 1;
9884 	if(new_attr & GL_TXT_DIM && !(old_attr & GL_TXT_DIM) &&
9885 	   gl_print_control_sequence(gl, 1, gl->dim))
9886 	  return 1;
9887 	if(new_attr & GL_TXT_REVERSE && !(old_attr & GL_TXT_REVERSE) &&
9888 	   gl_print_control_sequence(gl, 1, gl->reverse))
9889 	  return 1;
9890 	if(new_attr & GL_TXT_BLINK && !(old_attr & GL_TXT_BLINK) &&
9891 	   gl_print_control_sequence(gl, 1, gl->blink))
9892 	  return 1;
9893 	old_attr = new_attr;
9894       };
9895 /*
9896  * Display the latest character.
9897  */
9898       if(gl_print_char(gl, *pptr, pptr[1]))
9899 	return 1;
9900     };
9901 /*
9902  * Turn off all text attributes now that we have finished drawing
9903  * the prompt.
9904  */
9905     if(gl_print_control_sequence(gl, 1, gl->text_attr_off))
9906       return 1;
9907     break;
9908   };
9909 /*
9910  * Restore the original echo mode.
9911  */
9912   gl->echo = kept_echo;
9913 /*
9914  * The prompt has now been displayed at least once.
9915  */
9916   gl->prompt_changed = 0;
9917   return 0;
9918 }
9919 
9920 /*.......................................................................
9921  * This function can be called from gl_get_line() callbacks to have
9922  * the prompt changed when they return. It has no effect if gl_get_line()
9923  * is not currently being invoked.
9924  *
9925  * Input:
9926  *  gl         GetLine *  The resource object of gl_get_line().
9927  *  prompt  const char *  The new prompt.
9928  */
9929 void gl_replace_prompt(GetLine *gl, const char *prompt)
9930 {
9931   if(gl) {
9932     sigset_t oldset; /* The signals that were blocked on entry to this block */
9933 /*
9934  * Temporarily block all signals.
9935  */
9936     gl_mask_signals(gl, &oldset);
9937 /*
9938  * Replace the prompt.
9939  */
9940     _gl_replace_prompt(gl, prompt);
9941 /*
9942  * Restore the process signal mask before returning.
9943  */
9944     gl_unmask_signals(gl, &oldset);
9945   };
9946 }
9947 
9948 /*.......................................................................
9949  * This is the private body of the gl_replace_prompt() function. It
9950  * assumes that the caller has checked its arguments and blocked the
9951  * delivery of signals.
9952  */
9953 static void _gl_replace_prompt(GetLine *gl, const char *prompt)
9954 {
9955   size_t size;
9956 
9957 /*
9958  * Substitute an empty prompt?
9959  */
9960   if(!prompt)
9961     prompt = "";
9962 /*
9963  * Gaurd against aliasing between prompt and gl->prompt.
9964  */
9965   if(gl->prompt != prompt) {
9966 /*
9967  * Get the length of the new prompt string.
9968  */
9969     size_t slen = strlen(prompt);
9970 /*
9971  * If needed, allocate a new buffer for the prompt string.
9972  */
9973     size = sizeof(char) * (slen + 1);
9974     if(!gl->prompt || slen > strlen(gl->prompt)) {
9975       char *new_prompt = gl->prompt ? realloc(gl->prompt, size) : malloc(size);
9976       if(!new_prompt)
9977 	return;
9978       gl->prompt = new_prompt;
9979     };
9980 /*
9981  * Make a copy of the new prompt.
9982  */
9983     strlcpy(gl->prompt, prompt, size);
9984   };
9985 /*
9986  * Record the statistics of the new prompt.
9987  */
9988   gl->prompt_len = gl_displayed_prompt_width(gl);
9989   gl->prompt_changed = 1;
9990   gl_queue_redisplay(gl);
9991   return;
9992 }
9993 
9994 /*.......................................................................
9995  * Work out the length of the current prompt on the terminal, according
9996  * to the current prompt formatting style.
9997  *
9998  * Input:
9999  *  gl       GetLine *  The resource object of this library.
10000  * Output:
10001  *  return       int    The number of displayed characters.
10002  */
10003 static int gl_displayed_prompt_width(GetLine *gl)
10004 {
10005   int slen=0;         /* The displayed number of characters */
10006   const char *pptr;   /* A pointer into prompt[] */
10007 /*
10008  * The length differs according to the prompt display style.
10009  */
10010   switch(gl->prompt_style) {
10011   case GL_LITERAL_PROMPT:
10012     return gl_displayed_string_width(gl, gl->prompt, -1, 0);
10013     break;
10014   case GL_FORMAT_PROMPT:
10015 /*
10016  * Add up the length of the displayed string, while filtering out
10017  * attribute directives.
10018  */
10019     for(pptr=gl->prompt; *pptr; pptr++) {
10020 /*
10021  * Does the latest character appear to be the start of a directive?
10022  */
10023       if(*pptr == '%') {
10024 /*
10025  * Check for and skip attribute changing directives.
10026  */
10027 	switch(pptr[1]) {
10028 	case 'B': case 'b': case 'U': case 'u': case 'S': case 's':
10029 	  pptr++;
10030 	  continue;
10031 /*
10032  * A literal % is represented by %%. Skip the leading %.
10033  */
10034 	case '%':
10035 	  pptr++;
10036 	  break;
10037 	};
10038       };
10039       slen += gl_displayed_char_width(gl, *pptr, slen);
10040     };
10041     break;
10042   };
10043   return slen;
10044 }
10045 
10046 /*.......................................................................
10047  * Specify whether to heed text attribute directives within prompt
10048  * strings.
10049  *
10050  * Input:
10051  *  gl           GetLine *  The resource object of gl_get_line().
10052  *  style  GlPromptStyle    The style of prompt (see the definition of
10053  *                          GlPromptStyle in libtecla.h for details).
10054  */
10055 void gl_prompt_style(GetLine *gl, GlPromptStyle style)
10056 {
10057   if(gl) {
10058     sigset_t oldset; /* The signals that were blocked on entry to this block */
10059 /*
10060  * Temporarily block all signals.
10061  */
10062     gl_mask_signals(gl, &oldset);
10063 /*
10064  * Install the new style in gl while signals are blocked.
10065  */
10066     if(style != gl->prompt_style) {
10067       gl->prompt_style = style;
10068       gl->prompt_len = gl_displayed_prompt_width(gl);
10069       gl->prompt_changed = 1;
10070       gl_queue_redisplay(gl);
10071     };
10072 /*
10073  * Restore the process signal mask before returning.
10074  */
10075     gl_unmask_signals(gl, &oldset);
10076   };
10077 }
10078 
10079 /*.......................................................................
10080  * Tell gl_get_line() how to respond to a given signal. This can be used
10081  * both to override the default responses to signals that gl_get_line()
10082  * normally catches and to add new signals to the list that are to be
10083  * caught.
10084  *
10085  * Input:
10086  *  gl           GetLine *  The resource object of gl_get_line().
10087  *  signo            int    The number of the signal to be caught.
10088  *  flags       unsigned    A bitwise union of GlSignalFlags enumerators.
10089  *  after  GlAfterSignal    What to do after the application's signal
10090  *                          handler has been called.
10091  *  errno_value      int    The value to set errno to.
10092  * Output:
10093  *  return           int    0 - OK.
10094  *                          1 - Error.
10095  */
10096 int gl_trap_signal(GetLine *gl, int signo, unsigned flags,
10097 		   GlAfterSignal after, int errno_value)
10098 {
10099   sigset_t oldset; /* The signals that were blocked on entry to this function */
10100   int status;      /* The return status of this function */
10101 /*
10102  * Check the arguments.
10103  */
10104   if(!gl) {
10105     errno = EINVAL;
10106     return 1;
10107   };
10108 /*
10109  * Block all signals while modifying the contents of gl.
10110  */
10111   if(gl_mask_signals(gl, &oldset))
10112     return 1;
10113 /*
10114  * Perform the modification while signals are blocked.
10115  */
10116   status = _gl_trap_signal(gl, signo, flags, after, errno_value);
10117 /*
10118  * Restore the process signal mask before returning.
10119  */
10120   gl_unmask_signals(gl, &oldset);
10121   return status;
10122 }
10123 
10124 /*.......................................................................
10125  * This is the private body of the gl_trap_signal() function. It
10126  * assumes that the caller has checked its arguments and blocked the
10127  * delivery of signals.
10128  */
10129 static int _gl_trap_signal(GetLine *gl, int signo, unsigned flags,
10130 			   GlAfterSignal after, int errno_value)
10131 {
10132   GlSignalNode *sig;
10133 /*
10134  * Complain if an attempt is made to trap untrappable signals.
10135  * These would otherwise cause errors later in gl_mask_signals().
10136  */
10137   if(0
10138 #ifdef SIGKILL
10139      || signo==SIGKILL
10140 #endif
10141 #ifdef SIGBLOCK
10142      || signo==SIGBLOCK
10143 #endif
10144      ) {
10145     return 1;
10146   };
10147 /*
10148  * See if the signal has already been registered.
10149  */
10150   for(sig=gl->sigs; sig && sig->signo != signo; sig = sig->next)
10151     ;
10152 /*
10153  * If the signal hasn't already been registered, allocate a node for
10154  * it.
10155  */
10156   if(!sig) {
10157     sig = (GlSignalNode *) _new_FreeListNode(gl->sig_mem);
10158     if(!sig)
10159       return 1;
10160 /*
10161  * Add the new node to the head of the list.
10162  */
10163     sig->next = gl->sigs;
10164     gl->sigs = sig;
10165 /*
10166  * Record the signal number.
10167  */
10168     sig->signo = signo;
10169 /*
10170  * Create a signal set that includes just this signal.
10171  */
10172     sigemptyset(&sig->proc_mask);
10173     if(sigaddset(&sig->proc_mask, signo) == -1) {
10174       _err_record_msg(gl->err, "sigaddset error", END_ERR_MSG);
10175       sig = (GlSignalNode *) _del_FreeListNode(gl->sig_mem, sig);
10176       return 1;
10177     };
10178 /*
10179  * Add the signal to the bit-mask of signals being trapped.
10180  */
10181     sigaddset(&gl->all_signal_set, signo);
10182   };
10183 /*
10184  * Record the new signal attributes.
10185  */
10186   sig->flags = flags;
10187   sig->after = after;
10188   sig->errno_value = errno_value;
10189   return 0;
10190 }
10191 
10192 /*.......................................................................
10193  * Remove a signal from the list of signals that gl_get_line() traps.
10194  *
10195  * Input:
10196  *  gl           GetLine *  The resource object of gl_get_line().
10197  *  signo            int    The number of the signal to be ignored.
10198  * Output:
10199  *  return           int    0 - OK.
10200  *                          1 - Error.
10201  */
10202 int gl_ignore_signal(GetLine *gl, int signo)
10203 {
10204   GlSignalNode *sig;  /* The gl->sigs list node of the specified signal */
10205   GlSignalNode *prev; /* The node that precedes sig in the list */
10206   sigset_t oldset;    /* The signals that were blocked on entry to this */
10207                       /*  function. */
10208 /*
10209  * Check the arguments.
10210  */
10211   if(!gl) {
10212     errno = EINVAL;
10213     return 1;
10214   };
10215 /*
10216  * Block all signals while modifying the contents of gl.
10217  */
10218   if(gl_mask_signals(gl, &oldset))
10219     return 1;
10220 /*
10221  * Find the node of the gl->sigs list which records the disposition
10222  * of the specified signal.
10223  */
10224   for(prev=NULL,sig=gl->sigs; sig && sig->signo != signo;
10225       prev=sig,sig=sig->next)
10226     ;
10227   if(sig) {
10228 /*
10229  * Remove the node from the list.
10230  */
10231     if(prev)
10232       prev->next = sig->next;
10233     else
10234       gl->sigs = sig->next;
10235 /*
10236  * Return the node to the freelist.
10237  */
10238     sig = (GlSignalNode *) _del_FreeListNode(gl->sig_mem, sig);
10239 /*
10240  * Remove the signal from the bit-mask union of signals being trapped.
10241  */
10242     sigdelset(&gl->all_signal_set, signo);
10243   };
10244 /*
10245  * Restore the process signal mask before returning.
10246  */
10247   gl_unmask_signals(gl, &oldset);
10248   return 0;
10249 }
10250 
10251 /*.......................................................................
10252  * This function is called when an input line has been completed. It
10253  * appends the specified newline character, terminates the line,
10254  * records the line in the history buffer if appropriate, and positions
10255  * the terminal cursor at the start of the next line.
10256  *
10257  * Input:
10258  *  gl           GetLine *  The resource object of gl_get_line().
10259  *  newline_char     int    The newline character to add to the end
10260  *                          of the line.
10261  * Output:
10262  *  return           int    0 - OK.
10263  *                          1 - Error.
10264  */
10265 static int gl_line_ended(GetLine *gl, int newline_char)
10266 {
10267 /*
10268  * If the newline character is printable, display it at the end of
10269  * the line, and add it to the input line buffer.
10270  */
10271   if(isprint((int)(unsigned char) newline_char)) {
10272     if(gl_end_of_line(gl, 1, NULL) || gl_add_char_to_line(gl, newline_char))
10273       return 1;
10274   } else {
10275 /*
10276  * Otherwise just append a newline character to the input line buffer.
10277  */
10278     newline_char = '\n';
10279     gl_buffer_char(gl, newline_char, gl->ntotal);
10280   };
10281 /*
10282  * Add the line to the history buffer if it was entered with a
10283  * newline character.
10284  */
10285   if(gl->echo && gl->automatic_history && newline_char=='\n')
10286     (void) _gl_append_history(gl, gl->line);
10287 /*
10288  * Except when depending on the system-provided line editing, start a new
10289  * line after the end of the line that has just been entered.
10290  */
10291   if(gl->editor != GL_NO_EDITOR && gl_start_newline(gl, 1))
10292     return 1;
10293 /*
10294  * Record the successful return status.
10295  */
10296   gl_record_status(gl, GLR_NEWLINE, 0);
10297 /*
10298  * Attempt to flush any pending output.
10299  */
10300   (void) gl_flush_output(gl);
10301 /*
10302  * The next call to gl_get_line() will write the prompt for a new line
10303  * (or continue the above flush if incomplete), so if we manage to
10304  * flush the terminal now, report that we are waiting to write to the
10305  * terminal.
10306  */
10307   gl->pending_io = GLP_WRITE;
10308   return 0;
10309 }
10310 
10311 /*.......................................................................
10312  * Return the last signal that was caught by the most recent call to
10313  * gl_get_line(), or -1 if no signals were caught. This is useful if
10314  * gl_get_line() returns errno=EINTR and you need to find out what signal
10315  * caused it to abort.
10316  *
10317  * Input:
10318  *  gl           GetLine *  The resource object of gl_get_line().
10319  * Output:
10320  *  return           int    The last signal caught by the most recent
10321  *                          call to gl_get_line(), or -1 if no signals
10322  *                          were caught.
10323  */
10324 int gl_last_signal(GetLine *gl)
10325 {
10326   int signo = -1;   /* The requested signal number */
10327   if(gl) {
10328     sigset_t oldset; /* The signals that were blocked on entry to this block */
10329 /*
10330  * Temporarily block all signals.
10331  */
10332     gl_mask_signals(gl, &oldset);
10333 /*
10334  * Access gl now that signals are blocked.
10335  */
10336     signo = gl->last_signal;
10337 /*
10338  * Restore the process signal mask before returning.
10339  */
10340     gl_unmask_signals(gl, &oldset);
10341   };
10342   return signo;
10343 }
10344 
10345 /*.......................................................................
10346  * Prepare to edit a new line.
10347  *
10348  * Input:
10349  *  gl         GetLine *  The resource object of this library.
10350  *  prompt        char *  The prompt to prefix the line with, or NULL to
10351  *                        use the same prompt that was used by the previous
10352  *                        line.
10353  *  start_line    char *  The initial contents of the input line, or NULL
10354  *                        if it should start out empty.
10355  *  start_pos      int    If start_line isn't NULL, this specifies the
10356  *                        index of the character over which the cursor
10357  *                        should initially be positioned within the line.
10358  *                        If you just want it to follow the last character
10359  *                        of the line, send -1.
10360  * Output:
10361  *  return    int    0 - OK.
10362  *                   1 - Error.
10363  */
10364 static int gl_present_line(GetLine *gl, const char *prompt,
10365 			   const char *start_line, int start_pos)
10366 {
10367 /*
10368  * Reset the properties of the line.
10369  */
10370   gl_reset_input_line(gl);
10371 /*
10372  * Record the new prompt and its displayed width.
10373  */
10374   if(prompt)
10375     _gl_replace_prompt(gl, prompt);
10376 /*
10377  * Reset the history search pointers.
10378  */
10379   if(_glh_cancel_search(gl->glh)) {
10380     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
10381     return 1;
10382   };
10383 /*
10384  * If the previous line was entered via the repeat-history action,
10385  * preload the specified history line.
10386  */
10387   if(gl->preload_history) {
10388     gl->preload_history = 0;
10389     if(gl->preload_id) {
10390       if(_glh_recall_line(gl->glh, gl->preload_id, gl->line, gl->linelen+1)) {
10391 	gl_update_buffer(gl);          /* Compute gl->ntotal etc.. */
10392 	gl->buff_curpos = gl->ntotal;
10393       } else {
10394 	gl_truncate_buffer(gl, 0);
10395       };
10396       gl->preload_id = 0;
10397     };
10398 /*
10399  * Present a specified initial line?
10400  */
10401   } else if(start_line) {
10402     char *cptr;      /* A pointer into gl->line[] */
10403 /*
10404  * Measure the length of the starting line.
10405  */
10406     int start_len = strlen(start_line);
10407 /*
10408  * If the length of the line is greater than the available space,
10409  * truncate it.
10410  */
10411     if(start_len > gl->linelen)
10412       start_len = gl->linelen;
10413 /*
10414  * Load the line into the buffer.
10415  */
10416     if(start_line != gl->line)
10417       gl_buffer_string(gl, start_line, start_len, 0);
10418 /*
10419  * Strip off any trailing newline and carriage return characters.
10420  */
10421     for(cptr=gl->line + gl->ntotal - 1; cptr >= gl->line &&
10422 	(*cptr=='\n' || *cptr=='\r'); cptr--,gl->ntotal--)
10423       ;
10424     gl_truncate_buffer(gl, gl->ntotal < 0 ? 0 : gl->ntotal);
10425 /*
10426  * Where should the cursor be placed within the line?
10427  */
10428     if(start_pos < 0 || start_pos > gl->ntotal) {
10429       if(gl_place_cursor(gl, gl->ntotal))
10430 	return 1;
10431     } else {
10432       if(gl_place_cursor(gl, start_pos))
10433 	return 1;
10434     };
10435 /*
10436  * Clear the input line?
10437  */
10438   } else {
10439     gl_truncate_buffer(gl, 0);
10440   };
10441 /*
10442  * Arrange for the line to be displayed by gl_flush_output().
10443  */
10444   gl_queue_redisplay(gl);
10445 /*
10446  * Update the display.
10447  */
10448   return gl_flush_output(gl);
10449 }
10450 
10451 /*.......................................................................
10452  * Reset all line input parameters for a new input line.
10453  *
10454  * Input:
10455  *  gl      GetLine *  The line editor resource object.
10456  */
10457 static void gl_reset_input_line(GetLine *gl)
10458 {
10459   gl->ntotal = 0;
10460   gl->line[0] = '\0';
10461   gl->buff_curpos = 0;
10462   gl->term_curpos = 0;
10463   gl->term_len = 0;
10464   gl->insert_curpos = 0;
10465   gl->number = -1;
10466   gl->displayed = 0;
10467   gl->endline = 0;
10468   gl->redisplay = 0;
10469   gl->postpone = 0;
10470   gl->nbuf = 0;
10471   gl->nread = 0;
10472   gl->vi.command = 0;
10473   gl->vi.undo.line[0] = '\0';
10474   gl->vi.undo.ntotal = 0;
10475   gl->vi.undo.buff_curpos = 0;
10476   gl->vi.repeat.action.fn = 0;
10477   gl->vi.repeat.action.data = 0;
10478   gl->last_signal = -1;
10479 }
10480 
10481 /*.......................................................................
10482  * Print an informational message to the terminal, after starting a new
10483  * line.
10484  *
10485  * Input:
10486  *  gl      GetLine *  The line editor resource object.
10487  *  ...  const char *  Zero or more strings to be printed.
10488  *  ...        void *  The last argument must always be GL_END_INFO.
10489  * Output:
10490  *  return      int    0 - OK.
10491  *                     1 - Error.
10492  */
10493 static int gl_print_info(GetLine *gl, ...)
10494 {
10495   va_list ap;     /* The variable argument list */
10496   const char *s;  /* The string being printed */
10497   int waserr = 0; /* True after an error */
10498 /*
10499  * Only display output when echoing is on.
10500  */
10501   if(gl->echo) {
10502 /*
10503  * Skip to the start of the next empty line before displaying the message.
10504  */
10505     if(gl_start_newline(gl, 1))
10506       return 1;
10507 /*
10508  * Display the list of provided messages.
10509  */
10510     va_start(ap, gl);
10511     while(!waserr && (s = va_arg(ap, const char *)) != GL_END_INFO)
10512       waserr = gl_print_raw_string(gl, 1, s, -1);
10513     va_end(ap);
10514 /*
10515  * Start a newline.
10516  */
10517     waserr = waserr || gl_print_raw_string(gl, 1, "\n\r", -1);
10518 /*
10519  * Arrange for the input line to be redrawn.
10520  */
10521     gl_queue_redisplay(gl);
10522   };
10523   return waserr;
10524 }
10525 
10526 /*.......................................................................
10527  * Go to the start of the next empty line, ready to output miscellaneous
10528  * text to the screen.
10529  *
10530  * Note that when async-signal safety is required, the 'buffered'
10531  * argument must be 0.
10532  *
10533  * Input:
10534  *  gl          GetLine *  The line editor resource object.
10535  *  buffered        int    If true, used buffered I/O when writing to
10536  *                         the terminal. Otherwise use async-signal-safe
10537  *                         unbuffered I/O.
10538  * Output:
10539  *  return          int    0 - OK.
10540  *                         1 - Error.
10541  */
10542 static int gl_start_newline(GetLine *gl, int buffered)
10543 {
10544   int waserr = 0;  /* True after any I/O error */
10545 /*
10546  * Move the cursor to the start of the terminal line that follows the
10547  * last line of the partially enterred line. In order that this
10548  * function remain async-signal safe when write_fn is signal safe, we
10549  * can't call our normal output functions, since they call tputs(),
10550  * who's signal saftey isn't defined. Fortunately, we can simply use
10551  * \r and \n to move the cursor to the right place.
10552  */
10553   if(gl->displayed) {   /* Is an input line currently displayed? */
10554 /*
10555  * On which terminal lines are the cursor and the last character of the
10556  * input line?
10557  */
10558     int curs_line = gl->term_curpos / gl->ncolumn;
10559     int last_line = gl->term_len / gl->ncolumn;
10560 /*
10561  * Move the cursor to the start of the line that follows the last
10562  * terminal line that is occupied by the input line.
10563  */
10564     for( ; curs_line < last_line + 1; curs_line++)
10565       waserr = waserr || gl_print_raw_string(gl, buffered, "\n", 1);
10566     waserr = waserr || gl_print_raw_string(gl, buffered, "\r", 1);
10567 /*
10568  * Mark the line as no longer displayed.
10569  */
10570     gl_line_erased(gl);
10571   };
10572   return waserr;
10573 }
10574 
10575 /*.......................................................................
10576  * The callback through which all terminal output is routed.
10577  * This simply appends characters to a queue buffer, which is
10578  * subsequently flushed to the output channel by gl_flush_output().
10579  *
10580  * Input:
10581  *  data     void *  The pointer to a GetLine line editor resource object
10582  *                   cast to (void *).
10583  *  s  const char *  The string to be written.
10584  *  n         int    The number of characters to write from s[].
10585  * Output:
10586  *  return    int    The number of characters written. This will always
10587  *                   be equal to 'n' unless an error occurs.
10588  */
10589 static GL_WRITE_FN(gl_write_fn)
10590 {
10591   GetLine *gl = (GetLine *) data;
10592   int ndone = _glq_append_chars(gl->cq, s, n, gl->flush_fn, gl);
10593   if(ndone != n)
10594     _err_record_msg(gl->err, _glq_last_error(gl->cq), END_ERR_MSG);
10595   return ndone;
10596 }
10597 
10598 /*.......................................................................
10599  * Ask gl_get_line() what caused it to return.
10600  *
10601  * Input:
10602  *  gl             GetLine *  The line editor resource object.
10603  * Output:
10604  *  return  GlReturnStatus    The return status of the last call to
10605  *                            gl_get_line().
10606  */
10607 GlReturnStatus gl_return_status(GetLine *gl)
10608 {
10609   GlReturnStatus rtn_status = GLR_ERROR;   /* The requested status */
10610   if(gl) {
10611     sigset_t oldset; /* The signals that were blocked on entry to this block */
10612 /*
10613  * Temporarily block all signals.
10614  */
10615     gl_mask_signals(gl, &oldset);
10616 /*
10617  * Access gl while signals are blocked.
10618  */
10619     rtn_status = gl->rtn_status;
10620 /*
10621  * Restore the process signal mask before returning.
10622  */
10623     gl_unmask_signals(gl, &oldset);
10624   };
10625   return rtn_status;
10626 }
10627 
10628 /*.......................................................................
10629  * In non-blocking server-I/O mode, this function should be called
10630  * from the application's external event loop to see what type of
10631  * terminal I/O is being waited for by gl_get_line(), and thus what
10632  * direction of I/O to wait for with select() or poll().
10633  *
10634  * Input:
10635  *  gl          GetLine *  The resource object of gl_get_line().
10636  * Output:
10637  *  return  GlPendingIO    The type of pending I/O being waited for.
10638  */
10639 GlPendingIO gl_pending_io(GetLine *gl)
10640 {
10641   GlPendingIO pending_io = GLP_WRITE;   /* The requested information */
10642   if(gl) {
10643     sigset_t oldset; /* The signals that were blocked on entry to this block */
10644 /*
10645  * Temporarily block all signals.
10646  */
10647     gl_mask_signals(gl, &oldset);
10648 /*
10649  * Access gl while signals are blocked.
10650  */
10651     pending_io = gl->pending_io;
10652 /*
10653  * Restore the process signal mask before returning.
10654  */
10655     gl_unmask_signals(gl, &oldset);
10656   };
10657   return pending_io;
10658 }
10659 
10660 /*.......................................................................
10661  * In server mode, this function configures the terminal for non-blocking
10662  * raw terminal I/O. In normal I/O mode it does nothing.
10663  *
10664  * Callers of this function must be careful to trap all signals that
10665  * terminate or suspend the program, and call gl_normal_io()
10666  * from the corresponding signal handlers in order to restore the
10667  * terminal to its original settings before the program is terminated
10668  * or suspended. They should also trap the SIGCONT signal to detect
10669  * when the program resumes, and ensure that its signal handler
10670  * call gl_raw_io() to redisplay the line and resume editing.
10671  *
10672  * This function is async signal safe.
10673  *
10674  * Input:
10675  *  gl      GetLine *  The line editor resource object.
10676  * Output:
10677  *  return      int    0 - OK.
10678  *                     1 - Error.
10679  */
10680 int gl_raw_io(GetLine *gl)
10681 {
10682   sigset_t oldset; /* The signals that were blocked on entry to this function */
10683   int status;      /* The return status of _gl_raw_io() */
10684 /*
10685  * Check the arguments.
10686  */
10687   if(!gl) {
10688     errno = EINVAL;
10689     return 1;
10690   };
10691 /*
10692  * Block all signals.
10693  */
10694   if(gl_mask_signals(gl, &oldset))
10695     return 1;
10696 /*
10697  * Don't allow applications to switch into raw mode unless in server mode.
10698  */
10699   if(gl->io_mode != GL_SERVER_MODE) {
10700     _err_record_msg(gl->err, "Can't switch to raw I/O unless in server mode",
10701 		    END_ERR_MSG);
10702     errno = EPERM;
10703     status = 1;
10704   } else {
10705 /*
10706  * Execute the private body of the function while signals are blocked.
10707  */
10708     status = _gl_raw_io(gl, 1);
10709   };
10710 /*
10711  * Restore the process signal mask.
10712  */
10713   gl_unmask_signals(gl, &oldset);
10714   return status;
10715 }
10716 
10717 /*.......................................................................
10718  * This is the private body of the public function, gl_raw_io().
10719  * It assumes that the caller has checked its arguments and blocked the
10720  * delivery of signals.
10721  *
10722  * This function is async signal safe.
10723  */
10724 static int _gl_raw_io(GetLine *gl, int redisplay)
10725 {
10726 /*
10727  * If we are already in the correct mode, do nothing.
10728  */
10729   if(gl->raw_mode)
10730     return 0;
10731 /*
10732  * Switch the terminal to raw mode.
10733  */
10734   if(gl->is_term && gl_raw_terminal_mode(gl))
10735     return 1;
10736 /*
10737  * Switch to non-blocking I/O mode?
10738  */
10739   if(gl->io_mode==GL_SERVER_MODE &&
10740      (gl_nonblocking_io(gl, gl->input_fd) ||
10741       gl_nonblocking_io(gl, gl->output_fd) ||
10742       (gl->file_fp && gl_nonblocking_io(gl, fileno(gl->file_fp))))) {
10743     if(gl->is_term)
10744       gl_restore_terminal_attributes(gl);
10745     return 1;
10746   };
10747 /*
10748  * If an input line is being entered, arrange for it to be
10749  * displayed.
10750  */
10751   if(redisplay) {
10752     gl->postpone = 0;
10753     gl_queue_redisplay(gl);
10754   };
10755   return 0;
10756 }
10757 
10758 /*.......................................................................
10759  * Restore the terminal to the state that it had when
10760  * gl_raw_io() was last called. After calling
10761  * gl_raw_io(), this function must be called before
10762  * terminating or suspending the program, and before attempting other
10763  * uses of the terminal from within the program. See gl_raw_io()
10764  * for more details.
10765  *
10766  * Input:
10767  *  gl      GetLine *  The line editor resource object.
10768  * Output:
10769  *  return      int    0 - OK.
10770  *                     1 - Error.
10771  */
10772 int gl_normal_io(GetLine *gl)
10773 {
10774   sigset_t oldset; /* The signals that were blocked on entry to this function */
10775   int status;      /* The return status of _gl_normal_io() */
10776 /*
10777  * Check the arguments.
10778  */
10779   if(!gl) {
10780     errno = EINVAL;
10781     return 1;
10782   };
10783 /*
10784  * Block all signals.
10785  */
10786   if(gl_mask_signals(gl, &oldset))
10787     return 1;
10788 /*
10789  * Execute the private body of the function while signals are blocked.
10790  */
10791   status = _gl_normal_io(gl);
10792 /*
10793  * Restore the process signal mask.
10794  */
10795   gl_unmask_signals(gl, &oldset);
10796   return status;
10797 }
10798 
10799 /*.......................................................................
10800  * This is the private body of the public function, gl_normal_io().
10801  * It assumes that the caller has checked its arguments and blocked the
10802  * delivery of signals.
10803  */
10804 static int _gl_normal_io(GetLine *gl)
10805 {
10806 /*
10807  * If we are already in normal mode, do nothing.
10808  */
10809   if(!gl->raw_mode)
10810     return 0;
10811 /*
10812  * Postpone subsequent redisplays until after _gl_raw_io(gl, 1)
10813  * is next called.
10814  */
10815   gl->postpone = 1;
10816 /*
10817  * Switch back to blocking I/O. Note that this is essential to do
10818  * here, because when using non-blocking I/O, the terminal output
10819  * buffering code can't always make room for new output without calling
10820  * malloc(), and a call to malloc() would mean that this function
10821  * couldn't safely be called from signal handlers.
10822  */
10823   if(gl->io_mode==GL_SERVER_MODE &&
10824      (gl_blocking_io(gl, gl->input_fd) ||
10825       gl_blocking_io(gl, gl->output_fd) ||
10826       (gl->file_fp && gl_blocking_io(gl, fileno(gl->file_fp)))))
10827     return 1;
10828 /*
10829  * Move the cursor to the next empty terminal line. Note that
10830  * unbuffered I/O is requested, to ensure that gl_start_newline() be
10831  * async-signal-safe.
10832  */
10833   if(gl->is_term && gl_start_newline(gl, 0))
10834     return 1;
10835 /*
10836  * Switch the terminal to normal mode.
10837  */
10838   if(gl->is_term && gl_restore_terminal_attributes(gl)) {
10839 /*
10840  * On error, revert to non-blocking I/O if needed, so that on failure
10841  * we remain in raw mode.
10842  */
10843     if(gl->io_mode==GL_SERVER_MODE) {
10844       gl_nonblocking_io(gl, gl->input_fd);
10845       gl_nonblocking_io(gl, gl->output_fd);
10846       if(gl->file_fp)
10847 	gl_nonblocking_io(gl, fileno(gl->file_fp));
10848     };
10849     return 1;
10850   };
10851   return 0;
10852 }
10853 
10854 /*.......................................................................
10855  * This function allows you to install an additional completion
10856  * action, or to change the completion function of an existing
10857  * one. This should be called before the first call to gl_get_line()
10858  * so that the name of the action be defined before the user's
10859  * configuration file is read.
10860  *
10861  * Input:
10862  *  gl            GetLine *  The resource object of the command-line input
10863  *                           module.
10864  *  data             void *  This is passed to match_fn() whenever it is
10865  *                           called. It could, for example, point to a
10866  *                           symbol table that match_fn() would look up
10867  *                           matches in.
10868  *  match_fn   CplMatchFn *  The function that will identify the prefix
10869  *                           to be completed from the input line, and
10870  *                           report matching symbols.
10871  *  list_only         int    If non-zero, install an action that only lists
10872  *                           possible completions, rather than attempting
10873  *                           to perform the completion.
10874  *  name       const char *  The name with which users can refer to the
10875  *                           binding in tecla configuration files.
10876  *  keyseq     const char *  Either NULL, or a key sequence with which
10877  *                           to invoke the binding. This should be
10878  *                           specified in the same manner as key-sequences
10879  *                           in tecla configuration files (eg. "M-^I").
10880  * Output:
10881  *  return            int    0 - OK.
10882  *                           1 - Error.
10883  */
10884 int gl_completion_action(GetLine *gl, void *data, CplMatchFn *match_fn,
10885 			 int list_only, const char *name, const char *keyseq)
10886 {
10887   sigset_t oldset; /* The signals that were blocked on entry to this function */
10888   int status;      /* The return status of _gl_completion_action() */
10889 /*
10890  * Check the arguments.
10891  */
10892   if(!gl || !name || !match_fn) {
10893     errno = EINVAL;
10894     return 1;
10895   };
10896 /*
10897  * Block all signals.
10898  */
10899   if(gl_mask_signals(gl, &oldset))
10900     return 1;
10901 /*
10902  * Install the new action while signals are blocked.
10903  */
10904   status = _gl_completion_action(gl, data, match_fn, list_only, name, keyseq);
10905 /*
10906  * Restore the process signal mask.
10907  */
10908   gl_unmask_signals(gl, &oldset);
10909   return status;
10910 }
10911 
10912 /*.......................................................................
10913  * This is the private body of the public function, gl_completion_action().
10914  * It assumes that the caller has checked its arguments and blocked the
10915  * delivery of signals.
10916  */
10917 static int _gl_completion_action(GetLine *gl, void *data, CplMatchFn *match_fn,
10918 				 int list_only, const char *name,
10919 				 const char *keyseq)
10920 {
10921   KtKeyFn *current_fn;      /* An existing action function */
10922   void *current_data;       /* The action-function callback data */
10923 /*
10924  * Which action function is desired?
10925  */
10926   KtKeyFn *action_fn = list_only ? gl_list_completions : gl_complete_word;
10927 /*
10928  * Is there already an action of the specified name?
10929  */
10930   if(_kt_lookup_action(gl->bindings, name, &current_fn, &current_data) == 0) {
10931 /*
10932  * If the action has the same type as the one being requested,
10933  * simply change the contents of its GlCplCallback callback data.
10934  */
10935     if(current_fn == action_fn) {
10936       GlCplCallback *cb = (GlCplCallback *) current_data;
10937       cb->fn = match_fn;
10938       cb->data = data;
10939     } else {
10940       errno = EINVAL;
10941       _err_record_msg(gl->err,
10942         "Illegal attempt to change the type of an existing completion action",
10943         END_ERR_MSG);
10944       return 1;
10945     };
10946 /*
10947  * No existing action has the specified name.
10948  */
10949   } else {
10950 /*
10951  * Allocate a new GlCplCallback callback object.
10952  */
10953     GlCplCallback *cb = (GlCplCallback *) _new_FreeListNode(gl->cpl_mem);
10954     if(!cb) {
10955       errno = ENOMEM;
10956       _err_record_msg(gl->err, "Insufficient memory to add completion action",
10957 		      END_ERR_MSG);
10958       return 1;
10959     };
10960 /*
10961  * Record the completion callback data.
10962  */
10963     cb->fn = match_fn;
10964     cb->data = data;
10965 /*
10966  * Attempt to register the new action.
10967  */
10968     if(_kt_set_action(gl->bindings, name, action_fn, cb)) {
10969       _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
10970       _del_FreeListNode(gl->cpl_mem, (void *) cb);
10971       return 1;
10972     };
10973   };
10974 /*
10975  * Bind the action to a given key-sequence?
10976  */
10977   if(keyseq && _kt_set_keybinding(gl->bindings, KTB_NORM, keyseq, name)) {
10978     _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
10979     return 1;
10980   };
10981   return 0;
10982 }
10983 
10984 /*.......................................................................
10985  * Register an application-provided function as an action function.
10986  * This should preferably be called before the first call to gl_get_line()
10987  * so that the name of the action becomes defined before the user's
10988  * configuration file is read.
10989  *
10990  * Input:
10991  *  gl            GetLine *  The resource object of the command-line input
10992  *                           module.
10993  *  data             void *  Arbitrary application-specific callback
10994  *                           data to be passed to the callback
10995  *                           function, fn().
10996  *  fn         GlActionFn *  The application-specific function that
10997  *                           implements the action. This will be invoked
10998  *                           whenever the user presses any
10999  *                           key-sequence which is bound to this action.
11000  *  name       const char *  The name with which users can refer to the
11001  *                           binding in tecla configuration files.
11002  *  keyseq     const char *  The key sequence with which to invoke
11003  *                           the binding. This should be specified in the
11004  *                           same manner as key-sequences in tecla
11005  *                           configuration files (eg. "M-^I").
11006  * Output:
11007  *  return            int    0 - OK.
11008  *                           1 - Error.
11009  */
11010 int gl_register_action(GetLine *gl, void *data, GlActionFn *fn,
11011                        const char *name, const char *keyseq)
11012 {
11013   sigset_t oldset; /* The signals that were blocked on entry to this function */
11014   int status;      /* The return status of _gl_register_action() */
11015 /*
11016  * Check the arguments.
11017  */
11018   if(!gl || !name || !fn) {
11019     errno = EINVAL;
11020     return 1;
11021   };
11022 /*
11023  * Block all signals.
11024  */
11025   if(gl_mask_signals(gl, &oldset))
11026     return 1;
11027 /*
11028  * Install the new action while signals are blocked.
11029  */
11030   status = _gl_register_action(gl, data, fn, name, keyseq);
11031 /*
11032  * Restore the process signal mask.
11033  */
11034   gl_unmask_signals(gl, &oldset);
11035   return status;
11036 }
11037 
11038 /*.......................................................................
11039  * This is the private body of the public function, gl_register_action().
11040  * It assumes that the caller has checked its arguments and blocked the
11041  * delivery of signals.
11042  */
11043 static int _gl_register_action(GetLine *gl, void *data, GlActionFn *fn,
11044 			       const char *name, const char *keyseq)
11045 {
11046   KtKeyFn *current_fn;      /* An existing action function */
11047   void *current_data;       /* The action-function callback data */
11048 /*
11049  * Get the action function which actually runs the application-provided
11050  * function.
11051  */
11052   KtKeyFn *action_fn = gl_run_external_action;
11053 /*
11054  * Is there already an action of the specified name?
11055  */
11056   if(_kt_lookup_action(gl->bindings, name, &current_fn, &current_data) == 0) {
11057 /*
11058  * If the action has the same type as the one being requested,
11059  * simply change the contents of its GlCplCallback callback data.
11060  */
11061     if(current_fn == action_fn) {
11062       GlExternalAction *a = (GlExternalAction *) current_data;
11063       a->fn = fn;
11064       a->data = data;
11065     } else {
11066       errno = EINVAL;
11067       _err_record_msg(gl->err,
11068         "Illegal attempt to change the type of an existing action",
11069 		      END_ERR_MSG);
11070       return 1;
11071     };
11072 /*
11073  * No existing action has the specified name.
11074  */
11075   } else {
11076 /*
11077  * Allocate a new GlCplCallback callback object.
11078  */
11079     GlExternalAction *a =
11080       (GlExternalAction *) _new_FreeListNode(gl->ext_act_mem);
11081     if(!a) {
11082       errno = ENOMEM;
11083       _err_record_msg(gl->err, "Insufficient memory to add completion action",
11084 		      END_ERR_MSG);
11085       return 1;
11086     };
11087 /*
11088  * Record the completion callback data.
11089  */
11090     a->fn = fn;
11091     a->data = data;
11092 /*
11093  * Attempt to register the new action.
11094  */
11095     if(_kt_set_action(gl->bindings, name, action_fn, a)) {
11096       _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
11097       _del_FreeListNode(gl->cpl_mem, (void *) a);
11098       return 1;
11099     };
11100   };
11101 /*
11102  * Bind the action to a given key-sequence?
11103  */
11104   if(keyseq && _kt_set_keybinding(gl->bindings, KTB_NORM, keyseq, name)) {
11105     _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
11106     return 1;
11107   };
11108   return 0;
11109 }
11110 
11111 /*.......................................................................
11112  * Invoke an action function previously registered by a call to
11113  * gl_register_action().
11114  */
11115 static KT_KEY_FN(gl_run_external_action)
11116 {
11117   GlAfterAction status;  /* The return value of the action function */
11118 /*
11119  * Get the container of the action function and associated callback data.
11120  */
11121   GlExternalAction *a = (GlExternalAction *) data;
11122 /*
11123  * Invoke the action function.
11124  */
11125   status = a->fn(gl, a->data, count, gl->buff_curpos, gl->line);
11126 /*
11127  * If the callback took us out of raw (possibly non-blocking) input
11128  * mode, restore this mode, and queue a redisplay of the input line.
11129  */
11130   if(_gl_raw_io(gl, 1))
11131     return 1;
11132 /*
11133  * Finally, check to see what the action function wants us to do next.
11134  */
11135   switch(status) {
11136   default:
11137   case GLA_ABORT:
11138     gl_record_status(gl, GLR_ERROR, errno);
11139     return 1;
11140     break;
11141   case GLA_RETURN:
11142     return gl_newline(gl, 1, NULL);
11143     break;
11144   case GLA_CONTINUE:
11145     break;
11146   };
11147   return 0;
11148 }
11149 
11150 /*.......................................................................
11151  * In server-I/O mode the terminal is left in raw mode between calls
11152  * to gl_get_line(), so it is necessary for the application to install
11153  * terminal restoring signal handlers for signals that could terminate
11154  * or suspend the process, plus a terminal reconfiguration handler to
11155  * be called when a process resumption signal is received, and finally
11156  * a handler to be called when a terminal-resize signal is received.
11157  *
11158  * Since there are many signals that by default terminate or suspend
11159  * processes, and different systems support different sub-sets of
11160  * these signals, this function provides a convenient wrapper around
11161  * sigaction() for assigning the specified handlers to all appropriate
11162  * signals. It also arranges that when any one of these signals is
11163  * being handled, all other catchable signals are blocked. This is
11164  * necessary so that the specified signal handlers can safely call
11165  * gl_raw_io(), gl_normal_io() and gl_update_size() without
11166  * reentrancy issues.
11167  *
11168  * Input:
11169  *  term_handler  void (*)(int)  The signal handler to invoke when
11170  *                               a process terminating signal is
11171  *                               received.
11172  *  susp_handler  void (*)(int)  The signal handler to invoke when
11173  *                               a process suspending signal is
11174  *                               received.
11175  *  cont_handler  void (*)(int)  The signal handler to invoke when
11176  *                               a process resumption signal is
11177  *                               received (ie. SIGCONT).
11178  *  size_handler  void (*)(int)  The signal handler to invoke when
11179  *                               a terminal-resize signal (ie. SIGWINCH)
11180  *                               is received.
11181  * Output:
11182  *  return                  int  0 - OK.
11183  *                               1 - Error.
11184  */
11185 int gl_tty_signals(void (*term_handler)(int), void (*susp_handler)(int),
11186 		   void (*cont_handler)(int), void (*size_handler)(int))
11187 {
11188   int i;
11189 /*
11190  * Search for signals of the specified classes, and assign the
11191  * associated signal handler to them.
11192  */
11193   for(i=0; i<sizeof(gl_signal_list)/sizeof(gl_signal_list[0]); i++) {
11194     const struct GlDefSignal *sig = gl_signal_list + i;
11195     if(sig->attr & GLSA_SUSP) {
11196       if(gl_set_tty_signal(sig->signo, term_handler))
11197 	return 1;
11198     } else if(sig->attr & GLSA_TERM) {
11199       if(gl_set_tty_signal(sig->signo, susp_handler))
11200 	return 1;
11201     } else if(sig->attr & GLSA_CONT) {
11202       if(gl_set_tty_signal(sig->signo, cont_handler))
11203 	return 1;
11204     } else if(sig->attr & GLSA_SIZE) {
11205       if(gl_set_tty_signal(sig->signo, size_handler))
11206 	return 1;
11207     };
11208   };
11209   return 0;
11210 }
11211 
11212 /*.......................................................................
11213  * This is a private function of gl_tty_signals(). It installs a given
11214  * signal handler, and arranges that when that signal handler is being
11215  * invoked other signals are blocked. The latter is important to allow
11216  * functions like gl_normal_io(), gl_raw_io() and gl_update_size()
11217  * to be called from signal handlers.
11218  *
11219  * Input:
11220  *  signo     int           The signal to be trapped.
11221  *  handler  void (*)(int)  The signal handler to assign to the signal.
11222  */
11223 static int gl_set_tty_signal(int signo, void (*handler)(int))
11224 {
11225   SigAction act;   /* The signal handler configuation */
11226 /*
11227  * Arrange to block all trappable signals except the one that is being
11228  * assigned (the trapped signal will be blocked automatically by the
11229  * system).
11230  */
11231   gl_list_trappable_signals(&act.sa_mask);
11232   sigdelset(&act.sa_mask, signo);
11233 /*
11234  * Assign the signal handler.
11235  */
11236   act.sa_handler = handler;
11237 /*
11238  * There is only one portable signal handling flag, and it isn't
11239  * relevant to us, so don't specify any flags.
11240  */
11241   act.sa_flags = 0;
11242 /*
11243  * Register the signal handler.
11244  */
11245   if(sigaction(signo, &act, NULL))
11246     return 1;
11247   return 0;
11248 }
11249 
11250 /*.......................................................................
11251  * Display a left-justified string over multiple terminal lines,
11252  * taking account of the current width of the terminal. Optional
11253  * indentation and an optional prefix string can be specified to be
11254  * displayed at the start of each new terminal line used. Similarly,
11255  * an optional suffix can be specified to be displayed at the end of
11256  * each terminal line.  If needed, a single paragraph can be broken
11257  * across multiple calls.  Note that literal newlines in the input
11258  * string can be used to force a newline at any point and that you
11259  * should use this feature to explicitly end all paragraphs, including
11260  * at the end of the last string that you write. Note that when a new
11261  * line is started between two words that are separated by spaces,
11262  * those spaces are not output, whereas when a new line is started
11263  * because a newline character was found in the string, only the
11264  * spaces before the newline character are discarded.
11265  *
11266  * Input:
11267  *  gl         GetLine *  The resource object of gl_get_line().
11268  *  indentation    int    The number of spaces of indentation to write
11269  *                        at the beginning of each new terminal line.
11270  *  prefix  const char *  An optional prefix string to write after the
11271  *                        indentation margin at the start of each new
11272  *                        terminal line. You can specify NULL if no
11273  *                        prefix is required.
11274  *  suffix  const char *  An optional suffix string to draw at the end
11275  *                        of the terminal line. Spaces will be added
11276  *                        where necessary to ensure that the suffix ends
11277  *                        in the last column of the terminal line. If
11278  *                        no suffix is desired, specify NULL.
11279  *  fill_char      int    The padding character to use when indenting
11280  *                        the line or padding up to the suffix.
11281  *  def_width      int    If the terminal width isn't known, such as when
11282  *                        writing to a pipe or redirecting to a file,
11283  *                        this number specifies what width to assume.
11284  *  start          int    The number of characters already written to
11285  *                        the start of the current terminal line. This
11286  *                        is primarily used to allow individual
11287  *                        paragraphs to be written over multiple calls
11288  *                        to this function, but can also be used to
11289  *                        allow you to start the first line of a
11290  *                        paragraph with a different prefix or
11291  *                        indentation than those specified above.
11292  *  string  const char *  The string to be written.
11293  * Output:
11294  *  return         int    On error -1 is returned. Otherwise the
11295  *                        return value is the terminal column index at
11296  *                        which the cursor was left after writing the
11297  *                        final word in the string. Successful return
11298  *                        values can thus be passed verbatim to the
11299  *                        'start' arguments of subsequent calls to
11300  *                        gl_display_text() to allow the printing of a
11301  *                        paragraph to be broken across multiple calls
11302  *                        to gl_display_text().
11303  */
11304 int gl_display_text(GetLine *gl, int indentation, const char *prefix,
11305 		    const char *suffix, int fill_char,
11306 		    int def_width, int start, const char *string)
11307 {
11308   sigset_t oldset; /* The signals that were blocked on entry to this function */
11309   int status;      /* The return status of _gl_completion_action() */
11310 /*
11311  * Check the arguments?
11312  */
11313   if(!gl || !string) {
11314     errno = EINVAL;
11315     return -1;
11316   };
11317 /*
11318  * Block all signals.
11319  */
11320   if(gl_mask_signals(gl, &oldset))
11321     return -1;
11322 /*
11323  * Display the text while signals are blocked.
11324  */
11325   status = _io_display_text(_io_write_stdio, gl->output_fp, indentation,
11326 			    prefix, suffix, fill_char,
11327 			    gl->ncolumn > 0 ? gl->ncolumn : def_width,
11328 			    start, string);
11329 /*
11330  * Restore the process signal mask.
11331  */
11332   gl_unmask_signals(gl, &oldset);
11333   return status;
11334 }
11335 
11336 /*.......................................................................
11337  * Block all of the signals that we are currently trapping.
11338  *
11339  * Input:
11340  *  gl       GetLine *   The resource object of gl_get_line().
11341  * Input/Output:
11342  *  oldset   sigset_t *   The superseded process signal mask
11343  *                        will be return in *oldset unless oldset is
11344  *                        NULL.
11345  * Output:
11346  *  return        int     0 - OK.
11347  *                        1 - Error.
11348  */
11349 static int gl_mask_signals(GetLine *gl, sigset_t *oldset)
11350 {
11351 /*
11352  * Block all signals in all_signal_set, along with any others that are
11353  * already blocked by the application.
11354  */
11355   if(sigprocmask(SIG_BLOCK, &gl->all_signal_set, oldset) >= 0) {
11356     gl->signals_masked = 1;
11357     return 0;
11358   };
11359 /*
11360  * On error attempt to query the current process signal mask, so
11361  * that oldset be the correct process signal mask to restore later
11362  * if the caller of this function ignores the error return value.
11363  */
11364   if(oldset)
11365     (void) sigprocmask(SIG_SETMASK, NULL, oldset);
11366   gl->signals_masked = 0;
11367   return 1;
11368 }
11369 
11370 /*.......................................................................
11371  * Restore a process signal mask that was previously returned via the
11372  * oldset argument of gl_mask_signals().
11373  *
11374  * Input:
11375  *  gl        GetLine *   The resource object of gl_get_line().
11376  * Input/Output:
11377  *  oldset   sigset_t *   The process signal mask to be restored.
11378  * Output:
11379  *  return        int     0 - OK.
11380  *                        1 - Error.
11381  */
11382 static int gl_unmask_signals(GetLine *gl, sigset_t *oldset)
11383 {
11384   gl->signals_masked = 0;
11385   return sigprocmask(SIG_SETMASK, oldset, NULL) < 0;
11386 }
11387 
11388 /*.......................................................................
11389  * Arrange to temporarily catch the signals marked in gl->use_signal_set.
11390  *
11391  * Input:
11392  *  gl        GetLine *   The resource object of gl_get_line().
11393  * Output:
11394  *  return        int     0 - OK.
11395  *                        1 - Error.
11396  */
11397 static int gl_catch_signals(GetLine *gl)
11398 {
11399   return sigprocmask(SIG_UNBLOCK, &gl->use_signal_set, NULL) < 0;
11400 }
11401 
11402 /*.......................................................................
11403  * Select the I/O mode to be used by gl_get_line().
11404  *
11405  * Input:
11406  *  gl         GetLine *  The resource object of gl_get_line().
11407  *  mode      GlIOMode    The I/O mode to establish.
11408  * Output:
11409  *  return         int    0 - OK.
11410  *                        1 - Error.
11411  */
11412 int gl_io_mode(GetLine *gl, GlIOMode mode)
11413 {
11414   sigset_t oldset; /* The signals that were blocked on entry to this function */
11415   int status;      /* The return status of _gl_io_mode() */
11416 /*
11417  * Check the arguments.
11418  */
11419   if(!gl) {
11420     errno = EINVAL;
11421     return 1;
11422   };
11423 /*
11424  * Check that the requested mode is known.
11425  */
11426   switch(mode) {
11427   case GL_NORMAL_MODE:
11428   case GL_SERVER_MODE:
11429     break;
11430   default:
11431     errno = EINVAL;
11432     _err_record_msg(gl->err, "Unknown gl_get_line() I/O mode requested.",
11433 		    END_ERR_MSG);
11434     return 1;
11435   };
11436 /*
11437  * Block all signals.
11438  */
11439   if(gl_mask_signals(gl, &oldset))
11440     return 1;
11441 /*
11442  * Invoke the private body of this function.
11443  */
11444   status = _gl_io_mode(gl, mode);
11445 /*
11446  * Restore the process signal mask.
11447  */
11448   gl_unmask_signals(gl, &oldset);
11449   return status;
11450 }
11451 
11452 /*.......................................................................
11453  * This is the private body of the public function, gl_io_mode().
11454  * It assumes that the caller has checked its arguments and blocked the
11455  * delivery of signals.
11456  */
11457 static int _gl_io_mode(GetLine *gl, GlIOMode mode)
11458 {
11459 /*
11460  * Are we already in the specified mode?
11461  */
11462   if(mode == gl->io_mode)
11463     return 0;
11464 /*
11465  * First revert to normal I/O in the current I/O mode.
11466  */
11467   _gl_normal_io(gl);
11468 /*
11469  * Record the new mode.
11470  */
11471   gl->io_mode = mode;
11472 /*
11473  * Perform any actions needed by the new mode.
11474  */
11475   if(mode==GL_SERVER_MODE) {
11476     if(_gl_raw_io(gl, 1))
11477       return 1;
11478   };
11479   return 0;
11480 }
11481 
11482 /*.......................................................................
11483  * Return extra information (ie. in addition to that provided by errno)
11484  * about the last error to occur in either gl_get_line() or its
11485  * associated public functions.
11486  *
11487  * Input:
11488  *  gl         GetLine *  The resource object of gl_get_line().
11489  * Input/Output:
11490  *  buff          char *  An optional output buffer. Note that if the
11491  *                        calling application calls any gl_*()
11492  *                        functions from signal handlers, it should
11493  *                        provide a buffer here, so that a copy of
11494  *                        the latest error message can safely be made
11495  *                        while signals are blocked.
11496  *  n           size_t    The allocated size of buff[].
11497  * Output:
11498  *  return  const char *  A pointer to the error message. This will
11499  *                        be the buff argument, unless buff==NULL, in
11500  *                        which case it will be a pointer to an
11501  *                        internal error buffer. In the latter case,
11502  *                        note that the contents of the returned buffer
11503  *                        will change on subsequent calls to any gl_*()
11504  *                        functions.
11505  */
11506 const char *gl_error_message(GetLine *gl, char *buff, size_t n)
11507 {
11508   if(!gl) {
11509     static const char *msg = "NULL GetLine argument";
11510     if(buff) {
11511       strncpy(buff, msg, n);
11512       buff[n-1] = '\0';
11513     } else {
11514       return msg;
11515     };
11516   } else if(buff) {
11517     sigset_t oldset; /* The signals that were blocked on entry to this block */
11518 /*
11519  * Temporarily block all signals.
11520  */
11521     gl_mask_signals(gl, &oldset);
11522 /*
11523  * Copy the error message into the specified buffer.
11524  */
11525     if(buff && n > 0) {
11526       strncpy(buff, _err_get_msg(gl->err), n);
11527       buff[n-1] = '\0';
11528     };
11529 /*
11530  * Restore the process signal mask before returning.
11531  */
11532     gl_unmask_signals(gl, &oldset);
11533   } else {
11534     return _err_get_msg(gl->err);
11535   };
11536   return buff;
11537 }
11538 
11539 /*.......................................................................
11540  * Return the signal mask used by gl_get_line(). This is the set of
11541  * signals that gl_get_line() is currently configured to trap.
11542  *
11543  * Input:
11544  *  gl         GetLine *  The resource object of gl_get_line().
11545  * Input/Output:
11546  *  set       sigset_t *  The set of signals will be returned in *set,
11547  *                        in the form of a signal process mask, as
11548  *                        used by sigaction(), sigprocmask(),
11549  *                        sigpending(), sigsuspend(), sigsetjmp() and
11550  *                        other standard POSIX signal-aware
11551  *                        functions.
11552  * Output:
11553  *  return         int    0 - OK.
11554  *                        1 - Error (examine errno for reason).
11555  */
11556 int gl_list_signals(GetLine *gl, sigset_t *set)
11557 {
11558 /*
11559  * Check the arguments.
11560  */
11561   if(!gl || !set) {
11562     if(gl)
11563       _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
11564     errno = EINVAL;
11565     return 1;
11566   };
11567 /*
11568  * Copy the signal mask into *set.
11569  */
11570   memcpy(set, &gl->all_signal_set, sizeof(*set));
11571   return 0;
11572 }
11573 
11574 /*.......................................................................
11575  * By default, gl_get_line() doesn't trap signals that are blocked
11576  * when it is called. This default can be changed either on a
11577  * per-signal basis by calling gl_trap_signal(), or on a global basis
11578  * by calling this function. What this function does is add the
11579  * GLS_UNBLOCK_SIG flag to all signals that are currently configured
11580  * to be trapped by gl_get_line(), such that when subsequent calls to
11581  * gl_get_line() wait for I/O, these signals are temporarily
11582  * unblocked. This behavior is useful in non-blocking server-I/O mode,
11583  * where it is used to avoid race conditions related to handling these
11584  * signals externally to gl_get_line(). See the demonstration code in
11585  * demo3.c, or the gl_handle_signal() man page for further
11586  * information.
11587  *
11588  * Input:
11589  *  gl         GetLine *   The resource object of gl_get_line().
11590  */
11591 void gl_catch_blocked(GetLine *gl)
11592 {
11593   sigset_t oldset;    /* The process signal mask to restore */
11594   GlSignalNode *sig;  /* A signal node in gl->sigs */
11595 /*
11596  * Check the arguments.
11597  */
11598   if(!gl) {
11599     errno = EINVAL;
11600     return;
11601   };
11602 /*
11603  * Temporarily block all signals while we modify the contents of gl.
11604  */
11605   gl_mask_signals(gl, &oldset);
11606 /*
11607  * Add the GLS_UNBLOCK_SIG flag to all configured signals.
11608  */
11609   for(sig=gl->sigs; sig; sig=sig->next)
11610     sig->flags |= GLS_UNBLOCK_SIG;
11611 /*
11612  * Restore the process signal mask that was superseded by the call
11613  * to gl_mask_signals().
11614  */
11615   gl_unmask_signals(gl, &oldset);
11616   return;
11617 }
11618 
11619 /*.......................................................................
11620  * Respond to signals who's default effects have important
11621  * consequences to gl_get_line(). This is intended for use in
11622  * non-blocking server mode, where the external event loop is
11623  * responsible for catching signals. Signals that are handled include
11624  * those that by default terminate or suspend the process, and the
11625  * signal that indicates that the terminal size has changed. Note that
11626  * this function is not signal safe and should thus not be called from
11627  * a signal handler itself. See the gl_io_mode() man page for how it
11628  * should be used.
11629  *
11630  * In the case of signals that by default terminate or suspend
11631  * processes, command-line editing will be suspended, the terminal
11632  * returned to a usable state, then the default disposition of the
11633  * signal restored and the signal resent, in order to suspend or
11634  * terminate the process.  If the process subsequently resumes,
11635  * command-line editing is resumed.
11636  *
11637  * In the case of signals that indicate that the terminal has been
11638  * resized, the new size will be queried, and any input line that is
11639  * being edited will be redrawn to fit the new dimensions of the
11640  * terminal.
11641  *
11642  * Input:
11643  *  signo    int    The number of the signal to respond to.
11644  *  gl   GetLine *  The first element of an array of 'ngl' GetLine
11645  *                  objects.
11646  *  ngl      int    The number of elements in the gl[] array. Normally
11647  *                  this will be one.
11648  */
11649 void gl_handle_signal(int signo, GetLine *gl, int ngl)
11650 {
11651   int attr;             /* The attributes of the specified signal */
11652   sigset_t all_signals; /* The set of trappable signals */
11653   sigset_t oldset;      /* The process signal mask to restore */
11654   int i;
11655 /*
11656  * NULL operation?
11657  */
11658   if(ngl < 1 || !gl)
11659     return;
11660 /*
11661  * Look up the default attributes of the specified signal.
11662  */
11663   attr = gl_classify_signal(signo);
11664 /*
11665  * If the signal isn't known, we are done.
11666  */
11667   if(!attr)
11668     return;
11669 /*
11670  * Temporarily block all signals while we modify the gl objects.
11671  */
11672   gl_list_trappable_signals(&all_signals);
11673   sigprocmask(SIG_BLOCK, &all_signals, &oldset);
11674 /*
11675  * Suspend or terminate the process?
11676  */
11677   if(attr & (GLSA_SUSP | GLSA_TERM)) {
11678     gl_suspend_process(signo, gl, ngl);
11679 /*
11680  * Resize the terminal? Note that ioctl() isn't defined as being
11681  * signal safe, so we can't call gl_update_size() here. However,
11682  * gl_get_line() checks for resizes on each call, so simply arrange
11683  * for the application's event loop to call gl_get_line() as soon as
11684  * it becomes possible to write to the terminal. Note that if the
11685  * caller is calling select() or poll when this happens, these functions
11686  * get interrupted, since a signal has been caught.
11687  */
11688   } else if(attr & GLSA_SIZE) {
11689     for(i=0; i<ngl; i++)
11690       gl[i].pending_io = GLP_WRITE;
11691   };
11692 /*
11693  * Restore the process signal mask that was superseded by the call
11694  * to gl_mask_signals().
11695  */
11696   sigprocmask(SIG_SETMASK, &oldset, NULL);
11697   return;
11698 }
11699 
11700 /*.......................................................................
11701  * Respond to an externally caught process suspension or
11702  * termination signal.
11703  *
11704  * After restoring the terminal to a usable state, suspend or
11705  * terminate the calling process, using the original signal with its
11706  * default disposition restored to do so. If the process subsequently
11707  * resumes, resume editing any input lines that were being entered.
11708  *
11709  * Input:
11710  *  signo    int    The signal number to suspend the process with. Note
11711  *                  that the default disposition of this signal will be
11712  *                  restored before the signal is sent, so provided
11713  *                  that the default disposition of this signal is to
11714  *                  either suspend or terminate the application,
11715  *                  that is what wil happen, regardless of what signal
11716  *                  handler is currently assigned to this signal.
11717  *  gl   GetLine *  The first element of an array of 'ngl' GetLine objects
11718  *                  whose terminals should be restored to a sane state
11719  *                  while the application is suspended.
11720  *  ngl      int    The number of elements in the gl[] array.
11721  */
11722 static void gl_suspend_process(int signo, GetLine *gl, int ngl)
11723 {
11724   sigset_t only_signo;          /* A signal set containing just signo */
11725   sigset_t oldset;              /* The signal mask on entry to this function */
11726   sigset_t all_signals;         /* A signal set containing all signals */
11727   struct sigaction old_action;  /* The current signal handler */
11728   struct sigaction def_action;  /* The default signal handler */
11729   int i;
11730 /*
11731  * Create a signal mask containing the signal that was trapped.
11732  */
11733   sigemptyset(&only_signo);
11734   sigaddset(&only_signo, signo);
11735 /*
11736  * Temporarily block all signals.
11737  */
11738   gl_list_trappable_signals(&all_signals);
11739   sigprocmask(SIG_BLOCK, &all_signals, &oldset);
11740 /*
11741  * Restore the terminal to a usable state.
11742  */
11743   for(i=0; i<ngl; i++) {
11744     GetLine *obj = gl + i;
11745     if(obj->raw_mode) {
11746       _gl_normal_io(obj);
11747       if(!obj->raw_mode)        /* Check that gl_normal_io() succeded */
11748 	obj->raw_mode = -1;     /* Flag raw mode as needing to be restored */
11749     };
11750   };
11751 /*
11752  * Restore the system default disposition of the signal that we
11753  * caught.  Note that this signal is currently blocked. Note that we
11754  * don't use memcpy() to copy signal sets here, because the signal safety
11755  * of memcpy() is undefined.
11756  */
11757   def_action.sa_handler = SIG_DFL;
11758   {
11759     char *orig = (char *) &all_signals;
11760     char *dest = (char *) &def_action.sa_mask;
11761     for(i=0; i<sizeof(sigset_t); i++)
11762       *dest++ = *orig++;
11763   };
11764   sigaction(signo, &def_action, &old_action);
11765 /*
11766  * Resend the signal, and unblock it so that it gets delivered to
11767  * the application. This will invoke the default action of this signal.
11768  */
11769   raise(signo);
11770   sigprocmask(SIG_UNBLOCK, &only_signo, NULL);
11771 /*
11772  * If the process resumes again, it will resume here.
11773  * Block the signal again, then restore our signal handler.
11774  */
11775   sigprocmask(SIG_BLOCK, &only_signo, NULL);
11776   sigaction(signo, &old_action, NULL);
11777 /*
11778  * Resume command-line editing.
11779  */
11780   for(i=0; i<ngl; i++) {
11781     GetLine *obj = gl + i;
11782     if(obj->raw_mode == -1) { /* Did we flag the need to restore raw mode? */
11783       obj->raw_mode = 0;      /* gl_raw_io() does nothing unless raw_mode==0 */
11784       _gl_raw_io(obj, 1);
11785     };
11786   };
11787 /*
11788  * Restore the process signal mask to the way it was when this function
11789  * was called.
11790  */
11791   sigprocmask(SIG_SETMASK, &oldset, NULL);
11792   return;
11793 }
11794 
11795 /*.......................................................................
11796  * Return the information about the default attributes of a given signal.
11797  * The attributes that are returned are as defined by the standards that
11798  * created them, including POSIX, SVR4 and 4.3+BSD, and are taken from a
11799  * table in Richard Steven's book, "Advanced programming in the UNIX
11800  * environment".
11801  *
11802  * Input:
11803  *  signo        int   The signal to be characterized.
11804  * Output:
11805  *  return       int   A bitwise union of GlSigAttr enumerators, or 0
11806  *                     if the signal isn't known.
11807  */
11808 static int gl_classify_signal(int signo)
11809 {
11810   int i;
11811 /*
11812  * Search for the specified signal in the gl_signal_list[] table.
11813  */
11814   for(i=0; i<sizeof(gl_signal_list)/sizeof(gl_signal_list[0]); i++) {
11815     const struct GlDefSignal *sig = gl_signal_list + i;
11816     if(sig->signo == signo)
11817       return sig->attr;
11818   };
11819 /*
11820  * Signal not known.
11821  */
11822   return 0;
11823 }
11824 
11825 /*.......................................................................
11826  * When in non-blocking server mode, this function can be used to abandon
11827  * the current incompletely entered input line, and prepare to start
11828  * editing a new line on the next call to gl_get_line().
11829  *
11830  * Input:
11831  *  gl      GetLine *  The line editor resource object.
11832  */
11833 void gl_abandon_line(GetLine *gl)
11834 {
11835   sigset_t oldset;    /* The process signal mask to restore */
11836 /*
11837  * Check the arguments.
11838  */
11839   if(!gl) {
11840     errno = EINVAL;
11841     return;
11842   };
11843 /*
11844  * Temporarily block all signals while we modify the contents of gl.
11845  */
11846   gl_mask_signals(gl, &oldset);
11847 /*
11848  * Mark the input line as discarded.
11849  */
11850   _gl_abandon_line(gl);
11851 /*
11852  * Restore the process signal mask that was superseded by the call
11853  * to gl_mask_signals().
11854  */
11855   gl_unmask_signals(gl, &oldset);
11856   return;
11857 }
11858 
11859 /*.......................................................................
11860  * This is the private body of the gl_abandon_line() function. It
11861  * assumes that the caller has checked its arguments and blocked the
11862  * delivery of signals.
11863  */
11864 void _gl_abandon_line(GetLine *gl)
11865 {
11866   gl->endline = 1;
11867   gl->pending_io = GLP_WRITE;
11868 }
11869 
11870 /*.......................................................................
11871  * How many characters are needed to write a number as an octal string?
11872  *
11873  * Input:
11874  *  num   unsigned   The to be measured.
11875  * Output:
11876  *  return     int   The number of characters needed.
11877  */
11878 static int gl_octal_width(unsigned num)
11879 {
11880   int n;    /* The number of characters needed to render the number */
11881   for(n=1; num /= 8; n++)
11882     ;
11883   return n;
11884 }
11885 
11886 /*.......................................................................
11887  * Tell gl_get_line() the current terminal size. Note that this is only
11888  * necessary on systems where changes in terminal size aren't reported
11889  * via SIGWINCH.
11890  *
11891  * Input:
11892  *  gl            GetLine *  The resource object of gl_get_line().
11893  *  ncolumn           int    The number of columns in the terminal.
11894  *  nline             int    The number of lines in the terminal.
11895  * Output:
11896  *  return            int    0 - OK.
11897  *                           1 - Error.
11898  */
11899 int gl_set_term_size(GetLine *gl, int ncolumn, int nline)
11900 {
11901   sigset_t oldset;      /* The signals that were blocked on entry */
11902                         /*  to this function */
11903   int status;           /* The return status */
11904 /*
11905  * Block all signals while accessing gl.
11906  */
11907   gl_mask_signals(gl, &oldset);
11908 /*
11909  * Install the new terminal size.
11910  */
11911   status = _gl_set_term_size(gl, ncolumn, nline);
11912 /*
11913  * Restore the process signal mask before returning.
11914  */
11915   gl_unmask_signals(gl, &oldset);
11916   return status;
11917 }
11918 
11919 /*.......................................................................
11920  * This is the private body of the gl_set_term_size() function. It
11921  * assumes that the caller has checked its arguments and blocked the
11922  * delivery of signals.
11923  */
11924 static int _gl_set_term_size(GetLine *gl, int ncolumn, int nline)
11925 {
11926 /*
11927  * Check the arguments.
11928  */
11929   if(!gl) {
11930     errno = EINVAL;
11931     return 1;
11932   };
11933 /*
11934  * Reject non-sensical dimensions.
11935  */
11936   if(ncolumn <= 0 || nline <= 0) {
11937     _err_record_msg(gl->err, "Invalid terminal size", END_ERR_MSG);
11938     errno = EINVAL;
11939     return 1;
11940   };
11941 /*
11942  * Install the new dimensions in the terminal driver if possible, so
11943  * that future calls to gl_query_size() get the new value.
11944  */
11945 #ifdef TIOCSWINSZ
11946   if(gl->is_term) {
11947     struct winsize size;
11948     size.ws_row = nline;
11949     size.ws_col = ncolumn;
11950     size.ws_xpixel = 0;
11951     size.ws_ypixel = 0;
11952     if(ioctl(gl->output_fd, TIOCSWINSZ, &size) == -1) {
11953       _err_record_msg(gl->err, "Can't change terminal size", END_ERR_MSG);
11954       return 1;
11955     };
11956   };
11957 #endif
11958 /*
11959  * If an input line is in the process of being edited, redisplay it to
11960  * accomodate the new dimensions, and record the new dimensions in
11961  * gl->nline and gl->ncolumn.
11962  */
11963   return gl_handle_tty_resize(gl, ncolumn, nline);
11964 }
11965 
11966 /*.......................................................................
11967  * Record a character in the input line buffer at a given position.
11968  *
11969  * Input:
11970  *  gl    GetLine *   The resource object of gl_get_line().
11971  *  c        char     The character to be recorded.
11972  *  bufpos    int     The index in the buffer at which to record the
11973  *                    character.
11974  * Output:
11975  *  return    int     0 - OK.
11976  *                    1 - Insufficient room.
11977  */
11978 static int gl_buffer_char(GetLine *gl, char c, int bufpos)
11979 {
11980 /*
11981  * Guard against buffer overruns.
11982  */
11983   if(bufpos >= gl->linelen)
11984     return 1;
11985 /*
11986  * Record the new character.
11987  */
11988   gl->line[bufpos] = c;
11989 /*
11990  * If the new character was placed beyond the end of the current input
11991  * line, update gl->ntotal to reflect the increased number of characters
11992  * that are in gl->line, and terminate the string.
11993  */
11994   if(bufpos >= gl->ntotal) {
11995     gl->ntotal = bufpos+1;
11996     gl->line[gl->ntotal] = '\0';
11997   };
11998   return 0;
11999 }
12000 
12001 /*.......................................................................
12002  * Copy a given string into the input buffer, overwriting the current
12003  * contents.
12004  *
12005  * Input:
12006  *  gl    GetLine *   The resource object of gl_get_line().
12007  *  s  const char *   The string to be recorded.
12008  *  n         int     The number of characters to be copied from the
12009  *                    string.
12010  *  bufpos    int     The index in the buffer at which to place the
12011  *                    the first character of the string.
12012  * Output:
12013  *  return    int     0 - OK.
12014  *                    1 - String truncated to fit.
12015  */
12016 static int gl_buffer_string(GetLine *gl, const char *s, int n, int bufpos)
12017 {
12018   int nnew;  /* The number of characters actually recorded */
12019   int i;
12020 /*
12021  * How many of the characters will fit within the buffer?
12022  */
12023   nnew = bufpos + n <= gl->linelen ? n : (gl->linelen - bufpos);
12024 /*
12025  * Record the first nnew characters of s[] in the buffer.
12026  */
12027   for(i=0; i<nnew; i++)
12028     gl_buffer_char(gl, s[i], bufpos + i);
12029 /*
12030  * Was the string truncated?
12031  */
12032   return nnew < n;
12033 }
12034 
12035 /*.......................................................................
12036  * Make room in the input buffer for a string to be inserted. This
12037  * involves moving the characters that follow a specified point, towards
12038  * the end of the buffer.
12039  *
12040  * Input:
12041  *  gl    GetLine *   The resource object of gl_get_line().
12042  *  start     int     The index of the first character to be moved.
12043  *  n         int     The width of the gap.
12044  * Output:
12045  *  return    int     0 - OK.
12046  *                    1 - Insufficient room.
12047  */
12048 static int gl_make_gap_in_buffer(GetLine *gl, int start, int n)
12049 {
12050 /*
12051  * Ensure that the buffer has sufficient space.
12052  */
12053   if(gl->ntotal + n > gl->linelen)
12054     return 1;
12055 /*
12056  * Move everything including and beyond the character at 'start'
12057  * towards the end of the string.
12058  */
12059   memmove(gl->line + start + n, gl->line + start, gl->ntotal - start + 1);
12060 /*
12061  * Update the recorded size of the line.
12062  */
12063   gl->ntotal += n;
12064   return 1;
12065 }
12066 
12067 /*.......................................................................
12068  * Remove a given number of characters from the input buffer. This
12069  * involves moving the characters that follow the removed characters to
12070  * where the removed sub-string started in the input buffer.
12071  *
12072  * Input:
12073  *  gl    GetLine *   The resource object of gl_get_line().
12074  *  start     int     The first character to be removed.
12075  *  n         int     The number of characters to remove.
12076  */
12077 static void gl_remove_from_buffer(GetLine *gl, int start, int n)
12078 {
12079   memmove(gl->line + start, gl->line + start + n, gl->ntotal - start - n + 1);
12080 /*
12081  * Update the recorded size of the line.
12082  */
12083   gl->ntotal -= n;
12084 }
12085 
12086 /*.......................................................................
12087  * Truncate the string in the input line buffer after a given number of
12088  * characters.
12089  *
12090  * Input:
12091  *  gl       GetLine *   The resource object of gl_get_line().
12092  *  n            int     The new length of the line.
12093  * Output:
12094  *  return       int     0 - OK.
12095  *                       1 - n > gl->linelen.
12096  */
12097 static int gl_truncate_buffer(GetLine *gl, int n)
12098 {
12099   if(n > gl->linelen)
12100     return 1;
12101   gl->line[n] = '\0';
12102   gl->ntotal = n;
12103   return 0;
12104 }
12105 
12106 /*.......................................................................
12107  * When the contents of gl->line[] are changed without calling any of the
12108  * gl_ buffer manipulation functions, this function must be called to
12109  * compute the length of this string, and ancillary information.
12110  *
12111  * Input:
12112  *  gl      GetLine *   The resource object of gl_get_line().
12113  */
12114 static void gl_update_buffer(GetLine *gl)
12115 {
12116   int len;  /* The length of the line */
12117 /*
12118  * Measure the length of the input line.
12119  */
12120   for(len=0; len <= gl->linelen && gl->line[len]; len++)
12121     ;
12122 /*
12123  * Just in case the string wasn't correctly terminated, do so here.
12124  */
12125   gl->line[len] = '\0';
12126 /*
12127  * Record the number of characters that are now in gl->line[].
12128  */
12129   gl->ntotal = len;
12130 /*
12131  * Ensure that the cursor stays within the bounds of the modified
12132  * input line.
12133  */
12134   if(gl->buff_curpos > gl->ntotal)
12135     gl->buff_curpos = gl->ntotal;
12136 /*
12137  * Arrange for the input line to be redrawn.
12138  */
12139   gl_queue_redisplay(gl);
12140   return;
12141 }
12142 
12143 /*.......................................................................
12144  * Erase the displayed input line, including its prompt, and leave the
12145  * cursor where the erased line started. Note that to allow this
12146  * function to be used when responding to a terminal resize, this
12147  * function is designed to work even if the horizontal cursor position
12148  * doesn't match the internally recorded position.
12149  *
12150  * Input:
12151  *  gl      GetLine *   The resource object of gl_get_line().
12152  * Output:
12153  *  return      int     0 - OK.
12154  *                      1 - Error.
12155  */
12156 static int gl_erase_line(GetLine *gl)
12157 {
12158 /*
12159  * Is a line currently displayed?
12160  */
12161   if(gl->displayed) {
12162 /*
12163  * Relative the the start of the input line, which terminal line of
12164  * the current input line is the cursor currently on?
12165  */
12166     int cursor_line = gl->term_curpos / gl->ncolumn;
12167 /*
12168  * Move the cursor to the start of the line.
12169  */
12170     for( ; cursor_line > 0; cursor_line--) {
12171       if(gl_print_control_sequence(gl, 1, gl->up))
12172 	return 1;
12173     };
12174     if(gl_print_control_sequence(gl, 1, gl->bol))
12175       return 1;
12176 /*
12177  * Clear from the start of the line to the end of the terminal.
12178  */
12179     if(gl_print_control_sequence(gl, gl->nline, gl->clear_eod))
12180       return 1;
12181 /*
12182  * Mark the line as no longer displayed.
12183  */
12184     gl_line_erased(gl);
12185   };
12186   return 0;
12187 }
12188 
12189 /*.......................................................................
12190  * Arrange for the input line to be redisplayed by gl_flush_output(),
12191  * as soon as the output queue becomes empty.
12192  *
12193  * Input:
12194  *  gl          GetLine *   The resource object of gl_get_line().
12195  */
12196 static void gl_queue_redisplay(GetLine *gl)
12197 {
12198   gl->redisplay = 1;
12199   gl->pending_io = GLP_WRITE;
12200 }
12201 
12202 /*.......................................................................
12203  * Truncate the displayed input line starting from the current
12204  * terminal cursor position, and leave the cursor at the end of the
12205  * truncated line. The input-line buffer is not affected.
12206  *
12207  * Input:
12208  *  gl     GetLine *   The resource object of gl_get_line().
12209  * Output:
12210  *  return     int     0 - OK.
12211  *                     1 - Error.
12212  */
12213 static int gl_truncate_display(GetLine *gl)
12214 {
12215 /*
12216  * Keep a record of the current terminal cursor position.
12217  */
12218   int term_curpos = gl->term_curpos;
12219 /*
12220  * First clear from the cursor to the end of the current input line.
12221  */
12222   if(gl_print_control_sequence(gl, 1, gl->clear_eol))
12223     return 1;
12224 /*
12225  * If there is more than one line displayed, go to the start of the
12226  * next line and clear from there to the end of the display. Note that
12227  * we can't use clear_eod to do the whole job of clearing from the
12228  * current cursor position to the end of the terminal because
12229  * clear_eod is only defined when used at the start of a terminal line
12230  * (eg. with gnome terminals, clear_eod clears from the start of the
12231  * current terminal line, rather than from the current cursor
12232  * position).
12233  */
12234   if(gl->term_len / gl->ncolumn > gl->term_curpos / gl->ncolumn) {
12235     if(gl_print_control_sequence(gl, 1, gl->down) ||
12236        gl_print_control_sequence(gl, 1, gl->bol) ||
12237        gl_print_control_sequence(gl, gl->nline, gl->clear_eod))
12238       return 1;
12239 /*
12240  * Where is the cursor now?
12241  */
12242     gl->term_curpos = gl->ncolumn * (term_curpos / gl->ncolumn + 1);
12243 /*
12244  * Restore the cursor position.
12245  */
12246     gl_set_term_curpos(gl, term_curpos);
12247   };
12248 /*
12249  * Update the recorded position of the final character.
12250  */
12251   gl->term_len = gl->term_curpos;
12252   return 0;
12253 }
12254 
12255 /*.......................................................................
12256  * Return the set of all trappable signals.
12257  *
12258  * Input:
12259  *  signals   sigset_t *  The set of signals will be recorded in
12260  *                        *signals.
12261  */
12262 static void gl_list_trappable_signals(sigset_t *signals)
12263 {
12264 /*
12265  * Start with the set of all signals.
12266  */
12267   sigfillset(signals);
12268 /*
12269  * Remove un-trappable signals from this set.
12270  */
12271 #ifdef SIGKILL
12272   sigdelset(signals, SIGKILL);
12273 #endif
12274 #ifdef SIGSTOP
12275   sigdelset(signals, SIGSTOP);
12276 #endif
12277 }
12278 
12279 /*.......................................................................
12280  * Read an input line from a non-interactive input stream.
12281  *
12282  * Input:
12283  *  gl     GetLine *   The resource object of gl_get_line().
12284  * Output:
12285  *  return     int     0 - OK
12286  *                     1 - Error.
12287  */
12288 static int gl_read_stream_line(GetLine *gl)
12289 {
12290   char c = '\0'; /* The latest character read from fp */
12291 /*
12292  * Record the fact that we are about to read input.
12293  */
12294   gl->pending_io = GLP_READ;
12295 /*
12296  * If we are starting a new line, reset the line-input parameters.
12297  */
12298   if(gl->endline)
12299     gl_reset_input_line(gl);
12300 /*
12301  * Read one character at a time.
12302  */
12303   while(gl->ntotal < gl->linelen && c != '\n') {
12304 /*
12305  * Attempt to read one more character.
12306  */
12307     switch(gl_read_input(gl, &c)) {
12308     case GL_READ_OK:
12309       break;
12310     case GL_READ_EOF:        /* Reached end-of-file? */
12311 /*
12312  * If any characters were read before the end-of-file condition,
12313  * interpolate a newline character, so that the caller sees a
12314  * properly terminated line. Otherwise return an end-of-file
12315  * condition.
12316  */
12317       if(gl->ntotal > 0) {
12318 	c = '\n';
12319       } else {
12320 	gl_record_status(gl, GLR_EOF, 0);
12321 	return 1;
12322       };
12323       break;
12324     case GL_READ_BLOCKED:    /* Input blocked? */
12325       gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO);
12326       return 1;
12327       break;
12328     case GL_READ_ERROR:     /* I/O error? */
12329       return 1;
12330       break;
12331     };
12332 /*
12333  * Append the character to the line buffer.
12334  */
12335     if(gl_buffer_char(gl, c, gl->ntotal))
12336       return 1;
12337   };
12338 /*
12339  * Was the end of the input line reached before running out of buffer space?
12340  */
12341   gl->endline = (c == '\n');
12342   return 0;
12343 }
12344 
12345 /*.......................................................................
12346  * Read a single character from a non-interactive input stream.
12347  *
12348  * Input:
12349  *  gl     GetLine *   The resource object of gl_get_line().
12350  * Output:
12351  *  return     int     The character, or EOF on error.
12352  */
12353 static int gl_read_stream_char(GetLine *gl)
12354 {
12355   char c = '\0';    /* The latest character read from fp */
12356   int retval = EOF; /* The return value of this function */
12357 /*
12358  * Arrange to discard any incomplete input line.
12359  */
12360   _gl_abandon_line(gl);
12361 /*
12362  * Record the fact that we are about to read input.
12363  */
12364   gl->pending_io = GLP_READ;
12365 /*
12366  * Attempt to read one more character.
12367  */
12368   switch(gl_read_input(gl, &c)) {
12369   case GL_READ_OK:      /* Success */
12370     retval = c;
12371     break;
12372   case GL_READ_BLOCKED: /* The read blocked */
12373     gl_record_status(gl, GLR_BLOCKED, BLOCKED_ERRNO);
12374     retval = EOF;  /* Failure */
12375     break;
12376   case GL_READ_EOF:     /* End of file reached */
12377     gl_record_status(gl, GLR_EOF, 0);
12378     retval = EOF;  /* Failure */
12379     break;
12380   case GL_READ_ERROR:
12381     retval = EOF;  /* Failure */
12382     break;
12383   };
12384   return retval;
12385 }
12386 
12387 /*.......................................................................
12388  * Bind a key sequence to a given action.
12389  *
12390  * Input:
12391  *  gl          GetLine *   The resource object of gl_get_line().
12392  *  origin  GlKeyOrigin     The originator of the key binding.
12393  *  key      const char *   The key-sequence to be bound (or unbound).
12394  *  action   const char *   The name of the action to bind the key to,
12395  *                          or either NULL or "" to unbind the
12396  *                          key-sequence.
12397  * Output:
12398  *  return          int     0 - OK
12399  *                          1 - Error.
12400  */
12401 int gl_bind_keyseq(GetLine *gl, GlKeyOrigin origin, const char *keyseq,
12402 		   const char *action)
12403 {
12404   KtBinder binder;  /* The private internal equivalent of 'origin' */
12405 /*
12406  * Check the arguments.
12407  */
12408   if(!gl || !keyseq) {
12409     errno = EINVAL;
12410     if(gl)
12411       _err_record_msg(gl->err, "NULL argument(s)", END_ERR_MSG);
12412     return 1;
12413   };
12414 /*
12415  * An empty action string requests that the key-sequence be unbound.
12416  * This is indicated to _kt_set_keybinding() by passing a NULL action
12417  * string, so convert an empty string to a NULL action pointer.
12418  */
12419   if(action && *action=='\0')
12420     action = NULL;
12421 /*
12422  * Translate the public originator enumeration to the private equivalent.
12423  */
12424   binder = origin==GL_USER_KEY ? KTB_USER : KTB_NORM;
12425 /*
12426  * Bind the action to a given key-sequence?
12427  */
12428   if(keyseq && _kt_set_keybinding(gl->bindings, binder, keyseq, action)) {
12429     _err_record_msg(gl->err, _kt_last_error(gl->bindings), END_ERR_MSG);
12430     return 1;
12431   };
12432   return 0;
12433 }
12434 
12435 /*.......................................................................
12436  * This is the public wrapper around the gl_clear_termina() function.
12437  * It clears the terminal and leaves the cursor at the home position.
12438  * In server I/O mode, the next call to gl_get_line() will also
12439  * redisplay the current input line.
12440  *
12441  * Input:
12442  *  gl          GetLine *   The resource object of gl_get_line().
12443  * Output:
12444  *  return          int     0 - OK.
12445  *                          1 - Error.
12446  */
12447 int gl_erase_terminal(GetLine *gl)
12448 {
12449   sigset_t oldset;      /* The signals that were blocked on entry */
12450                         /*  to this function */
12451   int status;           /* The return status */
12452 /*
12453  * Block all signals while accessing gl.
12454  */
12455   gl_mask_signals(gl, &oldset);
12456 /*
12457  * Clear the terminal.
12458  */
12459   status = gl_clear_screen(gl, 1, NULL);
12460 /*
12461  * Attempt to flush the clear-screen control codes to the terminal.
12462  * If this doesn't complete the job, the next call to gl_get_line()
12463  * will.
12464  */
12465   (void) gl_flush_output(gl);
12466 /*
12467  * Restore the process signal mask before returning.
12468  */
12469   gl_unmask_signals(gl, &oldset);
12470   return status;
12471 }
12472 
12473 /*.......................................................................
12474  * This function must be called by any function that erases the input
12475  * line.
12476  *
12477  * Input:
12478  *  gl          GetLine *   The resource object of gl_get_line().
12479  */
12480 static void gl_line_erased(GetLine *gl)
12481 {
12482   gl->displayed = 0;
12483   gl->term_curpos = 0;
12484   gl->term_len = 0;
12485 }
12486 
12487 /*.......................................................................
12488  * Append a specified line to the history list.
12489  *
12490  * Input:
12491  *  gl          GetLine *   The resource object of gl_get_line().
12492  *  line     const char *   The line to be added.
12493  * Output:
12494  *  return          int     0 - OK.
12495  *                          1 - Error.
12496  */
12497 int gl_append_history(GetLine *gl, const char *line)
12498 {
12499   sigset_t oldset;      /* The signals that were blocked on entry */
12500                         /*  to this function */
12501   int status;           /* The return status */
12502 /*
12503  * Check the arguments.
12504  */
12505   if(!gl || !line) {
12506     errno = EINVAL;
12507     return 1;
12508   };
12509 /*
12510  * Block all signals.
12511  */
12512   if(gl_mask_signals(gl, &oldset))
12513     return 1;
12514 /*
12515  * Execute the private body of the function while signals are blocked.
12516  */
12517   status = _gl_append_history(gl, line);
12518 /*
12519  * Restore the process signal mask.
12520  */
12521   gl_unmask_signals(gl, &oldset);
12522   return status;
12523 }
12524 
12525 /*.......................................................................
12526  * This is the private body of the public function, gl_append_history().
12527  * It assumes that the caller has checked its arguments and blocked the
12528  * delivery of signals.
12529  */
12530 static int _gl_append_history(GetLine *gl, const char *line)
12531 {
12532   int status =_glh_add_history(gl->glh, line, 0);
12533   if(status)
12534     _err_record_msg(gl->err, _glh_last_error(gl->glh), END_ERR_MSG);
12535   return status;
12536 }
12537 
12538 /*.......................................................................
12539  * Enable or disable the automatic addition of newly entered lines to the
12540  * history list.
12541  *
12542  * Input:
12543  *  gl          GetLine *   The resource object of gl_get_line().
12544  *  enable          int     If true, subsequently entered lines will
12545  *                          automatically be added to the history list
12546  *                          before they are returned to the caller of
12547  *                          gl_get_line(). If 0, the choice of how and
12548  *                          when to archive lines in the history list,
12549  *                          is left up to the calling application, which
12550  *                          can do so via calls to gl_append_history().
12551  * Output:
12552  *  return          int     0 - OK.
12553  *                          1 - Error.
12554  */
12555 int gl_automatic_history(GetLine *gl, int enable)
12556 {
12557   sigset_t oldset;      /* The signals that were blocked on entry */
12558                         /*  to this function */
12559 /*
12560  * Check the arguments.
12561  */
12562   if(!gl) {
12563     errno = EINVAL;
12564     return 1;
12565   };
12566 /*
12567  * Block all signals.
12568  */
12569   if(gl_mask_signals(gl, &oldset))
12570     return 1;
12571 /*
12572  * Execute the private body of the function while signals are blocked.
12573  */
12574   gl->automatic_history = enable;
12575 /*
12576  * Restore the process signal mask.
12577  */
12578   gl_unmask_signals(gl, &oldset);
12579   return 0;
12580 }
12581 
12582 /*.......................................................................
12583  * This is a public function that reads a single uninterpretted
12584  * character from the user, without displaying anything.
12585  *
12586  * Input:
12587  *  gl     GetLine *  A resource object previously returned by
12588  *                    new_GetLine().
12589  * Output:
12590  *  return     int    The character that was read, or EOF if the read
12591  *                    had to be aborted (in which case you can call
12592  *                    gl_return_status() to find out why).
12593  */
12594 int gl_read_char(GetLine *gl)
12595 {
12596   int retval;   /* The return value of _gl_read_char() */
12597 /*
12598  * This function can be called from application callback functions,
12599  * so check whether signals have already been masked, so that we don't
12600  * do it again, and overwrite gl->old_signal_set.
12601  */
12602   int was_masked = gl->signals_masked;
12603 /*
12604  * Check the arguments.
12605  */
12606   if(!gl) {
12607     errno = EINVAL;
12608     return EOF;
12609   };
12610 /*
12611  * Temporarily block all of the signals that we have been asked to trap.
12612  */
12613   if(!was_masked && gl_mask_signals(gl, &gl->old_signal_set))
12614     return EOF;
12615 /*
12616  * Perform the character reading task.
12617  */
12618   retval = _gl_read_char(gl);
12619 /*
12620  * Restore the process signal mask to how it was when this function was
12621  * first called.
12622  */
12623   if(!was_masked)
12624     gl_unmask_signals(gl, &gl->old_signal_set);
12625   return retval;
12626 }
12627 
12628 /*.......................................................................
12629  * This is the main body of the public function gl_read_char().
12630  */
12631 static int _gl_read_char(GetLine *gl)
12632 {
12633   int retval = EOF;  /* The return value */
12634   int waserr = 0;    /* True if an error occurs */
12635   char c;            /* The character read */
12636 /*
12637  * This function can be called from application callback functions,
12638  * so check whether signals have already been overriden, so that we don't
12639  * overwrite the preserved signal handlers with gl_get_line()s. Also
12640  * record whether we are currently in raw I/O mode or not, so that this
12641  * can be left in the same state on leaving this function.
12642  */
12643   int was_overriden = gl->signals_overriden;
12644   int was_raw = gl->raw_mode;
12645 /*
12646  * Also keep a record of the direction of any I/O that gl_get_line()
12647  * is awaiting, so that we can restore this status on return.
12648  */
12649   GlPendingIO old_pending_io = gl->pending_io;
12650 /*
12651  * Assume that this call will successfully complete the input operation
12652  * until proven otherwise.
12653  */
12654   gl_clear_status(gl);
12655 /*
12656  * If this is the first call to this function or gl_get_line(),
12657  * since new_GetLine(), complete any postponed configuration.
12658  */
12659   if(!gl->configured) {
12660     (void) _gl_configure_getline(gl, NULL, NULL, TECLA_CONFIG_FILE);
12661     gl->configured = 1;
12662   };
12663 /*
12664  * Before installing our signal handler functions, record the fact
12665  * that there are no pending signals.
12666  */
12667   gl_pending_signal = -1;
12668 /*
12669  * Temporarily override the signal handlers of the calling program,
12670  * so that we can intercept signals that would leave the terminal
12671  * in a bad state.
12672  */
12673   if(!was_overriden)
12674     waserr = gl_override_signal_handlers(gl);
12675 /*
12676  * After recording the current terminal settings, switch the terminal
12677  * into raw input mode, without redisplaying any partially entered input
12678  * line.
12679  */
12680   if(!was_raw)
12681     waserr = waserr || _gl_raw_io(gl, 0);
12682 /*
12683  * Attempt to read the line. This will require more than one attempt if
12684  * either a current temporary input file is opened by gl_get_input_line()
12685  * or the end of a temporary input file is reached by gl_read_stream_line().
12686  */
12687   while(!waserr) {
12688 /*
12689  * Read a line from a non-interactive stream?
12690  */
12691     if(gl->file_fp || !gl->is_term) {
12692       retval = gl_read_stream_char(gl);
12693       if(retval != EOF) {            /* Success? */
12694 	break;
12695       } else if(gl->file_fp) {  /* End of temporary input file? */
12696 	gl_revert_input(gl);
12697 	gl_record_status(gl, GLR_NEWLINE, 0);
12698       } else {                  /* An error? */
12699 	waserr = 1;
12700 	break;
12701       };
12702     };
12703 /*
12704  * Read from the terminal? Note that the above if() block may have
12705  * changed gl->file_fp, so it is necessary to retest it here, rather
12706  * than using an else statement.
12707  */
12708     if(!gl->file_fp && gl->is_term) {
12709 /*
12710  * Flush any pending output to the terminal before waiting
12711  * for the user to type a character.
12712  */
12713       if(_glq_char_count(gl->cq) > 0 && gl_flush_output(gl)) {
12714 	retval = EOF;
12715 /*
12716  * Read one character. Don't append it to the key buffer, since
12717  * this would subseuqnely appear as bogus input to the line editor.
12718  */
12719       } else if(gl_read_terminal(gl, 0, &c) == 0) {
12720 /*
12721  * Record the character for return.
12722  */
12723 	retval = c;
12724 /*
12725  * In this mode, count each character as being a new key-sequence.
12726  */
12727 	gl->keyseq_count++;
12728 /*
12729  * Delete the character that was read, from the key-press buffer.
12730  */
12731 	gl_discard_chars(gl, 1);
12732       };
12733       if(retval==EOF)
12734 	waserr = 1;
12735       else
12736 	break;
12737     };
12738   };
12739 /*
12740  * If an error occurred, but gl->rtn_status is still set to
12741  * GLR_NEWLINE, change the status to GLR_ERROR. Otherwise
12742  * leave it at whatever specific value was assigned by the function
12743  * that aborted input. This means that only functions that trap
12744  * non-generic errors have to remember to update gl->rtn_status
12745  * themselves.
12746  */
12747   if(waserr && gl->rtn_status == GLR_NEWLINE)
12748     gl_record_status(gl, GLR_ERROR, errno);
12749 /*
12750  * Restore terminal settings, if they were changed by this function.
12751  */
12752   if(!was_raw && gl->io_mode != GL_SERVER_MODE)
12753     _gl_normal_io(gl);
12754 /*
12755  * Restore the signal handlers, if they were overriden by this function.
12756  */
12757   if(!was_overriden)
12758     gl_restore_signal_handlers(gl);
12759 /*
12760  * If this function gets aborted early, the errno value associated
12761  * with the event that caused this to happen is recorded in
12762  * gl->rtn_errno. Since errno may have been overwritten by cleanup
12763  * functions after this, restore its value to the value that it had
12764  * when the error condition occured, so that the caller can examine it
12765  * to find out what happened.
12766  */
12767   errno = gl->rtn_errno;
12768 /*
12769  * Error conditions are signalled to the caller, by setting the returned
12770  * character to EOF.
12771  */
12772   if(gl->rtn_status != GLR_NEWLINE)
12773     retval = EOF;
12774 /*
12775  * Restore the indication of what direction of I/O gl_get_line()
12776  * was awaiting before this call.
12777  */
12778   gl->pending_io = old_pending_io;
12779 /*
12780  * Return the acquired character.
12781  */
12782   return retval;
12783 }
12784 
12785 /*.......................................................................
12786  * Reset the GetLine completion status. This function should be called
12787  * at the start of gl_get_line(), gl_read_char() and gl_query_char()
12788  * to discard the completion status and non-zero errno value of any
12789  * preceding calls to these functions.
12790  *
12791  * Input:
12792  *  gl       GetLine *  The resource object of this module.
12793  */
12794 static void gl_clear_status(GetLine *gl)
12795 {
12796   gl_record_status(gl, GLR_NEWLINE, 0);
12797 }
12798 
12799 /*.......................................................................
12800  * When an error or other event causes gl_get_line() to return, this
12801  * function should be called to record information about what
12802  * happened, including the value of errno and the value that
12803  * gl_return_status() should return.
12804  *
12805  * Input:
12806  *  gl                GetLine *  The resource object of this module.
12807  *  rtn_status GlReturnStatus    The completion status. To clear a
12808  *                               previous abnormal completion status,
12809  *                               specify GLR_NEWLINE (this is what
12810  *                               gl_clear_status() does).
12811  *  rtn_errno             int    The associated value of errno.
12812  */
12813 static void gl_record_status(GetLine *gl, GlReturnStatus rtn_status,
12814 			     int rtn_errno)
12815 {
12816 /*
12817  * If rtn_status==GLR_NEWLINE, then this resets the completion status, so we
12818  * should always heed this. Otherwise, only record the first abnormal
12819  * condition that occurs after such a reset.
12820  */
12821   if(rtn_status == GLR_NEWLINE || gl->rtn_status == GLR_NEWLINE) {
12822     gl->rtn_status = rtn_status;
12823     gl->rtn_errno = rtn_errno;
12824   };
12825 }
12826 
12827