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
RevLine 
[589]1///////////////////////////////////////////////////////////////////////////////////////
[708]2// File   : shell.c   
[640]3// Date   : july 2015
4// author : Clément Guérin
[589]5///////////////////////////////////////////////////////////////////////////////////////
[640]6// Simple shell for GIET_VM.
[589]7///////////////////////////////////////////////////////////////////////////////////////
8
9#include "stdio.h"
[703]10#include "stdlib.h"
[589]11#include "malloc.h"
12
[640]13#define BUF_SIZE    (256)
14#define MAX_ARGS    (32)
[589]15
[640]16struct command_t
17{
18    char *name;
[708]19    char *desc;
[640]20    void (*fn)(int, char**);
21};
[589]22
[640]23////////////////////////////////////////////////////////////////////////////////
[643]24//  Shell  Commands
25////////////////////////////////////////////////////////////////////////////////
[640]26
27struct command_t cmd[];
28
[643]29///////////////////////////////////////////
[640]30static void cmd_help(int argc, char** argv)
[589]31{
[640]32    int i;
[589]33
[640]34    giet_tty_printf("available commands:\n");
[610]35
[640]36    for (i = 0; cmd[i].name; i++)
[589]37    {
[708]38        giet_tty_printf("\t%s\t : %s\n", cmd[i].name , cmd[i].desc );
[589]39    }
[640]40}
41
[708]42///////////////////////////////////////////
43static void cmd_time(int argc, char** argv)
[640]44{
[708]45    giet_tty_printf("%d\n", giet_proctime());
[640]46}
47
[643]48/////////////////////////////////////////
[640]49static void cmd_ls(int argc, char** argv)
50{
[660]51    int fd;
52    fat_dirent_t entry;
53
[640]54    if (argc < 2)
[708]55    {
56        giet_tty_printf("  usage : %s <pathname>\n", argv[0]);
57        return;
58    }
[660]59
[708]60    fd = giet_fat_opendir(argv[1]);
61
[660]62    if (fd < 0)
[589]63    {
[708]64        giet_tty_printf("  error : cannot open %s / err = %d)\n", argv[1], fd);
[640]65        return;
[589]66    }
67
[660]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);
[640]80}
81
[643]82////////////////////////////////////////////
[640]83static void cmd_mkdir(int argc, char** argv)
84{
85    if (argc < 2)
[589]86    {
[708]87        giet_tty_printf("  usage : %s <path>\n", argv[0]);
[640]88        return;
[589]89    }
[640]90
91    int ret = giet_fat_mkdir(argv[1]);
[708]92
[640]93    if (ret < 0)
[589]94    {
[708]95        giet_tty_printf("  error : cannot create directory %s / err = %d\n", argv[1], ret);
[589]96    }
[640]97}
[589]98
[643]99/////////////////////////////////////////
[640]100static void cmd_cp(int argc, char** argv)
101{
102    if (argc < 3)
[589]103    {
[708]104        giet_tty_printf("  usage : %s <src> <dst>\n", argv[0]);
[640]105        return;
[589]106    }
107
[640]108    char buf[1024];
109    int src_fd = -1;
110    int dst_fd = -1;
[660]111    fat_file_info_t info;
[640]112    int size;
113    int i;
114
115    src_fd = giet_fat_open( argv[1] , O_RDONLY );
116    if (src_fd < 0)
[589]117    {
[708]118        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[1], src_fd);
[640]119        goto exit;
[589]120    }
[640]121
122    giet_fat_file_info(src_fd, &info);
[708]123
[640]124    if (info.is_dir)
[589]125    {
[708]126        giet_tty_printf("  error : %s is a directory\n", argv[1] );
[640]127        goto exit;
[589]128    }
[708]129
[640]130    size = info.size;
[589]131
[654]132    dst_fd = giet_fat_open( argv[2] , O_CREATE | O_TRUNC );
[708]133
[640]134    if (dst_fd < 0)
[589]135    {
[708]136        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[2], dst_fd);
[640]137        goto exit;
[589]138    }
139
[640]140    giet_fat_file_info(dst_fd, &info);
[708]141
[640]142    if (info.is_dir)
[589]143    {
[708]144        giet_tty_printf("error : %s is a directory\n", argv[2] );  // TODO
[640]145        goto exit;
[589]146    }
[640]147
148    i = 0;
149    while (i < size)
[589]150    {
[640]151        int len = (size - i < 1024 ? size - i : 1024);
152        int wlen;
153
[655]154        giet_tty_printf("\rwrite %d/%d (%d%%)", i, size, 100*i/size);
155
[640]156        len = giet_fat_read(src_fd, &buf, len);
157        wlen = giet_fat_write(dst_fd, &buf, len);
158        if (wlen != len)
159        {
[708]160            giet_tty_printf("  error : cannot write on device\n");
[640]161            goto exit;
162        }
163        i += len;
[589]164    }
[655]165    giet_tty_printf("\n");
[589]166
[640]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
[669]174/////////////////////////////////////////
[640]175static void cmd_rm(int argc, char **argv)
176{
177    if (argc < 2)
[589]178    {
[708]179        giet_tty_printf("  usage : %s <file>\n", argv[0]);
[640]180        return;
[589]181    }
[640]182
183    int ret = giet_fat_remove(argv[1], 0);
[708]184
[640]185    if (ret < 0)
[589]186    {
[708]187        giet_tty_printf("  error : cannot remove %s / err = %d\n", argv[1], ret );
[589]188    }
[640]189}
[589]190
[643]191////////////////////////////////////////////
[640]192static void cmd_rmdir(int argc, char **argv)
193{
194    if (argc < 2)
[589]195    {
[708]196        giet_tty_printf("  usage : %s <pathname>\n", argv[0]);
[640]197        return;
[589]198    }
[640]199
200    int ret = giet_fat_remove(argv[1], 1);
201    if (ret < 0)
[589]202    {
[708]203        giet_tty_printf("  error : cannot remove %s / err = %d\n", argv[1], ret );
[589]204    }
[640]205}
[589]206
[643]207/////////////////////////////////////////
[640]208static void cmd_mv(int argc, char **argv)
209{
210    if (argc < 3)
[589]211    {
[708]212        giet_tty_printf("  usage : %s <src> <dst>\n", argv[0]);
[640]213        return;
[589]214    }
[640]215
216    int ret = giet_fat_rename(argv[1], argv[2]);
217    if (ret < 0)
[589]218    {
[708]219        giet_tty_printf("error : cannot move %s to %s / err = %d\n", argv[1], argv[2], ret );
[589]220    }
[640]221}
[589]222
[643]223///////////////////////////////////////////
224static void cmd_exec(int argc, char **argv)
225{
226    if (argc < 2)
227    {
[708]228        giet_tty_printf("  usage : %s <vspace_name>\n", argv[0]);
[643]229        return;
230    }
231
232    int ret = giet_exec_application(argv[1]);
233    if ( ret == -1 )
234    {
[708]235        giet_tty_printf("  error : %s not found\n", argv[1] );
[643]236    }
237}
238
239///////////////////////////////////////////
240static void cmd_kill(int argc, char **argv)
241{
242    if (argc < 2)
243    {
[708]244        giet_tty_printf("  usage : %s <vspace_name>\n", argv[0]);
[643]245        return;
246    }
247
248    int ret = giet_kill_application(argv[1]);
249    if ( ret == -1 )
250    {
[708]251        giet_tty_printf("  error : %s not found\n", argv[1] );
[643]252    }
253    if ( ret == -2 )
254    {
[708]255        giet_tty_printf("  error : %s cannot be killed\n", argv[1] );
[643]256    }
257}
258
[708]259/////////////////////////////////////////
[687]260static void cmd_ps(int argc, char** argv)
261{
[708]262    giet_applications_status();
[687]263}
264
[708]265////////////////////////////////////////////
266static void cmd_pause(int argc, char** argv)
[703]267{
[708]268    if (argc < 3)
269    {
270        giet_tty_printf("  usage : %s <vspace_name> <thread_name>\n", argv[0] );
271        return;
272    }
[703]273
[708]274    int ret = giet_pthread_pause( argv[1] , argv[2] );
275
276    if ( ret == -1 )
[703]277    {
[708]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] );
[703]292        return;
293    }
294
[708]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    }
[703]305}
306
[708]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
[643]329////////////////////////////////////////////////////////////////////
[640]330struct command_t cmd[] =
331{
[708]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 }
[640]347};
348
[643]349// shell
[640]350
[708]351////////////////////////////
[703]352static void parse(char *buf)
[640]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++)
[589]361    {
[640]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        }
[589]374    }
[640]375
376    if (argc > 0)
[589]377    {
[640]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        {
[643]394            giet_tty_printf("undefined command %s\n", argv[0]);
[640]395        }
[589]396    }
[640]397}
[589]398
[643]399////////////////////
[640]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
[669]413    // get a private TTY
414    giet_tty_alloc( 0 );
[708]415    giet_tty_printf( "~~~ shell ~~~\n\n" );
[669]416
417    // display first prompt
[640]418    prompt();
419
420    while (1)
[589]421    {
[640]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';
[703]438                parse((char*)&buf);
[640]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        }
[589]459    }
460} // end main()
461
462// Local Variables:
[640]463// tab-width: 4
464// c-basic-offset: 4
[589]465// c-file-offsets:((innamespace . 0)(inline-open . 0))
466// indent-tabs-mode: nil
467// End:
[640]468// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
[589]469
Note: See TracBrowser for help on using the repository browser.