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

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

Adapt the following application to the POSIX threads API

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