void
strrtrim(char* str);
-void*
+char*
strltrim_safe(char* str);
#endif /* __LUNAIX_STRING_H */
struct device
{
struct llist_header siblings;
+ struct llist_header children;
struct device* parent;
struct hstr name;
dev_t dev_id;
--- /dev/null
+#include <lunaix/fctrl.h>
+#include <lunaix/foptions.h>
+#include <lunaix/lunistd.h>
+#include <lunaix/proc.h>
+#include <lunaix/status.h>
+
+#include <klibc/string.h>
+#include <ulibc/stdio.h>
+
+char pwd[512];
+
+/*
+ Simple shell - (actually this is not even a shell)
+ It just to make the testing more easy.
+*/
+
+void
+parse_cmdline(char* line, char** cmd, char** arg_part)
+{
+ strrtrim(line);
+ line = strltrim_safe(line);
+ int l = 0;
+ char c = 0;
+ while ((c = line[l])) {
+ if (c == ' ') {
+ line[l++] = 0;
+ break;
+ }
+ l++;
+ }
+ *cmd = line;
+ *arg_part = strltrim_safe(line + l);
+}
+
+void
+sh_printerr()
+{
+ int errno = geterrno();
+ switch (errno) {
+ case ENOTDIR:
+ printf("Error: Not a directory\n");
+ break;
+ case ENOENT:
+ printf("Error: No such file or directory\n");
+ break;
+ case EINVAL:
+ printf("Error: Invalid parameter or operation\n");
+ break;
+ case ENOTSUP:
+ printf("Error: Not supported\n");
+ break;
+ case EROFS:
+ printf("Error: File system is read only\n");
+ break;
+ case ENOMEM:
+ printf("Error: Out of memory\n");
+ break;
+ default:
+ printf("Error: Fail to open (%d)\n", errno);
+ break;
+ }
+}
+
+void
+sh_main()
+{
+ char buf[512];
+ char *cmd, *argpart;
+
+ while (1) {
+ getcwd(pwd, 512);
+ printf("%s> ", pwd);
+ size_t sz = read(stdin, buf, 512);
+ if (sz < 0) {
+ printf("fail to read user input (%d)\n", geterrno());
+ return;
+ }
+ buf[sz - 1] = '\0';
+ parse_cmdline(buf, &cmd, &argpart);
+ if (streq(cmd, "cd")) {
+ if (chdir(argpart) < 0) {
+ sh_printerr();
+ }
+ } else if (streq(cmd, "ls")) {
+ int fd = open(argpart, 0);
+ if (fd < 0) {
+ sh_printerr();
+ } else {
+ struct dirent ent = { .d_offset = 0 };
+ int status;
+ while ((status = readdir(fd, &ent)) == 1) {
+ printf(" %s\n", ent.d_name);
+ }
+
+ if (status < 0)
+ sh_printerr();
+
+ close(fd);
+ }
+ } else {
+ printf("unknow command");
+ }
+ printf("\n");
+ }
+}
\ No newline at end of file
int
devfs_readdir(struct v_file* file, struct dir_context* dctx)
{
- struct device* dev = device_getbyoffset(file->inode->data, dctx->index);
+ struct device* holder = (struct device*)(file->inode->data);
+ struct device* dev =
+ device_getbyoffset(holder ? &holder->children : NULL, dctx->index);
if (!dev) {
return 0;
}
if (parent) {
assert((parent->dev_type & DEV_MSKIF) == DEV_IFCAT);
+ llist_append(&parent->children, &dev->siblings);
+ } else {
+ llist_append(&root_list, &dev->siblings);
}
size_t strlen =
dev->dev_type = type;
hstr_rehash(&dev->name, HSTR_FULL_HASH);
- llist_append(&root_list, &dev->siblings);
+ llist_init_head(&dev->children);
return dev;
}
panick("vfs: no root");
}
}
- i++;
+
+ if (path[0] == VFS_PATH_DELIM) {
+ i++;
+ }
}
assert(start);
volatile static inode_t ino = 0;
extern const struct v_inode_ops ramfs_inode_ops;
+extern const struct v_file_ops ramfs_file_ops;
int
ramfs_readdir(struct v_file* file, struct dir_context* dctx)
{
inode->id = ino++;
inode->ops = &ramfs_inode_ops;
- inode->default_fops = &default_file_ops;
+ inode->default_fops = &ramfs_file_ops;
}
int
default_inode_dirlookup,
.create = ramfs_create,
.open = default_inode_open,
- .rename = default_inode_rename };
\ No newline at end of file
+ .rename = default_inode_rename };
+
+const struct v_file_ops ramfs_file_ops = { .readdir = ramfs_readdir,
+ .close = default_file_close,
+ .read = default_file_read,
+ .write = default_file_write,
+ .seek = default_file_seek };
\ No newline at end of file
char name_str[VFS_NAME_MAXLEN];
struct hstr name = HSTR(name_str, 0);
int errno;
+
+ name_str[0] = 0;
if ((errno = vfs_walk_proc(path, fdir, &name, VFS_WALK_PARENT))) {
return errno;
}
// #define DEMO_SIGNAL
// #define DEMO_READDIR
// #define DEMO_IOTEST
-#define DEMO_INPUT_TEST
+// #define DEMO_INPUT_TEST
+#define DEMO_SIMPLE_SH
extern void
_pconsole_main();
extern void
input_test();
+extern void
+sh_main();
+
void __USER__
__proc0_usr()
{
_iotest_main();
#elif defined DEMO_INPUT_TEST
input_test();
+#elif defined DEMO_SIMPLE_SH
+ sh_main();
#else
_lxinit_main();
#endif
str[l + 1] = '\0';
}
-void*
+char*
strltrim_safe(char* str)
{
size_t l = 0;
char c = 0;
- while ((c = str[l++]) && WS_CHAR(c))
- ;
+ while ((c = str[l]) && WS_CHAR(c)) {
+ l++;
+ }
+
+ if (!l)
+ return str;
return strcpy(str, str + l);
}
\ No newline at end of file