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

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

Introduce the "exec" and "kill" commands in the shell application.

File size: 7.8 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"
[640]10#include "string.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{
50    if (argc < 2)
[589]51    {
[640]52        giet_tty_printf("%s <path>\n", argv[0]);
53        return;
[589]54    }
55
[640]56    giet_fat_list(argv[1]);
57}
58
[643]59////////////////////////////////////////////
[640]60static void cmd_mkdir(int argc, char** argv)
61{
62    if (argc < 2)
[589]63    {
[640]64        giet_tty_printf("%s <path>\n", argv[0]);
65        return;
[589]66    }
[640]67
68    int ret = giet_fat_mkdir(argv[1]);
69    if (ret < 0)
[589]70    {
[640]71        giet_tty_printf("can't create directory (err=%d)\n", ret);
[589]72    }
[640]73}
[589]74
[643]75/////////////////////////////////////////
[640]76static void cmd_cp(int argc, char** argv)
77{
78    if (argc < 3)
[589]79    {
[640]80        giet_tty_printf("%s <src> <dst>\n", argv[0]);
81        return;
[589]82    }
83
[640]84    char buf[1024];
85    int src_fd = -1;
86    int dst_fd = -1;
87    struct fat_file_info_s info;
88    int size;
89    int i;
90
91    src_fd = giet_fat_open( argv[1] , O_RDONLY );
92    if (src_fd < 0)
[589]93    {
[640]94        giet_tty_printf("can't open %s (err=%d)\n", argv[1], src_fd);
95        goto exit;
[589]96    }
[640]97
98    giet_fat_file_info(src_fd, &info);
99    if (info.is_dir)
[589]100    {
[640]101        giet_tty_printf("can't copy a directory\n", argv[1]);
102        goto exit;
[589]103    }
[640]104    size = info.size;
[589]105
[640]106    dst_fd = giet_fat_open( argv[2] , O_CREATE ); // TODO O_TRUNC
107    if (dst_fd < 0)
[589]108    {
[640]109        giet_tty_printf("can't open %s (err=%d)\n", argv[2], src_fd);
110        goto exit;
[589]111    }
112
[640]113    giet_fat_file_info(dst_fd, &info);
114    if (info.is_dir)
[589]115    {
[640]116        giet_tty_printf("can't copy to a directory\n", argv[2]); // TODO
117        goto exit;
[589]118    }
[640]119
120    i = 0;
121    while (i < size)
[589]122    {
[640]123        int len = (size - i < 1024 ? size - i : 1024);
124        int wlen;
125
126        len = giet_fat_read(src_fd, &buf, len);
127        wlen = giet_fat_write(dst_fd, &buf, len);
128        if (wlen != len)
129        {
130            giet_tty_printf("write error\n");
131            goto exit;
132        }
133        i += len;
[641]134        giet_tty_printf("wrote %d/%d (%d%%)\n", i, size, 100*i/size);
[589]135    }
136
[640]137exit:
138    if (src_fd >= 0)
139        giet_fat_close(src_fd);
140    if (dst_fd >= 0)
141        giet_fat_close(dst_fd);
142}
143
144static void cmd_rm(int argc, char **argv)
145{
146    if (argc < 2)
[589]147    {
[640]148        giet_tty_printf("%s <file>\n", argv[0]);
149        return;
[589]150    }
[640]151
152    int ret = giet_fat_remove(argv[1], 0);
153    if (ret < 0)
[589]154    {
[640]155        giet_tty_printf("can't remove %s (err=%d)\n", argv[1], ret);
[589]156    }
[640]157}
[589]158
[643]159////////////////////////////////////////////
[640]160static void cmd_rmdir(int argc, char **argv)
161{
162    if (argc < 2)
[589]163    {
[640]164        giet_tty_printf("%s <path>\n", argv[0]);
165        return;
[589]166    }
[640]167
168    int ret = giet_fat_remove(argv[1], 1);
169    if (ret < 0)
[589]170    {
[640]171        giet_tty_printf("can't remove %s (err=%d)\n", argv[1], ret);
[589]172    }
[640]173}
[589]174
[643]175/////////////////////////////////////////
[640]176static void cmd_mv(int argc, char **argv)
177{
178    if (argc < 3)
[589]179    {
[640]180        giet_tty_printf("%s <src> <dst>\n", argv[0]);
181        return;
[589]182    }
[640]183
184    int ret = giet_fat_rename(argv[1], argv[2]);
185    if (ret < 0)
[589]186    {
[640]187        giet_tty_printf("can't move %s to %s (err=%d)\n", argv[1], argv[2], ret);
[589]188    }
[640]189}
[589]190
[643]191///////////////////////////////////////////
192static void cmd_exec(int argc, char **argv)
193{
194    if (argc < 2)
195    {
196        giet_tty_printf("%s <pathname>\n", argv[0]);
197        return;
198    }
199
200    int ret = giet_exec_application(argv[1]);
201    if ( ret == -1 )
202    {
203        giet_tty_printf("\n  error : %s not found\n", argv[1] );
204    }
205}
206
207///////////////////////////////////////////
208static void cmd_kill(int argc, char **argv)
209{
210    if (argc < 2)
211    {
212        giet_tty_printf("%s <pathname>\n", argv[0]);
213        return;
214    }
215
216    int ret = giet_kill_application(argv[1]);
217    if ( ret == -1 )
218    {
219        giet_tty_printf("\n  error : %s not found\n", argv[1] );
220    }
221    if ( ret == -2 )
222    {
223        giet_tty_printf("\n  error : %s cannot be killed\n", argv[0] );
224    }
225}
226
227////////////////////////////////////////////////////////////////////
[640]228struct command_t cmd[] =
229{
230    { "help",       cmd_help },
231    { "proctime",   cmd_proctime },
232    { "ls",         cmd_ls },
233    { "mkdir",      cmd_mkdir },
234    { "cp",         cmd_cp },
235    { "rm",         cmd_rm },
236    { "rmdir",      cmd_rmdir },
237    { "mv",         cmd_mv },
[643]238    { "exec",       cmd_exec },
239    { "kill",       cmd_kill },
[640]240    { NULL,         NULL }
241};
242
[643]243// shell
[640]244
[643]245///////////////////////////////////////
246static void parse(char *buf, int count)
[640]247{
248    int argc = 0;
249    char* argv[MAX_ARGS];
250    int i;
251    int len = strlen(buf);
252
253    // build argc/argv
254    for (i = 0; i < len; i++)
[589]255    {
[640]256        if (buf[i] == ' ')
257        {
258            buf[i] = '\0';
259        }
260        else if (i == 0 || buf[i - 1] == '\0')
261        {
262            if (argc < MAX_ARGS)
263            {
264                argv[argc] = &buf[i];
265                argc++;
266            }
267        }
[589]268    }
[640]269
270    if (argc > 0)
[589]271    {
[640]272        int found = 0;
273
274        // try to match typed command with built-ins
275        for (i = 0; cmd[i].name; i++)
276        {
277            if (strcmp(argv[0], cmd[i].name) == 0)
278            {
279                // invoke
280                cmd[i].fn(argc, argv);
281                found = 1;
282                break;
283            }
284        }
285
286        if (!found)
287        {
[643]288            giet_tty_printf("undefined command %s\n", argv[0]);
[640]289        }
[589]290    }
[640]291}
[589]292
[643]293////////////////////
[640]294static void prompt()
295{
296    giet_tty_printf("# ");
297}
298
299//////////////////////////////////////////
300__attribute__ ((constructor)) void main()
301//////////////////////////////////////////
302{
303    char c;
304    char buf[BUF_SIZE];
305    int count = 0;
306
307    giet_shr_printf("\n[SHELL] Enter at cycle %d\n", giet_proctime());
308    giet_tty_alloc();
309    prompt();
310
311    while (1)
[589]312    {
[640]313        giet_tty_getc(&c);
314
315        switch (c)
316        {
317        case '\b':      // backspace
318            if (count > 0)
319            {
320                giet_tty_printf("\b \b");
321                count--;
322            }
323            break;
324        case '\n':      // new line
325            giet_tty_printf("\n");
326            if (count > 0)
327            {
328                buf[count] = '\0';
[643]329                parse((char*)&buf, count);
[640]330            }
331            prompt();
332            count = 0;
333            break;
334        case '\t':      // tabulation
335            // do nothing
336            break;
337        case '\03':     // ^C
338            giet_tty_printf("^C\n");
339            prompt();
340            count = 0;
341            break;
342        default:        // regular character
343            if (count < sizeof(buf) - 1)
344            {
345                giet_tty_printf("%c", c);
346                buf[count] = c;
347                count++;
348            }
349        }
[589]350    }
351} // end main()
352
353// Local Variables:
[640]354// tab-width: 4
355// c-basic-offset: 4
[589]356// c-file-offsets:((innamespace . 0)(inline-open . 0))
357// indent-tabs-mode: nil
358// End:
[640]359// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
[589]360
Note: See TracBrowser for help on using the repository browser.