0003-implement-umask-builtin-on-unix.patch (2712B)
1 From 0f88ba02c7bbcb91b428bfb294831769e521a81b Mon Sep 17 00:00:00 2001 2 From: Michael Forney <mforney@mforney.org> 3 Date: Sun, 19 Apr 2026 14:11:15 -0700 4 Subject: [PATCH] implement umask builtin on unix 5 6 --- 7 exec.h | 2 +- 8 fns.h | 1 + 9 simple.c | 2 +- 10 unix.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 11 4 files changed, 49 insertions(+), 2 deletions(-) 12 13 diff --git a/exec.h b/exec.h 14 index 69b1004..ee8edab 100644 15 --- a/exec.h 16 +++ b/exec.h 17 @@ -77,7 +77,7 @@ extern void (*builtinfunc(char *name))(void); 18 void execcd(void), execwhatis(void), execeval(void), execexec(void); 19 int execforkexec(void); 20 void execexit(void), execshift(void); 21 -void execwait(void), execumask(void), execdot(void), execflag(void); 22 +void execwait(void), execdot(void), execflag(void); 23 void execfunc(var*), execcmds(io*, char*, var*, redir*); 24 void startfunc(var*, word*, var*, redir*); 25 26 diff --git a/fns.h b/fns.h 27 index 339f08b..1644d1e 100644 28 --- a/fns.h 29 +++ b/fns.h 30 @@ -45,6 +45,7 @@ int havewaitpid(int); 31 int idchr(int); 32 void inttoascii(char*, int); 33 void kinit(void); 34 +int mapfd(int); 35 int match(char*, char*, int); 36 char* makepath(char*, char*); 37 void panic(char*, int); 38 diff --git a/simple.c b/simple.c 39 index 362b77b..1a9d27d 100644 40 --- a/simple.c 41 +++ b/simple.c 42 @@ -287,7 +287,7 @@ execshift(void) 43 poplist(); 44 } 45 46 -static int 47 +int 48 mapfd(int fd) 49 { 50 redir *rp; 51 diff --git a/unix.c b/unix.c 52 index 05d883c..cbb2054 100644 53 --- a/unix.c 54 +++ b/unix.c 55 @@ -12,9 +12,12 @@ 56 #include <errno.h> 57 #include <fcntl.h> 58 #include <dirent.h> 59 +#include <limits.h> 60 +#include <sys/stat.h> 61 #include <sys/wait.h> 62 63 static void execfinit(void); 64 +static void execumask(void); 65 66 builtin Builtin[] = { 67 "cd", execcd, 68 @@ -24,6 +27,7 @@ builtin Builtin[] = { 69 "exit", execexit, 70 "shift", execshift, 71 "wait", execwait, 72 + "umask", execumask, 73 ".", execdot, 74 "flag", execflag, 75 "finit", execfinit, 76 @@ -81,6 +85,48 @@ execfinit(void) 77 start(rdfns, 2, runq->local, runq->redir); 78 } 79 80 +static int 81 +octal(char *s) 82 +{ 83 + int n = 0; 84 + 85 + while(n<INT_MAX/8 && '0'<=*s && *s<='7') 86 + n = n*8+*s++-'0'; 87 + return *s=='\0' ? n : -1; 88 +} 89 + 90 +static void 91 +execumask(void) 92 +{ 93 + int m; 94 + struct io *out; 95 + char *e; 96 + 97 + switch(count(runq->argv->words)){ 98 + case 2: 99 + m = octal(runq->argv->words->next->word); 100 + if(m>=0 && m<=07777) { 101 + umask(m); 102 + break; 103 + } 104 + /* fallthrough */ 105 + default: 106 + pfmt(err, "Usage: umask [umask]\n"); 107 + setstatus("umask usage"); 108 + poplist(); 109 + return; 110 + case 1: 111 + umask(m = umask(0)); 112 + out = openiofd(mapfd(1)); 113 + pfmt(out, "%o\n", m); 114 + flushio(out); 115 + free(closeiostr(out)); 116 + break; 117 + } 118 + setstatus(""); 119 + poplist(); 120 +} 121 + 122 static int 123 cmpenv(const void *aa, const void *ab) 124 { 125 -- 126 2.49.0 127