036550a4fe0ab6ccb7363e83bbdde3cc6c79f3f8
[lunaix-os.git] / lunaix-os / kernel / demos / simple_sh.c
1 #include <lunaix/fctrl.h>
2 #include <lunaix/foptions.h>
3 #include <lunaix/lunistd.h>
4 #include <lunaix/proc.h>
5 #include <lunaix/status.h>
6
7 #include <klibc/string.h>
8 #include <ulibc/stdio.h>
9
10 char pwd[512];
11
12 /*
13     Simple shell - (actually this is not even a shell)
14     It just to make the testing more easy.
15 */
16
17 void
18 parse_cmdline(char* line, char** cmd, char** arg_part)
19 {
20     strrtrim(line);
21     line = strltrim_safe(line);
22     int l = 0;
23     char c = 0;
24     while ((c = line[l])) {
25         if (c == ' ') {
26             line[l++] = 0;
27             break;
28         }
29         l++;
30     }
31     *cmd = line;
32     *arg_part = strltrim_safe(line + l);
33 }
34
35 void
36 sh_printerr()
37 {
38     int errno = geterrno();
39     switch (errno) {
40         case ENOTDIR:
41             printf("Error: Not a directory\n");
42             break;
43         case ENOENT:
44             printf("Error: No such file or directory\n");
45             break;
46         case EINVAL:
47             printf("Error: Invalid parameter or operation\n");
48             break;
49         case ENOTSUP:
50             printf("Error: Not supported\n");
51             break;
52         case EROFS:
53             printf("Error: File system is read only\n");
54             break;
55         case ENOMEM:
56             printf("Error: Out of memory\n");
57             break;
58         default:
59             printf("Error: Fail to open (%d)\n", errno);
60             break;
61     }
62 }
63
64 void
65 sh_main()
66 {
67     char buf[512];
68     char *cmd, *argpart;
69
70     while (1) {
71         getcwd(pwd, 512);
72         printf("%s> ", pwd);
73         size_t sz = read(stdin, buf, 512);
74         if (sz < 0) {
75             printf("fail to read user input (%d)\n", geterrno());
76             return;
77         }
78         buf[sz - 1] = '\0';
79         parse_cmdline(buf, &cmd, &argpart);
80         if (streq(cmd, "cd")) {
81             if (chdir(argpart) < 0) {
82                 sh_printerr();
83             }
84         } else if (streq(cmd, "ls")) {
85             int fd = open(argpart, 0);
86             if (fd < 0) {
87                 sh_printerr();
88             } else {
89                 struct dirent ent = { .d_offset = 0 };
90                 int status;
91                 while ((status = readdir(fd, &ent)) == 1) {
92                     printf(" %s\n", ent.d_name);
93                 }
94
95                 if (status < 0)
96                     sh_printerr();
97
98                 close(fd);
99             }
100         } else {
101             printf("unknow command");
102         }
103         printf("\n");
104     }
105 }