Make sh able to execute from file
This commit is contained in:
parent
44cfef634b
commit
d7a9bdee22
@ -1,4 +1,5 @@
|
||||
#include <sys/fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
@ -47,11 +48,15 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
path = argv[1];
|
||||
printf("open file %s\n", path);
|
||||
|
||||
if ((fd = open(path, O_RDONLY, 0)) < 0) {
|
||||
perror(path);
|
||||
return -1;
|
||||
if (!strcmp(path, "-")) {
|
||||
fd = STDIN_FILENO;
|
||||
printf("Reading from stdin\n");
|
||||
} else {
|
||||
if ((fd = open(path, O_RDONLY, 0)) < 0) {
|
||||
perror(path);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
|
3
etc/test.sh
Executable file
3
etc/test.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo Something
|
38
sh/builtin.c
38
sh/builtin.c
@ -38,6 +38,42 @@ DEF_BUILTIN(clear) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEF_BUILTIN(echo) {
|
||||
for (int i = 1; i < cmd->argc; ++i) {
|
||||
printf("%s ", cmd->args[i]);
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEF_BUILTIN(into) {
|
||||
if (cmd->argc < 3) {
|
||||
printf("usage: into <filename> <command> ...\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("fork()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
close(STDIN_FILENO);
|
||||
int fd = open(cmd->args[1], O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
perror(cmd->args[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
exit(execve(cmd->args[2], (const char *const *) &cmd->args[2], NULL));
|
||||
} else {
|
||||
int st;
|
||||
waitpid(pid, &st);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: support usernames (getpwnam_r)
|
||||
DEF_BUILTIN(setid) {
|
||||
if (cmd->argc == 2) {
|
||||
@ -78,8 +114,10 @@ static struct sh_builtin __builtins[] = {
|
||||
DECL_BUILTIN(builtins),
|
||||
DECL_BUILTIN(cd),
|
||||
DECL_BUILTIN(clear),
|
||||
DECL_BUILTIN(echo),
|
||||
DECL_BUILTIN(exit),
|
||||
DECL_BUILTIN(setid),
|
||||
DECL_BUILTIN(into),
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
5
sh/cmd.c
5
sh/cmd.c
@ -104,11 +104,16 @@ static int cmd_exec(const struct cmd_exec *cmd) {
|
||||
|
||||
int eval(char *str) {
|
||||
struct cmd_exec cmd;
|
||||
char *p;
|
||||
|
||||
while (isspace(*str)) {
|
||||
++str;
|
||||
}
|
||||
|
||||
if ((p = strchr(str, '#'))) {
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
if (!*str) {
|
||||
return 0;
|
||||
}
|
||||
|
29
sh/sh.c
29
sh/sh.c
@ -73,9 +73,38 @@ static void display_prompt(void) {
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int fd = STDIN_FILENO;
|
||||
char linebuf[256];
|
||||
int res;
|
||||
|
||||
if (argc == 2) {
|
||||
fd = open(argv[1], O_RDONLY, 0);
|
||||
|
||||
if (fd < 0) {
|
||||
perror(argv[1]);
|
||||
return -1;
|
||||
}
|
||||
} else if (argc != 1) {
|
||||
printf("usage: sh [filename]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!isatty(fd)) {
|
||||
while (1) {
|
||||
if (gets_safe(fd, linebuf, sizeof(linebuf)) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
eval(linebuf);
|
||||
}
|
||||
|
||||
if (fd != STDIN_FILENO) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
update_prompt();
|
||||
display_prompt();
|
||||
|
Loading…
x
Reference in New Issue
Block a user