source: soft/giet_vm/applications/shell/shell.c @ 722

Last change on this file since 722 was 712, checked in by alain, 9 years ago

Introduce the giet_fbf_size() and giet_fbf_alloc() system calls.

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