feat: taskfs for export process to filesystem
[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 char cat_buf[1024];
12
13 /*
14     Simple shell - (actually this is not even a shell)
15     It just to make the testing more easy.
16 */
17
18 void
19 parse_cmdline(char* line, char** cmd, char** arg_part)
20 {
21     strrtrim(line);
22     line = strltrim_safe(line);
23     int l = 0;
24     char c = 0;
25     while ((c = line[l])) {
26         if (c == ' ') {
27             line[l++] = 0;
28             break;
29         }
30         l++;
31     }
32     *cmd = line;
33     *arg_part = strltrim_safe(line + l);
34 }
35
36 void
37 sh_printerr()
38 {
39     int errno = geterrno();
40     switch (errno) {
41         case ENOTDIR:
42             printf("Error: Not a directory\n");
43             break;
44         case ENOENT:
45             printf("Error: No such file or directory\n");
46             break;
47         case EINVAL:
48             printf("Error: Invalid parameter or operation\n");
49             break;
50         case ENOTSUP:
51             printf("Error: Not supported\n");
52             break;
53         case EROFS:
54             printf("Error: File system is read only\n");
55             break;
56         case ENOMEM:
57             printf("Error: Out of memory\n");
58             break;
59         case EISDIR:
60             printf("Error: This is a directory\n");
61             break;
62         default:
63             printf("Error: Fail to open (%d)\n", errno);
64             break;
65     }
66 }
67
68 void
69 sh_main()
70 {
71     char buf[512];
72     char *cmd, *argpart;
73
74     printf("\n Simple shell. Use <PG_UP> or <PG_DOWN> to scroll.\n\n");
75
76     while (1) {
77         getcwd(pwd, 512);
78         printf("[\033[2m%s\033[39;49m]$ ", pwd);
79         size_t sz = read(stdin, buf, 512);
80         if (sz < 0) {
81             printf("fail to read user input (%d)\n", geterrno());
82             return;
83         }
84         buf[sz - 1] = '\0';
85         parse_cmdline(buf, &cmd, &argpart);
86         if (cmd[0] == 0) {
87             goto cont;
88         }
89         if (streq(cmd, "cd")) {
90             if (chdir(argpart) < 0) {
91                 sh_printerr();
92             }
93         } else if (streq(cmd, "ls")) {
94             int fd = open(argpart, 0);
95             if (fd < 0) {
96                 sh_printerr();
97             } else {
98                 struct dirent ent = { .d_offset = 0 };
99                 int status;
100                 while ((status = readdir(fd, &ent)) == 1) {
101                     if (ent.d_type == DT_DIR) {
102                         printf(" \033[3m%s\033[39;49m\n", ent.d_name);
103                     } else {
104                         printf(" %s\n", ent.d_name);
105                     }
106                 }
107
108                 if (status < 0)
109                     sh_printerr();
110
111                 close(fd);
112             }
113         } else if (streq(cmd, "cat")) {
114             int fd = open(argpart, 0);
115             if (fd < 0) {
116                 sh_printerr();
117             } else {
118                 int sz;
119                 while ((sz = read(fd, cat_buf, 1024)) > 0) {
120                     write(stdout, cat_buf, sz);
121                 }
122                 if (sz < 0) {
123                     sh_printerr();
124                 }
125                 close(fd);
126                 printf("\n");
127             }
128         } else {
129             printf("unknow command");
130         }
131     cont:
132         printf("\n");
133     }
134 }