2 * Listener loop for subsystem library libss.a.
7 * Copyright 1987, 1988 by MIT Student Information Processing Board
9 * Permission to use, copy, modify, and distribute this software and
10 * its documentation for any purpose is hereby granted, provided that
11 * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
12 * advertising or publicity pertaining to distribution of the software
13 * without specific, written prior permission. M.I.T. and the
14 * M.I.T. S.I.P.B. make no representations about the suitability of
15 * this software for any purpose. It is provided "as is" without
16 * express or implied warranty.
20 #include "ss_internal.h"
24 #include <sys/param.h>
26 typedef void sigret_t;
28 static ss_data *current_info;
29 static jmp_buf listen_jmpb;
30 static sigret_t (*sig_cont)(int);
32 static sigret_t print_prompt(int sig __SS_ATTR((unused)))
34 if (current_info->redisplay)
35 (*current_info->redisplay)();
37 (void) fputs(current_info->prompt, stdout);
38 (void) fflush(stdout);
42 static sigret_t listen_int_handler(int sig __SS_ATTR((unused)))
45 signal(SIGINT, listen_int_handler);
46 longjmp(listen_jmpb, 1);
49 int ss_listen (int sci_idx)
53 sigret_t (*sig_int)(int), (*old_sig_cont)(int);
55 sigset_t omask, igmask;
58 ss_data *old_info = current_info;
61 current_info = info = ss_info(sci_idx);
62 sig_cont = (sigret_t (*)(int)) 0;
65 sigaddset(&igmask, SIGINT);
66 sigprocmask(SIG_BLOCK, &igmask, &omask);
67 memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf));
68 sig_int = signal(SIGINT, listen_int_handler);
70 sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
73 old_sig_cont = sig_cont;
74 sig_cont = signal(SIGCONT, print_prompt);
75 if (sig_cont == print_prompt)
76 sig_cont = old_sig_cont;
78 line = (*info->readline)(current_info->prompt);
81 if (fgets(input, BUFSIZ, stdin) == input)
90 (void) signal(SIGCONT, sig_cont);
94 cp = strchr(line, '\n');
100 (void) signal(SIGCONT, sig_cont);
101 if (info->add_history)
102 (*info->add_history)(line);
104 code = ss_execute_line (sci_idx, line);
105 if (code == SS_ET_COMMAND_NOT_FOUND) {
106 register char *c = line;
107 while (*c == ' ' || *c == '\t')
109 cp = strchr (c, ' ');
112 cp = strchr (c, '\t');
115 ss_error (sci_idx, 0,
116 "Unknown request \"%s\". Type \"?\" for a request list.",
124 (void) signal(SIGINT, sig_int);
125 memcpy(listen_jmpb, old_jmpb, sizeof(jmp_buf));
126 current_info = old_info;
130 void ss_abort_subsystem(int sci_idx, int code)
132 ss_info(sci_idx)->abort = 1;
133 ss_info(sci_idx)->exit_status = code;
137 void ss_quit(int argc __SS_ATTR((unused)),
138 const char * const *argv __SS_ATTR((unused)),
139 int sci_idx, pointer infop __SS_ATTR((unused)))
141 ss_abort_subsystem(sci_idx, 0);
145 #define get_request(tbl,idx) ((tbl) -> requests + (idx))
147 static char *cmd_generator(const char *text, int state)
150 static ss_request_table **rqtbl;
152 static char const * const * name;
153 ss_request_entry *request;
158 rqtbl = current_info->rqt_tables;
159 if (!rqtbl || !*rqtbl)
166 if (!name || !*name) {
167 request = get_request(*rqtbl, curr_rqt++);
168 name = request->command_names;
178 if (strncmp(*name, text, len) == 0) {
179 ret = malloc(strlen(*name)+1);
191 char **ss_rl_completion(const char *text, int start,
192 int end __SS_ATTR((unused)))
194 if ((start == 0) && current_info->rl_completion_matches)
195 return (*current_info->rl_completion_matches)
196 (text, cmd_generator);