fiss

Friedel's Initialization and Service Supervision
Log | Files | Refs | LICENSE

builtins.c (1396B)


      1 #include <errno.h>
      2 #include <fmt.h>
      3 #include <stdio.h>
      4 #include <string.h>
      5 #include <unistd.h>
      6 
      7 #define MAXENV 256
      8 
      9 
     10 extern char* envp[];
     11 extern int   envc;
     12 
     13 int envset(char* s) {
     14 	char* l;
     15 
     16 	if (!(l = strchr(s, '='))) return -1;
     17 
     18 	for (int i = 0; i < envc && envp[i]; i++)
     19 		if (strncmp(envp[i], s, l - s) == 0) {
     20 			envp[i] = s;
     21 			return 0;
     22 		}
     23 
     24 	if (envc < MAXENV) {
     25 		envp[envc++] = s;
     26 		envp[envc]   = 0;
     27 		return 0;
     28 	}
     29 	return -1;
     30 }
     31 
     32 
     33 int chdir_builtin(int argc, char** argv) {
     34 	if (argc != 2) {
     35 		fprint(1, "usage: %s <path>\n", argv[0]);
     36 		return 1;
     37 	}
     38 
     39 	if (chdir(argv[1]) == -1) {
     40 		fprint(1, "%s: unable to change dir to '%s': %s\n", argv[0], argv[1], strerror(errno));
     41 		return 1;
     42 	}
     43 	return 0;
     44 }
     45 
     46 int export_builtin(int argc, char** argv) {
     47 	if (argc == 1) {
     48 		for (int i = 0; i < envc; i++)
     49 			print("%s\n", envp[i]);
     50 		return 0;
     51 	}
     52 
     53 	for (int i = 1; i < argc; i++) {
     54 		if (envset(argv[i]) == -1)
     55 			return 1;
     56 	}
     57 	return 0;
     58 }
     59 
     60 int execute(FILE*);
     61 
     62 int source_builtin(int argc, char** argv) {
     63 	FILE* f;
     64 	if (argc != 2) {
     65 		fprint(1, "source <file>\n");
     66 		return 1;
     67 	}
     68 	THROW_NULL(f = fopen(argv[1], "r"), "unable to open %s", 1, argv[1]);
     69 	return execute(f);
     70 }
     71 
     72 const struct builtin {
     73 	const char* name;
     74 	int (*func)(int argv, char** argc);
     75 } builtins[] = {
     76 	{ "cd", chdir_builtin },
     77 	{ "export", export_builtin },
     78 	{ ".", source_builtin },
     79 	{ "source", source_builtin },
     80 	{ 0 }
     81 };