Browse Source

More shoddy shell stuff

K. Lange 5 years ago
parent
commit
9b4a1174b6
3 changed files with 78 additions and 4 deletions
  1. 8 2
      Makefile
  2. 65 2
      apps/sh.c
  3. 5 0
      apps/test.sh

+ 8 - 2
Makefile

@@ -34,12 +34,14 @@ LC=base/lib/libc.so
 APPS=$(patsubst apps/%.c,%,$(wildcard apps/*.c))
 APPS_X=$(foreach app,$(APPS),base/bin/$(app))
 APPS_Y=$(foreach app,$(filter-out init,$(APPS)),.make/$(app).mak)
+APPS_SH=$(patsubst apps/%.sh,%.sh,$(wildcard apps/*.sh))
+APPS_SH_X=$(foreach app,$(APPS_SH),base/bin/$(app))
 
 LIBS=$(patsubst lib/%.c,%,$(wildcard lib/*.c))
 LIBS_X=$(foreach lib,$(LIBS),base/lib/libtoaru_$(lib).so)
 LIBS_Y=$(foreach lib,$(LIBS),.make/$(lib).lmak)
 
-RAMDISK_FILES= ${APPS_X} ${LIBS_X} base/lib/ld.so base/lib/libm.so
+RAMDISK_FILES= ${APPS_X} ${APPS_SH_X} ${LIBS_X} base/lib/ld.so base/lib/libm.so
 
 all: image.iso
 
@@ -168,6 +170,10 @@ ifeq (,$(findstring clean,$(MAKECMDGOALS)))
 -include ${APPS_Y}
 endif
 
+base/bin/%.sh: apps/%.sh
+	cp $< $@
+	chmod +x $@
+
 # Ramdisk
 
 util/devtable: ${RAMDISK_FILES} $(shell find base) util/update-devtable.py
@@ -228,7 +234,7 @@ boot/boot.o: boot/boot.s
 clean:
 	rm -f base/lib/*.so
 	rm -f base/lib/libc.a
-	rm -f ${APPS_X}
+	rm -f ${APPS_X} ${APPS_SH_X}
 	rm -f libc/*.o libc/*/*.o
 	rm -f image.iso
 	rm -f fatbase/ramdisk.img

+ 65 - 2
apps/sh.c

@@ -1219,7 +1219,7 @@ uint32_t shell_cmd_if(int argc, char * argv[]) {
 	}
 
 	tcsetpgrp(STDIN_FILENO, getpid());
-	return 1;
+	return 0;
 }
 
 uint32_t shell_cmd_while(int argc, char * argv[]) {
@@ -1272,12 +1272,75 @@ uint32_t shell_cmd_while(int argc, char * argv[]) {
 	return 127;
 }
 
+uint32_t shell_cmd_export_cmd(int argc, char * argv[]) {
+
+	if (argc < 3) {
+		fprintf(stderr, "%s: syntax error: not enough arguments\n", argv[0]);
+		return 1;
+	}
+
+	int pipe_fds[2];
+	pipe(pipe_fds);
+	pid_t child_pid = fork();
+	if (!child_pid) {
+		dup2(pipe_fds[1], STDOUT_FILENO);
+		close(pipe_fds[0]);
+		run_cmd(&argv[2]);
+	}
+
+	close(pipe_fds[1]);
+
+	tcsetpgrp(STDIN_FILENO, child_pid);
+	char buf[1024];
+	size_t accum = 0;
+
+	do {
+		int r = read(pipe_fds[0], buf+accum, 1023-accum);
+
+		if (r == 0) break;
+		if (r < 0) {
+			return -r;
+		}
+
+		accum += r;
+	} while (accum < 1023);
+
+	tcsetpgrp(STDIN_FILENO, getpid());
+
+	buf[accum] = '\0';
+
+	if (accum && buf[accum-1] == '\n') {
+		buf[accum-1] = '\0';
+	}
+
+	setenv(argv[1], buf, 1);
+	return 0;
+}
+
+uint32_t shell_cmd_empty(int argc, char * argv[]) {
+
+	for (int i = 1; i < argc; i++) {
+		if (argv[i] && *argv[i]) return 1;
+	}
+
+	return 0;
+}
+
+uint32_t shell_cmd_return(int argc, char * argv[]) {
+	if (argc < 2) return 0;
+
+	return atoi(argv[1]);
+}
+
 void install_commands() {
 	shell_install_command("cd",      shell_cmd_cd, "change directory");
 	shell_install_command("exit",    shell_cmd_exit, "exit the shell");
-	shell_install_command("export",  shell_cmd_export, "set environment variables");
+	shell_install_command("export",  shell_cmd_export, "set environment variables: export VAR=value");
 	shell_install_command("help",    shell_cmd_help, "display this help text");
 	shell_install_command("history", shell_cmd_history, "list command history");
 	shell_install_command("if",      shell_cmd_if, "if ... then ... [else ...]");
 	shell_install_command("while",   shell_cmd_while, "while ... do ...");
+	shell_install_command("empty?",  shell_cmd_empty, "empty? args...");
+	shell_install_command("return",  shell_cmd_return, "return status code");
+	shell_install_command("export-cmd",   shell_cmd_export_cmd, "set variable to result of command: export-cmd VAR command...");
 }

+ 5 - 0
apps/test.sh

@@ -0,0 +1,5 @@
+#!/bin/sh
+export-cmd UNAME uname
+export-cmd DATE date
+echo "This is a test shell script."
+echo "This is $UNAME and it is $DATE"