119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Listener loop for subsystem library libss.a.
319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *	$Header$
519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *	$Locker$
63984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright 1987, 1988 by MIT Student Information Processing Board
819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Permission to use, copy, modify, and distribute this software and
1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * its documentation for any purpose is hereby granted, provided that
1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * advertising or publicity pertaining to distribution of the software
1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * without specific, written prior permission.  M.I.T. and the
1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * M.I.T. S.I.P.B. make no representations about the suitability of
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * this software for any purpose.  It is provided "as is" without
1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * express or implied warranty.
1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ss_internal.h"
2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h>
2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <setjmp.h>
2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <signal.h>
2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/param.h>
2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecttypedef void sigret_t;
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic ss_data *current_info;
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic jmp_buf listen_jmpb;
2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic sigret_t (*sig_cont)(int);
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic sigret_t print_prompt(int sig __SS_ATTR((unused)))
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    if (current_info->redisplay)
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    (*current_info->redisplay)();
3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    else {
3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    (void) fputs(current_info->prompt, stdout);
3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    (void) fflush(stdout);
3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    }
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic sigret_t listen_int_handler(int sig __SS_ATTR((unused)))
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    putc('\n', stdout);
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    signal(SIGINT, listen_int_handler);
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    longjmp(listen_jmpb, 1);
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint ss_listen (int sci_idx)
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    char *cp;
5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    ss_data *info;
5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    sigret_t (*sig_int)(int), (*old_sig_cont)(int);
5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    char input[BUFSIZ];
5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    sigset_t omask, igmask;
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    int code;
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    jmp_buf old_jmpb;
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    ss_data *old_info = current_info;
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    char *line;
593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    current_info = info = ss_info(sci_idx);
6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    sig_cont = (sigret_t (*)(int)) 0;
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    info->abort = 0;
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    sigemptyset(&igmask);
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    sigaddset(&igmask, SIGINT);
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    sigprocmask(SIG_BLOCK, &igmask, &omask);
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf));
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    sig_int = signal(SIGINT, listen_int_handler);
6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    setjmp(listen_jmpb);
6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    while(!info->abort) {
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	old_sig_cont = sig_cont;
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sig_cont = signal(SIGCONT, print_prompt);
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sig_cont == print_prompt)
7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    sig_cont = old_sig_cont;
7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (info->readline) {
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		line = (*info->readline)(current_info->prompt);
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else {
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		print_prompt(0);
8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fgets(input, BUFSIZ, stdin) == input)
8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			line = input;
8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else
8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			line = NULL;
843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		input[BUFSIZ-1] = 0;
8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (line == NULL) {
8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		code = SS_ET_EOF;
8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		(void) signal(SIGCONT, sig_cont);
9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto egress;
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	cp = strchr(line, '\n');
9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (cp) {
9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    *cp = '\0';
9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    if (cp == line)
9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		continue;
9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	(void) signal(SIGCONT, sig_cont);
10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (info->add_history)
10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		(*info->add_history)(line);
10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	code = ss_execute_line (sci_idx, line);
10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (code == SS_ET_COMMAND_NOT_FOUND) {
10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    register char *c = line;
10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    while (*c == ' ' || *c == '\t')
10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		c++;
10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    cp = strchr (c, ' ');
10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    if (cp)
11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*cp = '\0';
11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    cp = strchr (c, '\t');
11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    if (cp)
11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*cp = '\0';
11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    ss_error (sci_idx, 0,
11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    "Unknown request \"%s\".  Type \"?\" for a request list.",
11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       c);
11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (info->readline)
11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		free(line);
12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    }
12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    code = 0;
12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectegress:
12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    (void) signal(SIGINT, sig_int);
12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    memcpy(listen_jmpb, old_jmpb, sizeof(jmp_buf));
12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    current_info = old_info;
12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    return code;
12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid ss_abort_subsystem(int sci_idx, int code)
13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    ss_info(sci_idx)->abort = 1;
13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    ss_info(sci_idx)->exit_status = code;
1333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid ss_quit(int argc __SS_ATTR((unused)),
1373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	     const char * const *argv __SS_ATTR((unused)),
13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     int sci_idx, pointer infop __SS_ATTR((unused)))
13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    ss_abort_subsystem(sci_idx, 0);
14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_DLOPEN
14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define get_request(tbl,idx)    ((tbl) -> requests + (idx))
14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic char *cmd_generator(const char *text, int state)
14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static int	len;
14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static ss_request_table **rqtbl;
15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static int	curr_rqt;
15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static char const * const * name;
15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ss_request_entry *request;
15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char		*ret;
1543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (state == 0) {
15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		len = strlen(text);
15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		rqtbl = current_info->rqt_tables;
15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!rqtbl || !*rqtbl)
15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return 0;
16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		curr_rqt = 0;
16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		name = 0;
16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (1) {
16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!name || !*name) {
16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			request = get_request(*rqtbl, curr_rqt++);
16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			name = request->command_names;
16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!name) {
16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				rqtbl++;
17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (*rqtbl) {
17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					curr_rqt = 0;
17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					continue;
17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				} else
17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					break;
17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (strncmp(*name, text, len) == 0) {
17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ret = malloc(strlen(*name)+1);
17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ret)
18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				strcpy(ret, *name);
18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			name++;
18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return ret;
18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		name++;
18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtchar **ss_rl_completion(const char *text, int start,
19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			int end __SS_ATTR((unused)))
19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((start == 0) && current_info->rl_completion_matches)
19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return (*current_info->rl_completion_matches)
19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			(text, cmd_generator);
19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
200