source: soft/giet_vm/applications/shell/main.c @ 699

Last change on this file since 699 was 687, checked in by alain, 9 years ago

Introduce the ps command in shell.
Adapt the router application.

File size: 8.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////////
2// File   : main.c   (for shell application)
3// Date   : july 2015
4// author : Clément Guérin
5///////////////////////////////////////////////////////////////////////////////////////
6// Simple shell for GIET_VM.
7///////////////////////////////////////////////////////////////////////////////////////
8
9#include "stdio.h"
10#include "string.h"
11#include "malloc.h"
12
13#define BUF_SIZE    (256)
14#define MAX_ARGS    (32)
15
16struct command_t
17{
18    char *name;
19    void (*fn)(int, char**);
20};
21
22////////////////////////////////////////////////////////////////////////////////
23//  Shell  Commands
24////////////////////////////////////////////////////////////////////////////////
25
26struct command_t cmd[];
27
28///////////////////////////////////////////
29static void cmd_help(int argc, char** argv)
30{
31    int i;
32
33    giet_tty_printf("available commands:\n");
34
35    for (i = 0; cmd[i].name; i++)
36    {
37        giet_tty_printf("\t%s\n", cmd[i].name);
38    }
39}
40
41///////////////////////////////////////////////
42static void cmd_proctime(int argc, char** argv)
43{
44    giet_tty_printf("%u\n", giet_proctime());
45}
46
47/////////////////////////////////////////
48static void cmd_ls(int argc, char** argv)
49{
50    int fd;
51    fat_dirent_t entry;
52
53    if (argc < 2)
54        fd = giet_fat_opendir("/");
55    else
56        fd = giet_fat_opendir(argv[1]);
57
58    if (fd < 0)
59    {
60        giet_tty_printf("can't list directory (err=%d)\n", fd);
61        return;
62    }
63
64    while (giet_fat_readdir(fd, &entry) == 0)
65    {
66        if (entry.is_dir)
67            giet_tty_printf("dir ");
68        else
69            giet_tty_printf("file");
70
71        giet_tty_printf(" | size = %d \t| cluster = %X \t| %s\n",
72                        entry.size, entry.cluster, entry.name );
73    }
74
75    giet_fat_closedir(fd);
76}
77
78////////////////////////////////////////////
79static void cmd_mkdir(int argc, char** argv)
80{
81    if (argc < 2)
82    {
83        giet_tty_printf("%s <path>\n", argv[0]);
84        return;
85    }
86
87    int ret = giet_fat_mkdir(argv[1]);
88    if (ret < 0)
89    {
90        giet_tty_printf("can't create directory (err=%d)\n", ret);
91    }
92}
93
94/////////////////////////////////////////
95static void cmd_cp(int argc, char** argv)
96{
97    if (argc < 3)
98    {
99        giet_tty_printf("%s <src> <dst>\n", argv[0]);
100        return;
101    }
102
103    char buf[1024];
104    int src_fd = -1;
105    int dst_fd = -1;
106    fat_file_info_t info;
107    int size;
108    int i;
109
110    src_fd = giet_fat_open( argv[1] , O_RDONLY );
111    if (src_fd < 0)
112    {
113        giet_tty_printf("can't open %s (err=%d)\n", argv[1], src_fd);
114        goto exit;
115    }
116
117    giet_fat_file_info(src_fd, &info);
118    if (info.is_dir)
119    {
120        giet_tty_printf("can't copy a directory\n");
121        goto exit;
122    }
123    size = info.size;
124
125    dst_fd = giet_fat_open( argv[2] , O_CREATE | O_TRUNC );
126    if (dst_fd < 0)
127    {
128        giet_tty_printf("can't open %s (err=%d)\n", argv[2], dst_fd);
129        goto exit;
130    }
131
132    giet_fat_file_info(dst_fd, &info);
133    if (info.is_dir)
134    {
135        giet_tty_printf("can't copy to a directory\n"); // TODO
136        goto exit;
137    }
138
139    i = 0;
140    while (i < size)
141    {
142        int len = (size - i < 1024 ? size - i : 1024);
143        int wlen;
144
145        giet_tty_printf("\rwrite %d/%d (%d%%)", i, size, 100*i/size);
146
147        len = giet_fat_read(src_fd, &buf, len);
148        wlen = giet_fat_write(dst_fd, &buf, len);
149        if (wlen != len)
150        {
151            giet_tty_printf("\nwrite error\n");
152            goto exit;
153        }
154        i += len;
155    }
156    giet_tty_printf("\n");
157
158exit:
159    if (src_fd >= 0)
160        giet_fat_close(src_fd);
161    if (dst_fd >= 0)
162        giet_fat_close(dst_fd);
163}
164
165/////////////////////////////////////////
166static void cmd_rm(int argc, char **argv)
167{
168    if (argc < 2)
169    {
170        giet_tty_printf("%s <file>\n", argv[0]);
171        return;
172    }
173
174    int ret = giet_fat_remove(argv[1], 0);
175    if (ret < 0)
176    {
177        giet_tty_printf("can't remove %s (err=%d)\n", argv[1], ret);
178    }
179}
180
181////////////////////////////////////////////
182static void cmd_rmdir(int argc, char **argv)
183{
184    if (argc < 2)
185    {
186        giet_tty_printf("%s <path>\n", argv[0]);
187        return;
188    }
189
190    int ret = giet_fat_remove(argv[1], 1);
191    if (ret < 0)
192    {
193        giet_tty_printf("can't remove %s (err=%d)\n", argv[1], ret);
194    }
195}
196
197/////////////////////////////////////////
198static void cmd_mv(int argc, char **argv)
199{
200    if (argc < 3)
201    {
202        giet_tty_printf("%s <src> <dst>\n", argv[0]);
203        return;
204    }
205
206    int ret = giet_fat_rename(argv[1], argv[2]);
207    if (ret < 0)
208    {
209        giet_tty_printf("can't move %s to %s (err=%d)\n", argv[1], argv[2], ret);
210    }
211}
212
213///////////////////////////////////////////
214static void cmd_exec(int argc, char **argv)
215{
216    if (argc < 2)
217    {
218        giet_tty_printf("%s <pathname>\n", argv[0]);
219        return;
220    }
221
222    int ret = giet_exec_application(argv[1]);
223    if ( ret == -1 )
224    {
225        giet_tty_printf("\n  error : %s not found\n", argv[1] );
226    }
227}
228
229///////////////////////////////////////////
230static void cmd_kill(int argc, char **argv)
231{
232    if (argc < 2)
233    {
234        giet_tty_printf("%s <pathname>\n", argv[0]);
235        return;
236    }
237
238    int ret = giet_kill_application(argv[1]);
239    if ( ret == -1 )
240    {
241        giet_tty_printf("\n  error : %s not found\n", argv[1] );
242    }
243    if ( ret == -2 )
244    {
245        giet_tty_printf("\n  error : %s cannot be killed\n", argv[0] );
246    }
247}
248
249///////////////////////////////////////////////
250static void cmd_ps(int argc, char** argv)
251{
252    giet_tasks_status();
253}
254
255////////////////////////////////////////////////////////////////////
256struct command_t cmd[] =
257{
258    { "help",       cmd_help },
259    { "proctime",   cmd_proctime },
260    { "ls",         cmd_ls },
261    { "mkdir",      cmd_mkdir },
262    { "cp",         cmd_cp },
263    { "rm",         cmd_rm },
264    { "rmdir",      cmd_rmdir },
265    { "mv",         cmd_mv },
266    { "exec",       cmd_exec },
267    { "kill",       cmd_kill },
268    { "ps",         cmd_ps },
269    { NULL,         NULL }
270};
271
272// shell
273
274///////////////////////////////////////
275static void parse(char *buf, int count)
276{
277    int argc = 0;
278    char* argv[MAX_ARGS];
279    int i;
280    int len = strlen(buf);
281
282    // build argc/argv
283    for (i = 0; i < len; i++)
284    {
285        if (buf[i] == ' ')
286        {
287            buf[i] = '\0';
288        }
289        else if (i == 0 || buf[i - 1] == '\0')
290        {
291            if (argc < MAX_ARGS)
292            {
293                argv[argc] = &buf[i];
294                argc++;
295            }
296        }
297    }
298
299    if (argc > 0)
300    {
301        int found = 0;
302
303        // try to match typed command with built-ins
304        for (i = 0; cmd[i].name; i++)
305        {
306            if (strcmp(argv[0], cmd[i].name) == 0)
307            {
308                // invoke
309                cmd[i].fn(argc, argv);
310                found = 1;
311                break;
312            }
313        }
314
315        if (!found)
316        {
317            giet_tty_printf("undefined command %s\n", argv[0]);
318        }
319    }
320}
321
322////////////////////
323static void prompt()
324{
325    giet_tty_printf("# ");
326}
327
328//////////////////////////////////////////
329__attribute__ ((constructor)) void main()
330//////////////////////////////////////////
331{
332    char c;
333    char buf[BUF_SIZE];
334    int count = 0;
335
336    // get a private TTY
337    giet_tty_alloc( 0 );
338
339    // display first prompt
340    prompt();
341
342    while (1)
343    {
344        giet_tty_getc(&c);
345
346        switch (c)
347        {
348        case '\b':      // backspace
349            if (count > 0)
350            {
351                giet_tty_printf("\b \b");
352                count--;
353            }
354            break;
355        case '\n':      // new line
356            giet_tty_printf("\n");
357            if (count > 0)
358            {
359                buf[count] = '\0';
360                parse((char*)&buf, count);
361            }
362            prompt();
363            count = 0;
364            break;
365        case '\t':      // tabulation
366            // do nothing
367            break;
368        case '\03':     // ^C
369            giet_tty_printf("^C\n");
370            prompt();
371            count = 0;
372            break;
373        default:        // regular character
374            if (count < sizeof(buf) - 1)
375            {
376                giet_tty_printf("%c", c);
377                buf[count] = c;
378                count++;
379            }
380        }
381    }
382} // end main()
383
384// Local Variables:
385// tab-width: 4
386// c-basic-offset: 4
387// c-file-offsets:((innamespace . 0)(inline-open . 0))
388// indent-tabs-mode: nil
389// End:
390// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
391
Note: See TracBrowser for help on using the repository browser.