~csurbhi/ubuntu/maverick/e2fsprogs/e2fsprogs.fix-505719

« back to all changes in this revision

Viewing changes to lib/ss/listen.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Zimmerman
  • Date: 2004-09-19 09:43:14 UTC
  • mto: (8.1.1 lenny) (1.2.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20040919094314-2tafd19i76fhu6ei
Tags: upstream-1.35
ImportĀ upstreamĀ versionĀ 1.35

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Listener loop for subsystem library libss.a.
3
3
 *
4
 
 *      $Header: lib/ss/SCCS/s.listen.c 1.16 02/03/07 23:52:55-05:00 tytso@think.thunk.org $
 
4
 *      $Header: lib/ss/SCCS/s.listen.c 1.19 03/12/07 01:28:48-05:00 tytso@think.thunk.org $
5
5
 *      $Locker: <Not implemented> $
6
6
 * 
7
7
 * Copyright 1987, 1988 by MIT Student Information Processing Board
21
21
#include <setjmp.h>
22
22
#include <signal.h>
23
23
#include <sys/param.h>
24
 
#ifdef BSD
25
 
#include <sgtty.h>
26
 
#endif
27
 
 
28
 
#ifndef lint
29
 
static char const rcs_id[] =
30
 
    "$Header: lib/ss/SCCS/s.listen.c 1.16 02/03/07 23:52:55-05:00 tytso@think.thunk.org $";
31
 
#endif
32
24
 
33
25
typedef void sigret_t;
34
26
 
36
28
static jmp_buf listen_jmpb;
37
29
static sigret_t (*sig_cont)(int);
38
30
 
39
 
static sigret_t print_prompt(int sig)
 
31
static sigret_t print_prompt(int sig __SS_ATTR((unused)))
40
32
{
41
 
#ifdef BSD
42
 
    /* put input into a reasonable mode */
43
 
    struct sgttyb ttyb;
44
 
    if (ioctl(fileno(stdin), TIOCGETP, &ttyb) != -1) {
45
 
        if (ttyb.sg_flags & (CBREAK|RAW)) {
46
 
            ttyb.sg_flags &= ~(CBREAK|RAW);
47
 
            (void) ioctl(0, TIOCSETP, &ttyb);
48
 
        }
 
33
    if (current_info->redisplay)
 
34
            (*current_info->redisplay)();
 
35
    else {
 
36
            (void) fputs(current_info->prompt, stdout);
 
37
            (void) fflush(stdout);
49
38
    }
50
 
#endif
51
 
    (void) fputs(current_info->prompt, stdout);
52
 
    (void) fflush(stdout);
53
39
}
54
40
 
55
 
static sigret_t listen_int_handler(int sig)
 
41
static sigret_t listen_int_handler(int sig __SS_ATTR((unused)))
56
42
{
57
43
    putc('\n', stdout);
58
44
    signal(SIGINT, listen_int_handler);
65
51
    ss_data *info;
66
52
    sigret_t (*sig_int)(int), (*old_sig_cont)(int);
67
53
    char input[BUFSIZ];
68
 
#ifdef POSIX_SIGNALS
69
54
    sigset_t omask, igmask;
70
 
#else
71
 
    int mask;
72
 
#endif
73
55
    int code;
74
56
    jmp_buf old_jmpb;
75
57
    ss_data *old_info = current_info;
 
58
    char *line;
76
59
    
77
60
    current_info = info = ss_info(sci_idx);
78
61
    sig_cont = (sigret_t (*)(int)) 0;
79
62
    info->abort = 0;
80
 
#ifdef POSIX_SIGNALS
81
63
    sigemptyset(&igmask);
82
64
    sigaddset(&igmask, SIGINT);
83
65
    sigprocmask(SIG_BLOCK, &igmask, &omask);
84
 
#else
85
 
    mask = sigblock(sigmask(SIGINT));
86
 
#endif
87
66
    memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf));
88
67
    sig_int = signal(SIGINT, listen_int_handler);
89
68
    setjmp(listen_jmpb);
90
 
#ifdef POSIX_SIGNALS
91
69
    sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0);
92
 
#else
93
 
    (void) sigsetmask(mask);
94
 
#endif
 
70
 
95
71
    while(!info->abort) {
96
 
        print_prompt(0);
97
72
        old_sig_cont = sig_cont;
98
73
        sig_cont = signal(SIGCONT, print_prompt);
99
74
        if (sig_cont == print_prompt)
100
75
            sig_cont = old_sig_cont;
101
 
        if (fgets(input, BUFSIZ, stdin) != input) {
102
 
            code = SS_ET_EOF;
103
 
            (void) signal(SIGCONT, sig_cont);
104
 
            goto egress;
105
 
        }
106
 
        input[BUFSIZ-1] = 0;
 
76
        if (info->readline) {
 
77
                line = (*info->readline)(current_info->prompt);
 
78
        } else {
 
79
                print_prompt(0);
 
80
                if (fgets(input, BUFSIZ, stdin) == input)
 
81
                        line = input;
 
82
                else
 
83
                        line = NULL;
107
84
        
108
 
        cp = strchr(input, '\n');
 
85
                input[BUFSIZ-1] = 0;
 
86
        }
 
87
        if (line == NULL) {
 
88
                code = SS_ET_EOF;
 
89
                (void) signal(SIGCONT, sig_cont);
 
90
                goto egress;
 
91
        }
 
92
                
 
93
        cp = strchr(line, '\n');
109
94
        if (cp) {
110
95
            *cp = '\0';
111
 
            if (cp == input)
 
96
            if (cp == line)
112
97
                continue;
113
98
        }
114
99
        (void) signal(SIGCONT, sig_cont);
 
100
        if (info->add_history)
 
101
                (*info->add_history)(line);
115
102
 
116
 
        code = ss_execute_line (sci_idx, input);
 
103
        code = ss_execute_line (sci_idx, line);
117
104
        if (code == SS_ET_COMMAND_NOT_FOUND) {
118
 
            register char *c = input;
 
105
            register char *c = line;
119
106
            while (*c == ' ' || *c == '\t')
120
107
                c++;
121
108
            cp = strchr (c, ' ');
128
115
                    "Unknown request \"%s\".  Type \"?\" for a request list.",
129
116
                       c);
130
117
        }
 
118
        if (info->readline)
 
119
                free(line);
131
120
    }
132
121
    code = 0;
133
122
egress:
144
133
    
145
134
}
146
135
 
147
 
void ss_quit(int argc, const char * const *argv, int sci_idx, pointer infop)
 
136
void ss_quit(int argc __SS_ATTR((unused)), 
 
137
             const char * const *argv __SS_ATTR((unused)), 
 
138
             int sci_idx, pointer infop __SS_ATTR((unused)))
148
139
{
149
140
    ss_abort_subsystem(sci_idx, 0);
150
141
}
 
142
 
 
143
#ifdef HAVE_DLOPEN
 
144
#define get_request(tbl,idx)    ((tbl) -> requests + (idx))
 
145
 
 
146
static char *cmd_generator(const char *text, int state)
 
147
{
 
148
        static int      len;
 
149
        static ss_request_table **rqtbl;
 
150
        static int      curr_rqt;
 
151
        static char const * const * name;
 
152
        ss_request_entry *request;
 
153
        char            *ret;
 
154
        
 
155
        if (state == 0) {
 
156
                len = strlen(text);
 
157
                rqtbl = current_info->rqt_tables;
 
158
                if (!rqtbl || !*rqtbl)
 
159
                        return 0;
 
160
                curr_rqt = 0;
 
161
                name = 0;
 
162
        }
 
163
 
 
164
        while (1) {
 
165
                if (!name || !*name) {
 
166
                        request = get_request(*rqtbl, curr_rqt++);
 
167
                        name = request->command_names;
 
168
                        if (!name) {
 
169
                                rqtbl++;
 
170
                                if (*rqtbl) {
 
171
                                        curr_rqt = 0;
 
172
                                        continue;
 
173
                                } else
 
174
                                        break;
 
175
                        }
 
176
                }
 
177
                if (strncmp(*name, text, len) == 0) {
 
178
                        ret = malloc(strlen(*name)+1);
 
179
                        if (ret)
 
180
                                strcpy(ret, *name);
 
181
                        name++;
 
182
                        return ret;
 
183
                }
 
184
                name++;
 
185
        }
 
186
 
 
187
        return 0;
 
188
}
 
189
 
 
190
char **ss_rl_completion(const char *text, int start, 
 
191
                        int end __SS_ATTR((unused)))
 
192
{
 
193
        if ((start == 0) && current_info->rl_completion_matches)
 
194
                return (*current_info->rl_completion_matches)
 
195
                        (text, cmd_generator);
 
196
        return 0;
 
197
}
 
198
#endif
 
199