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

Last change on this file since 706 was 703, checked in by guerin, 9 years ago

shell: add sleep command, misc fixes

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