source: trunk/athena/bin/discuss/edsc/edsc.c @ 25412

Revision 25412, 5.3 KB checked in by jdreed, 13 years ago (diff)
Cast return value of set_com_err_hook to void
Line 
1/*
2 *
3 *      Copyright (C) 1989 by the Massachusetts Institute of Technology
4 *      Developed by the MIT Student Information Processing Board (SIPB).
5 *      For copying information, see the file mit-copyright.h in this release.
6 *
7 */
8/*
9 *
10 * edsc () -- A subprocess to make implement emacs discuss mode easier.
11 *
12 */
13
14
15#ifndef lint
16static char *rcsid_discuss_c = "$Id: edsc.c,v 1.15 2006-03-10 07:11:37 ghudson Exp $";
17#endif /* lint */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <sys/file.h>
22#include <sys/time.h>
23#include <sys/resource.h>
24#include <signal.h>
25#include <string.h>
26#include <sys/wait.h>
27#include <pwd.h>
28#include <ctype.h>
29#include <errno.h>
30#include "config.h"
31#include "edsc.h"
32#define INPUT_BUFF_SIZE 10240
33
34char *local_realm();
35int log_warn();
36tfile unix_tfile();
37void sig_do_quit();
38
39static struct edsc_req {
40     char *name;                                /* Name of request */
41     int (*routine)();                          /* Routine to call */
42} edscr[] = {
43        {"quit", do_quit},
44        {"gmi", do_gmi},
45        {"gti", do_gti},
46        {"gml", do_gml},
47        {"gt", do_gt},
48        {"gtf", do_gtf},
49        {"grt", do_grt},
50        {"grtn", do_grtn},
51        {"ss", do_ss},
52        {"at", do_at},
53        {"nut", do_nut},
54        {"sfl", do_sfl},
55        {"am", do_am},
56        {"dm", do_dm},
57        {"pacl", do_pacl},
58        {"dacl", do_dacl},
59        {"sacl", do_sacl},
60        {"ls", do_ls},
61        {"dt", do_dt},
62        {"rt", do_rt},
63#ifdef EDSC_CACHE
64        {"scd", do_scd},
65        {"gtfc", do_gtfc},
66        {"it", do_it},
67        {"itn", do_itn},
68        {"im", do_im},
69#endif
70        {"gpv", do_gpv}
71};
72
73#define NUM_EDSC_REQUESTS (sizeof (edscr) / sizeof (struct edsc_req))
74
75void our_com_err(const char *who, long code, const char *fmt, va_list args)
76{
77  /* A simple com_err that keeps library errors from confusing emacs */
78  fprintf(stderr, ";%s: %s\n", who, error_message(code));
79}
80
81/*
82 * This is we can cleanup when we have problems
83 */
84void crash_handler(sig)
85        int     sig;
86{
87        static int      shutting_down_cache = 0;
88        int     pid;
89
90        pid = fork();
91        /*
92         * If the fork() fails or if this is the child, do a cache shutdown
93         */
94        if (pid <= 0) {
95                printf("; Edsc crash (code dump in /tmp) --- signal %d\n",
96                       sig);
97#ifdef EDSC_CACHE
98                if (!shutting_down_cache) {
99                        shutting_down_cache++;
100                        cache_shutdown();
101                }
102#endif
103        }
104        /*
105         * If the fork fails or if this is the parent, cd to /tmp
106         * and perform a crash dump
107         */
108        if (pid != 0) {
109                (void) chdir("/tmp");
110                signal(SIGILL, SIG_DFL);
111                abort();
112        }
113        exit(1);
114}
115
116       
117
118char *temp_file;
119char *pgm;
120char *user_id;
121tfile stdout_tf;
122main(argc, argv)
123     int argc;
124     char **argv;
125{
126     int code,i;
127     static char input_buf[INPUT_BUFF_SIZE];
128     char *cp,*op,delim,*args;
129     struct rlimit limit;
130
131#if defined(__APPLE__) && defined(__MACH__)
132     add_error_table(&et_dsc_error_table);
133#else
134     initialize_dsc_error_table();
135#endif
136
137     /* Use our com_err so the library doesn't spew and confuse emacs */
138     (void) set_com_err_hook(our_com_err);
139
140     temp_file = malloc(64);
141     pgm = malloc(64);
142     (void) sprintf(temp_file, "/tmp/mtg%d.%d", (int)getuid(), getpid());
143
144     code = find_rc_filename();
145     if (code && (code != EACCES)) {
146          char buf[100];
147          sprintf(buf, "%s -q", DSC_SETUP);
148          system(buf);
149          code = find_rc_filename();
150     }
151     if (code) {
152             printf(";%s\n", error_message(code));
153             exit(1);
154     }
155#ifdef EDSC_CACHE
156     cache_init(0);
157#endif
158     /*
159      * Set up debugging hooks.  Also useful becuase it means we clean
160      * up our cache files in case we die ungracefully.
161      */
162     getrlimit(RLIMIT_CORE, &limit);
163     limit.rlim_cur = limit.rlim_max;
164     setrlimit(RLIMIT_CORE, &limit);
165#ifdef SIGILL
166     signal(SIGILL, crash_handler);
167#endif
168#ifdef SIGIOT
169     signal(SIGIOT, crash_handler);
170#endif
171#ifdef SIGEMT
172     signal(SIGEMT, crash_handler);
173#endif
174#ifdef SIGFPE
175     signal(SIGFPE, crash_handler);
176#endif
177#ifdef SIGBUS
178     signal(SIGBUS, crash_handler);
179#endif
180#ifdef SIGSEGV
181     signal(SIGSEGV, crash_handler);
182#endif
183#ifdef SIGPIPE
184     signal(SIGPIPE, SIG_IGN);
185#endif
186     /*
187      * Set up hooks in case we get a graceful die signal
188      */
189     signal(SIGHUP, sig_do_quit);
190     signal(SIGINT, sig_do_quit);
191     signal(SIGTERM, sig_do_quit);
192     
193     {
194          register char *user = getpwuid(getuid())->pw_name;
195          register char *realm = local_realm();
196
197          user_id = malloc((unsigned)(strlen(user)+strlen(realm)+2));
198          strcpy(user_id, user);
199          strcat(user_id, "@");
200          strcat(user_id, realm);
201     }
202
203     stdout_tf = unix_tfile(1);         /* stdout tfile */
204
205     while (1) {
206          set_warning_hook(log_warn);
207#ifdef EDSC_CACHE
208          if (cache_working)
209                  do_cache_work();
210#endif
211             
212          if (fgets(input_buf, INPUT_BUFF_SIZE, stdin) == NULL)
213                  do_quit(0);
214
215          if (input_buf[0] != '(') {
216bad_syntax:
217               printf(";Incorrect syntax\n");
218               continue;
219          }
220
221          cp = &input_buf[1];
222          if (get_word(&cp,&op,") ",&delim) < 0)
223               goto bad_syntax;
224
225          args = cp;
226          /* Depending on the operation, call the routine */
227          for (i = 0; i < NUM_EDSC_REQUESTS; i++) {
228                  if (!strcmp (op, edscr[i].name)) {
229                          (*(edscr[i].routine))(args);
230                          break;
231                  }
232          }
233          if (i >= NUM_EDSC_REQUESTS)
234                  printf(";Unimplemented operation\n");
235
236          fflush(stdout);
237          }               
238}
239
240log_warn(code, message)
241int code;
242char *message;
243{
244     printf("-%s %s\n", error_message(code), message);
245}
246
247bit_bucket(code, message)
248int code;
249char *message;
250{
251}
252
253do_quit(args)
254        char    *args;
255{
256#ifdef EDSC_CACHE
257        signal(SIGHUP, SIG_IGN);
258        signal(SIGINT, SIG_IGN);
259        signal(SIGTERM, SIG_IGN);
260        cache_shutdown();
261#endif
262        exit(0);
263}
264
265void sig_do_quit()
266{
267        do_quit(NULL);
268}
Note: See TracBrowser for help on using the repository browser.