Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
141 Kevin 1
/*
2
 * esh - the 'extensible' shell.
3
 *
4
 * Developed by Godmar Back for CS 3214 Fall 2009
5
 * Virginia Tech.
6
 * 
7
 * $Id: esh.h,v 1.4 2011/03/29 15:46:28 cs3214 Exp $
8
 */
9
 
10
#include <stdbool.h>
11
#include <obstack.h>
12
#include <stdlib.h>
13
#include <termios.h>
14
#include "list.h"
15
 
16
/* Forward declarations. */
17
struct esh_command;
18
struct esh_pipeline;
19
struct esh_command_line;
20
 
21
/*
22
 * A esh_shell object allows plugins to access services and information. 
23
 * The shell object should support the following operations.
24
 */
25
struct esh_shell {
26
 
27
    /* Return the list of current jobs */
28
    struct list/* <esh_pipeline> */ * (* get_jobs) (void);
29
 
30
    /* Return job corresponding to jid */
31
    struct esh_pipeline * (* get_job_from_jid)(int jid);
32
 
33
    /* Return job corresponding to pgrp */
34
    struct esh_pipeline * (* get_job_from_pgrp)(pid_t pgrp);
35
 
36
    /* Return process corresponding to pid */
37
    struct esh_command * (* get_cmd_from_pid)(pid_t pid);
38
 
39
    /* Build a prompt.  Memory must be malloc'd */
40
    char * (* build_prompt) (void);
41
 
42
    /* Read an input line */
43
    char * (* readline) (const char *prompt);
44
 
45
    /* Parse command line */
46
    struct esh_command_line * (* parse_command_line) (char *);
47
};
48
 
49
/* 
50
 * Modules must define a esh_plugin instance named 'esh_module.'
51
 * Each of the following members is optional.
52
 * esh will call its 'init' functions upon successful load.
53
 *
54
 * For binary compatibility, do not change the order of these fields.
55
 */
56
struct esh_plugin {
57
    struct list_elem elem;    /* Link element */
58
 
59
    /* an integer number denoting the relative rank of the plugin
60
     * Plugins are notified of events in increasing rank. */
61
    int rank;
62
 
63
    /* Initialize plugin and pass shell object */
64
    bool (* init)(struct esh_shell *);
65
 
66
    /* The return value of the following three functions indicates
67
     * whether the plugin wants processing to stop.
68
     * true - indicates processing should stop.
69
     * false - indicates processing should continue.
70
     */
71
    /* The command line the user entered.
72
     * A plugin may change it. */
73
    bool (* process_raw_cmdline)(char **);
74
 
75
    /* A given pipeline of commands 
76
     * A plugin may change it. */
77
    bool (* process_pipeline)(struct esh_pipeline *);
78
 
79
    /* If the command is a built-in provided by a plugin, execute the
80
     * command and return true. */
81
    bool (* process_builtin)(struct esh_command *);
82
 
83
    /* Manufacture part of a prompt.  Memory must be allocated via malloc(). 
84
     * If no plugin implements this, the shell will provide a default prompt. */
85
    char * (* make_prompt)(void);
86
 
87
    /* The process or processes that are part of a new pipeline
88
     * have been forked.  
89
     * The jid and pgid fields of the pipeline and the pid fields
90
     * of all commands in the pipeline are set.
91
     * SIGCHLD is blocked.
92
     */
93
    void (* pipeline_forked)(struct esh_pipeline *);
94
 
95
    /* Notify the plugin about a child's status change.
96
     * 'waitstatus' is the value returned by waitpid(2) 
97
     *
98
     * May be called from SIGCHLD handler.
99
     * The status of the associated pipeline has not yet been
100
     * updated.
101
     * */
102
    bool (* command_status_change)(struct esh_command *, int waitstatus);
103
 
104
    /* Add additional fields here if needed. */
105
};
106
 
107
/* A command line may contain multiple pipelines. */
108
struct esh_command_line {
109
    struct list/* <esh_pipeline> */ pipes;        /* List of pipelines */
110
 
111
    /* Add additional fields here if needed. */
112
};
113
 
114
enum job_status  { 
115
    FOREGROUND,     /* job is running in foreground.  Only one job can be
116
                       in the foreground state. */
117
    BACKGROUND,     /* job is running in background */
118
    STOPPED,        /* job is stopped via SIGSTOP */
119
    NEEDSTERMINAL,  /* job is stopped because it was a background job
120
                       and requires exclusive terminal access */
121
    COMPLETED,
122
    TERMINATED,
123
};
124
 
125
/* A pipeline is a list of one or more commands. 
126
 * For the purposes of job control, a pipeline forms one job.
127
 */
128
struct esh_pipeline {
129
    struct list/* <esh_command> */ commands;    /* List of commands */
130
    char *iored_input;       /* If non-NULL, first command should read from
131
                                file 'iored_input' */
132
    char *iored_output;      /* If non-NULL, last command should write to
133
                                file 'iored_output' */
134
    bool append_to_output;   /* True if user typed >> to append */
135
    bool bg_job;             /* True if user entered & */
136
    struct list_elem elem;   /* Link element. */
137
 
138
    int     jid;             /* Job id. */
139
    pid_t   pgrp;            /* Process group. */
140
    enum job_status status;  /* Job status. */ 
141
    struct termios saved_tty_state;  /* The state of the terminal when this job was 
142
                                        stopped after having been in foreground */
143
 
144
    /* Add additional fields here if needed. */
145
    char cmd_string[256];   /* Command string */
146
};
147
 
148
/* A command is part of a pipeline. */
149
struct esh_command {
150
    char **argv;             /* NULL terminated array of pointers to words
151
                                making up this command. */
152
    char *iored_input;       /* If non-NULL, command should read from
153
                                file 'iored_input' */
154
    char *iored_output;      /* If non-NULL, command should write to
155
                                file 'iored_output' */
156
    bool append_to_output;   /* True if user typed >> to append */
157
    struct list_elem elem;   /* Link element to link commands in pipeline. */
158
 
159
    pid_t   pid;             /* Process id. */
160
    struct esh_pipeline * pipeline; 
161
                              /* The pipeline of which this job is a part. */
162
 
163
    /* Add additional fields here if needed. */
164
};
165
 
166
/** ----------------------------------------------------------- */
167
 
168
/* Create new command structure and initialize it */
169
struct esh_command * esh_command_create(char ** argv, 
170
                   char *iored_input, 
171
                   char *iored_output, 
172
                   bool append_to_output);
173
 
174
/* Create a new pipeline containing only one command */
175
struct esh_pipeline * esh_pipeline_create(struct esh_command *cmd);
176
 
177
/* Complete a pipe's setup by copying I/O redirection information
178
 * from first and last command */
179
void esh_pipeline_finish(struct esh_pipeline *pipe);
180
 
181
/* Create an empty command line */
182
struct esh_command_line * esh_command_line_create_empty(void);
183
 
184
/* Create a command line with a single pipeline */
185
struct esh_command_line * esh_command_line_create(struct esh_pipeline *pipe);
186
 
187
/* Deallocation functions */
188
void esh_command_line_free(struct esh_command_line *);
189
void esh_pipeline_free(struct esh_pipeline *);
190
void esh_command_free(struct esh_command *);
191
 
192
/* Print functions */
193
void esh_command_print(struct esh_command *cmd);
194
void esh_pipeline_print(struct esh_pipeline *pipe);
195
void esh_command_line_print(struct esh_command_line *line);
196
 
197
/* Parse a command line.  Implemented in esh-grammar.y */
198
struct esh_command_line * esh_parse_command_line(char * line);
199
 
200
/* Load plugins from directory dir */
201
void esh_plugin_load_from_directory(char *dirname);
202
 
203
/* Initialize loaded plugins */
204
void esh_plugin_initialize(struct esh_shell *shell);
205
 
206
/* List of loaded plugins */
207
extern struct list esh_plugin_list;