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 };