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

Last change on this file since 712 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
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
[712]16
[640]17struct command_t
18{
19    char *name;
[708]20    char *desc;
[640]21    void (*fn)(int, char**);
22};
[589]23
[640]24////////////////////////////////////////////////////////////////////////////////
[643]25//  Shell  Commands
26////////////////////////////////////////////////////////////////////////////////
[640]27
28struct command_t cmd[];
29
[643]30///////////////////////////////////////////
[640]31static void cmd_help(int argc, char** argv)
[589]32{
[640]33    int i;
[589]34
[640]35    giet_tty_printf("available commands:\n");
[610]36
[640]37    for (i = 0; cmd[i].name; i++)
[589]38    {
[708]39        giet_tty_printf("\t%s\t : %s\n", cmd[i].name , cmd[i].desc );
[589]40    }
[640]41}
42
[708]43///////////////////////////////////////////
44static void cmd_time(int argc, char** argv)
[640]45{
[708]46    giet_tty_printf("%d\n", giet_proctime());
[640]47}
48
[643]49/////////////////////////////////////////
[640]50static void cmd_ls(int argc, char** argv)
51{
[660]52    int fd;
53    fat_dirent_t entry;
54
[640]55    if (argc < 2)
[708]56    {
57        giet_tty_printf("  usage : %s <pathname>\n", argv[0]);
58        return;
59    }
[660]60
[708]61    fd = giet_fat_opendir(argv[1]);
62
[660]63    if (fd < 0)
[589]64    {
[708]65        giet_tty_printf("  error : cannot open %s / err = %d)\n", argv[1], fd);
[640]66        return;
[589]67    }
68
[660]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);
[640]81}
82
[643]83////////////////////////////////////////////
[640]84static void cmd_mkdir(int argc, char** argv)
85{
86    if (argc < 2)
[589]87    {
[708]88        giet_tty_printf("  usage : %s <path>\n", argv[0]);
[640]89        return;
[589]90    }
[640]91
92    int ret = giet_fat_mkdir(argv[1]);
[708]93
[640]94    if (ret < 0)
[589]95    {
[708]96        giet_tty_printf("  error : cannot create directory %s / err = %d\n", argv[1], ret);
[589]97    }
[640]98}
[589]99
[643]100/////////////////////////////////////////
[640]101static void cmd_cp(int argc, char** argv)
102{
103    if (argc < 3)
[589]104    {
[708]105        giet_tty_printf("  usage : %s <src> <dst>\n", argv[0]);
[640]106        return;
[589]107    }
108
[640]109    char buf[1024];
110    int src_fd = -1;
111    int dst_fd = -1;
[660]112    fat_file_info_t info;
[640]113    int size;
114    int i;
115
116    src_fd = giet_fat_open( argv[1] , O_RDONLY );
117    if (src_fd < 0)
[589]118    {
[708]119        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[1], src_fd);
[640]120        goto exit;
[589]121    }
[640]122
123    giet_fat_file_info(src_fd, &info);
[708]124
[640]125    if (info.is_dir)
[589]126    {
[708]127        giet_tty_printf("  error : %s is a directory\n", argv[1] );
[640]128        goto exit;
[589]129    }
[708]130
[640]131    size = info.size;
[589]132
[654]133    dst_fd = giet_fat_open( argv[2] , O_CREATE | O_TRUNC );
[708]134
[640]135    if (dst_fd < 0)
[589]136    {
[708]137        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[2], dst_fd);
[640]138        goto exit;
[589]139    }
140
[640]141    giet_fat_file_info(dst_fd, &info);
[708]142
[640]143    if (info.is_dir)
[589]144    {
[708]145        giet_tty_printf("error : %s is a directory\n", argv[2] );  // TODO
[640]146        goto exit;
[589]147    }
[640]148
149    i = 0;
150    while (i < size)
[589]151    {
[640]152        int len = (size - i < 1024 ? size - i : 1024);
153        int wlen;
154
[655]155        giet_tty_printf("\rwrite %d/%d (%d%%)", i, size, 100*i/size);
156
[640]157        len = giet_fat_read(src_fd, &buf, len);
158        wlen = giet_fat_write(dst_fd, &buf, len);
159        if (wlen != len)
160        {
[708]161            giet_tty_printf("  error : cannot write on device\n");
[640]162            goto exit;
163        }
164        i += len;
[589]165    }
[655]166    giet_tty_printf("\n");
[589]167
[640]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
[669]175/////////////////////////////////////////
[640]176static void cmd_rm(int argc, char **argv)
177{
178    if (argc < 2)
[589]179    {
[708]180        giet_tty_printf("  usage : %s <file>\n", argv[0]);
[640]181        return;
[589]182    }
[640]183
184    int ret = giet_fat_remove(argv[1], 0);
[708]185
[640]186    if (ret < 0)
[589]187    {
[708]188        giet_tty_printf("  error : cannot remove %s / err = %d\n", argv[1], ret );
[589]189    }
[640]190}
[589]191
[643]192////////////////////////////////////////////
[640]193static void cmd_rmdir(int argc, char **argv)
194{
195    if (argc < 2)
[589]196    {
[708]197        giet_tty_printf("  usage : %s <pathname>\n", argv[0]);
[640]198        return;
[589]199    }
[640]200
201    int ret = giet_fat_remove(argv[1], 1);
202    if (ret < 0)
[589]203    {
[708]204        giet_tty_printf("  error : cannot remove %s / err = %d\n", argv[1], ret );
[589]205    }
[640]206}
[589]207
[643]208/////////////////////////////////////////
[640]209static void cmd_mv(int argc, char **argv)
210{
211    if (argc < 3)
[589]212    {
[708]213        giet_tty_printf("  usage : %s <src> <dst>\n", argv[0]);
[640]214        return;
[589]215    }
[640]216
217    int ret = giet_fat_rename(argv[1], argv[2]);
218    if (ret < 0)
[589]219    {
[708]220        giet_tty_printf("error : cannot move %s to %s / err = %d\n", argv[1], argv[2], ret );
[589]221    }
[640]222}
[589]223
[643]224///////////////////////////////////////////
225static void cmd_exec(int argc, char **argv)
226{
227    if (argc < 2)
228    {
[708]229        giet_tty_printf("  usage : %s <vspace_name>\n", argv[0]);
[643]230        return;
231    }
232
233    int ret = giet_exec_application(argv[1]);
234    if ( ret == -1 )
235    {
[708]236        giet_tty_printf("  error : %s not found\n", argv[1] );
[643]237    }
238}
239
240///////////////////////////////////////////
241static void cmd_kill(int argc, char **argv)
242{
243    if (argc < 2)
244    {
[708]245        giet_tty_printf("  usage : %s <vspace_name>\n", argv[0]);
[643]246        return;
247    }
248
249    int ret = giet_kill_application(argv[1]);
250    if ( ret == -1 )
251    {
[708]252        giet_tty_printf("  error : %s not found\n", argv[1] );
[643]253    }
254    if ( ret == -2 )
255    {
[708]256        giet_tty_printf("  error : %s cannot be killed\n", argv[1] );
[643]257    }
258}
259
[708]260/////////////////////////////////////////
[687]261static void cmd_ps(int argc, char** argv)
262{
[712]263    if (argc == 1)
264    {
265        giet_applications_status( NULL );
266    }
267    else
268    {
269        giet_applications_status( argv[1] );
270    }
[687]271}
272
[708]273////////////////////////////////////////////
274static void cmd_pause(int argc, char** argv)
[703]275{
[708]276    if (argc < 3)
277    {
278        giet_tty_printf("  usage : %s <vspace_name> <thread_name>\n", argv[0] );
279        return;
280    }
[703]281
[712]282    giet_pthread_control( THREAD_CMD_PAUSE , argv[1] , argv[2] );
[708]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] );
[703]291        return;
292    }
293
[712]294    giet_pthread_control( THREAD_CMD_RESUME , argv[1] , argv[2] );
[703]295}
296
[708]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
[712]306    giet_pthread_control( THREAD_CMD_CONTEXT , argv[1] , argv[2] );
[708]307}
308
309
[643]310////////////////////////////////////////////////////////////////////
[640]311struct command_t cmd[] =
312{
[708]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 }
[640]328};
329
[643]330// shell
[640]331
[708]332////////////////////////////
[703]333static void parse(char *buf)
[640]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++)
[589]342    {
[640]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        }
[589]355    }
[640]356
357    if (argc > 0)
[589]358    {
[640]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        {
[643]375            giet_tty_printf("undefined command %s\n", argv[0]);
[640]376        }
[589]377    }
[640]378}
[589]379
[643]380////////////////////
[640]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
[669]394    // get a private TTY
395    giet_tty_alloc( 0 );
[708]396    giet_tty_printf( "~~~ shell ~~~\n\n" );
[669]397
398    // display first prompt
[640]399    prompt();
400
401    while (1)
[589]402    {
[640]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';
[703]419                parse((char*)&buf);
[640]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        }
[589]440    }
441} // end main()
442
443// Local Variables:
[640]444// tab-width: 4
445// c-basic-offset: 4
[589]446// c-file-offsets:((innamespace . 0)(inline-open . 0))
447// indent-tabs-mode: nil
448// End:
[640]449// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
[589]450
Note: See TracBrowser for help on using the repository browser.