1 /* 2 * Copyright (c) 2000 by Sun Microsystems, Inc. 3 * All rights reserved. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * Listener loop for subsystem library libss.a. 10 * 11 * util/ss/listen.c 12 * 13 * Copyright 1987, 1988 by MIT Student Information Processing Board 14 * 15 * For copyright information, see copyright.h. 16 */ 17 18 #include "copyright.h" 19 #include "ss_internal.h" 20 #include <stdio.h> 21 #include <setjmp.h> 22 #include <signal.h> 23 #include <libintl.h> 24 #include <sys/param.h> 25 #ifdef BSD 26 #include <sgtty.h> 27 #endif 28 29 static ss_data *current_info; 30 static jmp_buf listen_jmpb; 31 32 static RETSIGTYPE print_prompt() 33 { 34 #ifdef BSD 35 /* put input into a reasonable mode */ 36 struct sgttyb ttyb; 37 if (ioctl(fileno(stdin), TIOCGETP, &ttyb) != -1) { 38 if (ttyb.sg_flags & (CBREAK|RAW)) { 39 ttyb.sg_flags &= ~(CBREAK|RAW); 40 (void) ioctl(0, TIOCSETP, &ttyb); 41 } 42 } 43 #endif 44 (void) fputs(current_info->prompt, stdout); 45 (void) fflush(stdout); 46 } 47 48 static RETSIGTYPE listen_int_handler(signo) 49 int signo; 50 { 51 putc('\n', stdout); 52 longjmp(listen_jmpb, 1); 53 } 54 55 int ss_listen (sci_idx) 56 int sci_idx; 57 { 58 register char *cp; 59 register ss_data *info; 60 char input[BUFSIZ]; 61 char buffer[BUFSIZ]; 62 char *end = buffer; 63 int code; 64 jmp_buf old_jmpb; 65 ss_data *old_info = current_info; 66 #ifdef POSIX_SIGNALS 67 struct sigaction isig, csig, nsig, osig; 68 sigset_t nmask, omask; 69 #else 70 register RETSIGTYPE (*sig_cont)(); 71 RETSIGTYPE (*sig_int)(), (*old_sig_cont)(); 72 int mask; 73 #endif 74 75 current_info = info = ss_info(sci_idx); 76 info->abort = 0; 77 78 #ifdef POSIX_SIGNALS 79 csig.sa_handler = (RETSIGTYPE (*)())0; 80 sigemptyset(&nmask); 81 sigaddset(&nmask, SIGINT); 82 sigprocmask(SIG_BLOCK, &nmask, &omask); 83 #else 84 sig_cont = (RETSIGTYPE (*)())0; 85 mask = sigblock(sigmask(SIGINT)); 86 #endif 87 88 memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf)); 89 90 #ifdef POSIX_SIGNALS 91 nsig.sa_handler = listen_int_handler; 92 sigemptyset(&nsig.sa_mask); 93 nsig.sa_flags = 0; 94 sigaction(SIGINT, &nsig, &isig); 95 #else 96 sig_int = signal(SIGINT, listen_int_handler); 97 #endif 98 99 setjmp(listen_jmpb); 100 101 #ifdef POSIX_SIGNALS 102 sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0); 103 #else 104 (void) sigsetmask(mask); 105 #endif 106 while(!info->abort) { 107 print_prompt(); 108 *end = '\0'; 109 #ifdef POSIX_SIGNALS 110 nsig.sa_handler = listen_int_handler; /* fgets is not signal-safe */ 111 osig = csig; 112 sigaction(SIGCONT, &nsig, &csig); 113 if ((RETSIGTYPE (*)())csig.sa_handler==(RETSIGTYPE (*)())listen_int_handler) 114 csig = osig; 115 #else 116 old_sig_cont = sig_cont; 117 sig_cont = signal(SIGCONT, print_prompt); 118 if (sig_cont == print_prompt) 119 sig_cont = old_sig_cont; 120 #endif 121 if (fgets(input, BUFSIZ, stdin) != input) { 122 code = SS_ET_EOF; 123 goto egress; 124 } 125 cp = strchr(input, '\n'); 126 if (cp) { 127 *cp = '\0'; 128 if (cp == input) 129 continue; 130 } 131 #ifdef POSIX_SIGNALS 132 sigaction(SIGCONT, &csig, (struct sigaction *)0); 133 #else 134 (void) signal(SIGCONT, sig_cont); 135 #endif 136 for (end = input; *end; end++) 137 ; 138 139 code = ss_execute_line (sci_idx, input); 140 if (code == SS_ET_COMMAND_NOT_FOUND) { 141 register char *c = input; 142 while (*c == ' ' || *c == '\t') 143 c++; 144 cp = strchr (c, ' '); 145 if (cp) 146 *cp = '\0'; 147 cp = strchr (c, '\t'); 148 if (cp) 149 *cp = '\0'; 150 ss_error (sci_idx, 0, dgettext(TEXT_DOMAIN, 151 "Unknown request \"%s\". Type \"?\" for a request list."), 152 c); 153 } 154 } 155 code = 0; 156 egress: 157 #ifdef POSIX_SIGNALS 158 sigaction(SIGINT, &isig, (struct sigaction *)0); 159 #else 160 (void) signal(SIGINT, sig_int); 161 #endif 162 memcpy(listen_jmpb, old_jmpb, sizeof(jmp_buf)); 163 current_info = old_info; 164 return code; 165 } 166 167 void ss_abort_subsystem(sci_idx, code) 168 int sci_idx; 169 int code; 170 { 171 ss_info(sci_idx)->abort = 1; 172 ss_info(sci_idx)->exit_status = code; 173 174 } 175 176 void ss_quit(argc, argv, sci_idx, infop) 177 int argc; 178 char **argv; 179 int sci_idx; 180 pointer infop; 181 { 182 ss_abort_subsystem(sci_idx, 0); 183 } 184