From: Alan Cox Date: Thu, 28 Feb 2019 21:36:24 +0000 (+0000) Subject: kernel: kiss char * goodbye as much as possible, also fix pipe open X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=670141ffef60fe51806d45a860d583eef1cad8a3;p=FUZIX.git kernel: kiss char * goodbye as much as possible, also fix pipe open Also fix the pipe open semantics for named pipes (I hope). --- diff --git a/Kernel/filesys.c b/Kernel/filesys.c index 043871eb..803c3c92 100644 --- a/Kernel/filesys.c +++ b/Kernel/filesys.c @@ -19,38 +19,48 @@ * calls as they want a parent and to create the new node. */ -char lastname[31]; -uint8_t n_open_fault; -static char *name, *nameend; +uint8_t lastname[31]; + +static uint8_t n_open_fault; +static uint8_t n_fault_type; +static uint8_t *name, *nameend; static uint8_t getcf(void) { - int16_t c; - c = ugetc(name); - if (c == -1 || name == nameend) { - if (name == nameend) - udata.u_error = ENAMETOOLONG; + if (name == nameend) { + udata.u_error = n_fault_type; n_open_fault = 1; return 0; } - return (uint8_t)c; + return (uint8_t)_ugetc(name); } -inoptr n_open(char *namep, inoptr *parent) +inoptr n_open(uint8_t *namep, inoptr *parent) { staticfast inoptr wd; /* the directory we are currently searching. */ staticfast inoptr ninode; inoptr temp; uint8_t c; - char *fp; + uint8_t *fp; + usize_t len; + + /* Check the user address and length. If it's shorter than 512 bytes this + is fine, but set nameeend accordingly. This allows us to use _ugetc + in the hot path which saves us a ton of cycles */ + len = valaddr(namep, 512); + if (len == 0) + return NULLINODE; name = namep; + nameend = namep + len; n_open_fault = 0; - nameend = namep + 512; /* For now our pathmax is 512 */ -#ifdef DEBUG - kprintf("kn_open(\"%s\")\n", name); -#endif + /* What error do we return if we hit nameend - are we overlong, or out + of memory space */ + if (len == 512) + n_fault_type = ENAMETOOLONG; + else + n_fault_type = EACCES; if(getcf() == '/') wd = udata.u_root; @@ -149,7 +159,7 @@ nodir: * zeroes. */ -inoptr srch_dir(inoptr wd, char *compname) +inoptr srch_dir(inoptr wd, uint8_t *compname) { int curentry; blkno_t curblock; @@ -297,7 +307,7 @@ bool emptydir(inoptr wd) do { udata.u_count = DIR_LEN; - udata.u_base =(unsigned char *)&curentry; + udata.u_base = (uint8_t *)&curentry; udata.u_sysio = true; readi(wd, 0); @@ -319,7 +329,7 @@ bool emptydir(inoptr wd) * or the user did not have write permission. */ -bool ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex) +bool ch_link(inoptr wd, uint8_t *oldname, uint8_t *newname, inoptr nindex) { struct direct curentry; int i; @@ -350,7 +360,7 @@ bool ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex) for(;;) { udata.u_count = DIR_LEN; - udata.u_base =(unsigned char *)&curentry; + udata.u_base =(uint8_t *)&curentry; udata.u_sysio = true; readi(wd, 0); @@ -401,8 +411,11 @@ bool ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex) /* Namecomp compares two strings to see if they are the same file name. * It stops at FILENAME_LEN chars or a null or a slash. It returns 0 for difference. + * + * TODO: This generates crap code on most compilers so we probably ought to + * turn it into platform asm code. */ -bool namecomp(char *n1, char *n2) // return true if n1 == n2 +bool namecomp(uint8_t *n1, uint8_t *n2) // return true if n1 == n2 { uint8_t n; // do we have enough variables called n? @@ -433,7 +446,7 @@ bool namecomp(char *n1, char *n2) // return true if n1 == n2 * it's cleaner ??? */ -inoptr newfile(inoptr pino, char *name) +inoptr newfile(inoptr pino, uint8_t *name) { regptr inoptr nindex; uint8_t j; @@ -473,7 +486,7 @@ inoptr newfile(inoptr pino, char *name) nindex->c_node.i_addr[j] = 0; } wr_inode(nindex); - if (!ch_link(pino, "", name, nindex)) { + if (!ch_link(pino, (uint8_t *)"", name, nindex)) { i_deref(nindex); /* ch_link sets udata.u_error */ goto nogood; @@ -813,7 +826,7 @@ void i_deref(regptr inoptr ino) panic(PANIC_INODE_FREED); if (mode == MODE_R(F_PIPE)) - wakeup((char *)ino); + wakeup((uint8_t *)ino); /* If the inode has no links and no refs, it must have its blocks freed. */ @@ -904,7 +917,7 @@ int f_trunc(regptr inoptr ino) for(j=17; j >= 0; --j) freeblk(dev, ino->c_node.i_addr[j], 0); - memset((char *)ino->c_node.i_addr, 0, sizeof(ino->c_node.i_addr)); + memset((uint8_t *)ino->c_node.i_addr, 0, sizeof(ino->c_node.i_addr)); ino->c_flags |= CDIRTY; ino->c_node.i_size = 0; @@ -1326,7 +1339,7 @@ void magic(inoptr ino) * FIXME: this could be more efficient if we remembered which directory offset * we found the node at lookup time */ -arg_t unlinki(inoptr ino, inoptr pino, char *fname) +arg_t unlinki(inoptr ino, inoptr pino, uint8_t *fname) { if (getmode(ino) == MODE_R(F_DIR)) { udata.u_error = EISDIR; @@ -1334,7 +1347,7 @@ arg_t unlinki(inoptr ino, inoptr pino, char *fname) } /* Remove the directory entry (ch_link checks perms) */ - if (!ch_link(pino, fname, "", NULLINODE)) + if (!ch_link(pino, fname, (uint8_t *)"", NULLINODE)) return -1; /* Decrease the link count of the inode */ diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 348a9c7d..0f74de4c 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -90,6 +90,7 @@ From UZI by Doug Braun and UZI280 by Stefan Nitschke. #define CPUTYPE_R2K 9 #define CPUTYPE_Z280 10 #define CPUTYPE_8080 11 +#define CPUTYPE_8085 12 /* Maximum UFTSIZE can be is 16, then you need to alter the O_CLOEXEC code */ @@ -313,7 +314,7 @@ typedef struct cinode { #define DIR_LEN 32 typedef struct direct { uint16_t d_ino; - char d_name[FILENAME_LEN]; + uint8_t d_name[FILENAME_LEN]; } direct; @@ -819,7 +820,7 @@ extern size_t strlcpy(char *, const char *, size_t); #define uputw(v, p) ((*(uint16_t*)(p) = (v)) && 0) #define uzero(a,b) (memset(a,0,b) && 0) #else -extern usize_t valaddr(const char *base, usize_t size); +extern usize_t valaddr(const uint8_t *base, usize_t size); extern int uget(const void *userspace_source, void *dest, usize_t count); extern int16_t ugetc(const void *userspace_source); extern uint16_t ugetw(const void *userspace_source); @@ -895,16 +896,16 @@ extern int no_ioctl(uint8_t minor, uarg_t a, char *b); /* filesys.c */ /* open file, "name" in user address space */ -extern char lastname[31]; -extern inoptr n_open(char *uname, inoptr *parent); +extern uint8_t lastname[31]; +extern inoptr n_open(uint8_t *uname, inoptr *parent); extern inoptr i_open(uint16_t dev, uint16_t ino); -extern inoptr srch_dir(inoptr wd, char *compname); +extern inoptr srch_dir(inoptr wd, uint8_t *compname); extern inoptr srch_mt(inoptr ino); extern bool emptydir(inoptr ino); -extern bool ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex); +extern bool ch_link(inoptr wd, uint8_t *oldname, uint8_t *newname, inoptr nindex); /* return true if n1 == n2 */ -extern bool namecomp(char *n1, char *n2); -extern inoptr newfile(inoptr pino, char *name); +extern bool namecomp(uint8_t *n1, uint8_t *n2); +extern inoptr newfile(inoptr pino, uint8_t *name); extern fsptr getdev(uint16_t dev); extern bool baddev(fsptr dev); extern uint16_t i_alloc(uint16_t devno); @@ -937,7 +938,7 @@ extern struct mount *fs_tab_get(uint16_t dev); /* returns true on failure, false on success */ extern bool fmount(uint16_t dev, inoptr ino, uint16_t flags); extern void magic(inoptr ino); -extern arg_t unlinki(inoptr ino, inoptr pino, char *fname); +extern arg_t unlinki(inoptr ino, inoptr pino, uint8_t *fname); /* inode.c */ extern void readi(inoptr ino, uint8_t flag); @@ -1015,10 +1016,9 @@ extern void swapin(ptptr p, uint16_t map); /* syscalls_fs.c, syscalls_proc.c, syscall_other.c etc */ extern void updoff(void); -extern int stcpy(inoptr ino, char *buf); +extern int stcpy(inoptr ino, uint8_t *buf); extern bool rargs (char **userspace_argv, struct s_argblk *argbuf); extern char **wargs(char *userspace_ptr, struct s_argblk *argbuf, int *cnt); -extern arg_t unlinki(inoptr ino, inoptr pino, char *fname); /* timer.c */ extern void rdtime(time_t *tloc); @@ -1068,6 +1068,10 @@ extern void __hard_ei(void); #define di __hard_di #define irqrestore __hard_irqrestore #define ei __hard_ei +#else +extern irqflags_t di(void); +extern void irqrestore(irqflags_t f); +extern void ei(void); #endif /* Will need a uptr_t eventually */ diff --git a/Kernel/syscall_fs.c b/Kernel/syscall_fs.c index 5e9d2e9b..48a9dbf1 100644 --- a/Kernel/syscall_fs.c +++ b/Kernel/syscall_fs.c @@ -97,8 +97,8 @@ arg_t _sync(void) char *path; char *buf; ********************************************/ -#define path (char *)udata.u_argn -#define buf (char *)udata.u_argn1 +#define path (uint8_t *)udata.u_argn +#define buf (uint8_t *)udata.u_argn1 arg_t _stat(void) { @@ -121,7 +121,7 @@ arg_t _stat(void) char *buf; ********************************************/ #define fd (int16_t)udata.u_argn -#define buf (char *)udata.u_argn1 +#define buf (uint8_t *)udata.u_argn1 arg_t _fstat(void) { @@ -138,7 +138,7 @@ arg_t _fstat(void) /* Utility for stat and fstat */ -int stcpy(inoptr ino, char *buf) +int stcpy(inoptr ino, uint8_t *buf) { static uint8_t zero[4]; /* Copying the structure a member at a time is too expensive. Instead we @@ -378,7 +378,7 @@ arg_t _pipe(void) unlink (path) Function 6 char *path; ********************************************/ -#define path (char *)udata.u_argn +#define path (uint8_t *)udata.u_argn arg_t _unlink(void) { @@ -412,7 +412,7 @@ char *buf; uint16_t nbytes; ********************************************/ #define d (int16_t)udata.u_argn -#define buf (char *)udata.u_argn1 +#define buf (uint8_t *)udata.u_argn1 #define nbytes (susize_t)udata.u_argn2 arg_t readwrite(uint8_t reading) @@ -458,7 +458,7 @@ char *buf; uint16_t nbytes; ********************************************/ #define d (int16_t)udata.u_argn -#define buf (char *)udata.u_argn1 +#define buf (uint8_t *)udata.u_argn1 #define nbytes udata.u_argn2 /* @@ -487,7 +487,7 @@ char *buf; uint16_t nbytes; ********************************************/ #define d (int16_t)udata.u_argn -#define buf (char *)udata.u_argn1 +#define buf (uint8_t *)udata.u_argn1 #define nbytes (susize_t)udata.u_argn2 arg_t _write(void) diff --git a/Kernel/syscall_fs2.c b/Kernel/syscall_fs2.c index 2ee0512e..f7b5a3df 100644 --- a/Kernel/syscall_fs2.c +++ b/Kernel/syscall_fs2.c @@ -24,7 +24,7 @@ static arg_t chdiroot_op(inoptr ino, inoptr * p) chdir (dir) Function 10 char *dir; ********************************************/ -#define dir (char *)udata.u_argn +#define dir (uint8_t *)udata.u_argn arg_t _chdir(void) { @@ -59,7 +59,7 @@ arg_t _fchdir(void) chroot (dir) Function 46 char *dir; ********************************************/ -#define dir (char *)udata.u_argn +#define dir (uint8_t *)udata.u_argn arg_t _chroot(void) { @@ -81,9 +81,9 @@ arg_t _chroot(void) int16_t mode; int16_t dev; ********************************************/ -#define name (char *)udata.u_argn -#define mode (int16_t)udata.u_argn1 -#define dev (int16_t)udata.u_argn2 +#define name (uint8_t *)udata.u_argn +#define mode (uint16_t)udata.u_argn1 +#define dev (uint16_t)udata.u_argn2 arg_t _mknod(void) { @@ -135,8 +135,8 @@ arg_t _mknod(void) char *path; int16_t mode; ********************************************/ -#define path (char *)udata.u_argn -#define mode (int16_t)udata.u_argn1 +#define path (uint8_t *)udata.u_argn +#define mode (uint16_t)udata.u_argn1 arg_t _access(void) { @@ -202,7 +202,7 @@ static arg_t chmod_op(inoptr ino) char *path; int16_t mode; ********************************************/ -#define path (char *)udata.u_argn +#define path (uint8_t *)udata.u_argn arg_t _chmod(void) { @@ -279,7 +279,7 @@ static int chown_op(inoptr ino) int owner; int group; ********************************************/ -#define path (char *)udata.u_argn +#define path (uint8_t *)udata.u_argn arg_t _chown(void) { @@ -323,8 +323,8 @@ arg_t _fchown(void) char *file; char *buf; ********************************************/ -#define file (char *)udata.u_argn -#define buf (char *)udata.u_argn1 +#define file (uint8_t *)udata.u_argn +#define buf (uint8_t *)udata.u_argn1 arg_t _utime(void) { @@ -427,7 +427,7 @@ arg_t _getfsys(void) udata.u_error = ENXIO; return (-1); } - return uput((char *) &m->m_fs, (char *) buf, sizeof(struct filesys)); + return uput((uint8_t *) &m->m_fs, (uint8_t *) buf, sizeof(struct filesys)); } #undef dev diff --git a/Kernel/syscall_fs3.c b/Kernel/syscall_fs3.c index d628b9d9..59411cec 100644 --- a/Kernel/syscall_fs3.c +++ b/Kernel/syscall_fs3.c @@ -10,7 +10,7 @@ char *name; int16_t flag; int16_t mode; ********************************************/ -#define name (char *)udata.u_argn +#define name (uint8_t *)udata.u_argn #define flag (uint16_t)udata.u_argn1 #define mode (uint16_t)udata.u_argn2 @@ -133,23 +133,31 @@ arg_t _open(void) i_unlock(ino); /* FIXME: ATIME ? */ -/* - * Sleep process if no writer or reader. - * FIXME: check for other of pair now we have proper counts - */ - if (getmode(ino) == MODE_R(F_PIPE) && of_tab[oftindex].o_refs == 1 - && !(flag & O_NDELAY)) - psleep(ino); + + if (getmode(ino) == MODE_R(F_PIPE)) { + if (of_tab[oftindex].o_refs == 1 + && !(flag & O_NDELAY)) { + psleep(ino); + if (chksigs()) { + udata.u_error = EINTR; + goto idrop; + } + } + if ((ino->c_writers == 0) && (flag & O_NDELAY)) { + udata.u_error = ENXIO; + goto idrop; + } + } /* From the moment of the psleep ino is invalid */ return (uindex); - idrop: +idrop: i_unlock(ino); /* Falls through and drops the reference count */ - cantopen: +cantopen: oft_deref(oftindex); /* This will call i_deref() */ - nooft: +nooft: udata.u_files[uindex] = NO_FILE; return (-1); } @@ -165,8 +173,8 @@ link (name1, name2) Function 5 char *name1; char *name2; ********************************************/ -#define name1 (char *)udata.u_argn -#define name2 (char *)udata.u_argn1 +#define name1 (uint8_t *)udata.u_argn +#define name2 (uint8_t *)udata.u_argn1 arg_t _link(void) { @@ -291,7 +299,7 @@ We pass a set of \0 terminated strings, don't bother with node name. Rest is up to the libc. ********************************************/ -#define buf (char *)udata.u_argn +#define buf (uint8_t *)udata.u_argn #define len (uint16_t)udata.u_argn1 arg_t _uname(void) diff --git a/Kernel/syscall_other.c b/Kernel/syscall_other.c index e7357794..884e29a8 100644 --- a/Kernel/syscall_other.c +++ b/Kernel/syscall_other.c @@ -21,8 +21,8 @@ a directory. Don't allow an object to be put inside itself! ********************************************/ -#define src (char *)udata.u_argn -#define dst (char *)udata.u_argn1 +#define src (uint8_t *)udata.u_argn +#define dst (uint8_t *)udata.u_argn1 arg_t _rename(void) { @@ -137,7 +137,7 @@ arg_t _rename(void) int16_t mode; ********************************************/ -#define name (char *)udata.u_argn +#define name (uint8_t *)udata.u_argn #define mode (int16_t)udata.u_argn1 arg_t _mkdir(void) @@ -210,7 +210,7 @@ cleanup: rmdir (path) Function 52 char *path; ********************************************/ -#define path (char *)udata.u_argn +#define path (uint8_t *)udata.u_argn arg_t _rmdir(void) { @@ -302,8 +302,8 @@ arg_t _rmdir(void) char *dir; int flags; ********************************************/ -#define spec (char *)udata.u_argn -#define dir (char *)udata.u_argn1 +#define spec (uint8_t *)udata.u_argn +#define dir (uint8_t *)udata.u_argn1 #define flags (int)udata.u_argn2 arg_t _mount(void) @@ -372,7 +372,7 @@ arg_t _mount(void) char *spec; ********************************************/ -#define spec (char *)udata.u_argn +#define spec (uint8_t *)udata.u_argn #define flags (uint16_t)udata.u_argn1 static int do_umount(uint16_t dev) @@ -481,7 +481,7 @@ usize_t size; uint16_t scale; ********************************************/ -#define samples (char *)udata.u_argn +#define samples (uint8_t *)udata.u_argn #define offset (usize_t)udata.u_argn1 #define size (usize_t)udata.u_argn2 #define scale (uint16_t)udata.u_argn3 @@ -526,7 +526,7 @@ char *ptr; ********************************************/ #define cmd (int16_t)udata.u_argn #define func (int16_t)udata.u_argn1 -#define ptr (char *)udata.u_argn2 +#define ptr (uint8_t *)udata.u_argn2 arg_t _uadmin(void) { diff --git a/Kernel/syscall_proc.c b/Kernel/syscall_proc.c index 2658f9be..25441767 100644 --- a/Kernel/syscall_proc.c +++ b/Kernel/syscall_proc.c @@ -200,7 +200,7 @@ arg_t _stime(void) times (buf) Function 42 ? char *buf; ********************************************/ -#define buf (char *)udata.u_argn +#define buf (uint8_t *)udata.u_argn arg_t _times(void) { @@ -296,7 +296,7 @@ arg_t _waitpid(void) int retval; uint8_t found; - if (statloc && !valaddr((char *) statloc, sizeof(int))) { + if (statloc && !valaddr((uint8_t *) statloc, sizeof(int))) { udata.u_error = EFAULT; return (-1); } @@ -489,7 +489,7 @@ arg_t _signal(void) if (sig != SIGKILL && sig != SIGSTOP) sb->s_ignored |= sigmask(sig); } else { - if (func != SIG_DFL && !valaddr((char *) func, 1)) { + if (func != SIG_DFL && !valaddr((uint8_t *) func, 1)) { udata.u_error = EFAULT; goto nogood; } @@ -516,8 +516,8 @@ sigdisp(sig, disp) Function 59 int16_t sig; int16_t disp; *******************************************/ -#define sig (int16_t)udata.u_argn -#define disp (int16_t)udata.u_argn1 +#define sig (uint16_t)udata.u_argn +#define disp (uint16_t)udata.u_argn1 /* Implement sighold/sigrelse */ arg_t _sigdisp(void) diff --git a/Kernel/usermem.c b/Kernel/usermem.c index 511fe4d8..70998f7d 100644 --- a/Kernel/usermem.c +++ b/Kernel/usermem.c @@ -14,13 +14,13 @@ #if !defined(CONFIG_FLAT) && !defined(CONFIG_VMMU) /* This checks to see if a user-supplied address is legitimate */ -usize_t valaddr(const char *base, usize_t size) +usize_t valaddr(const uint8_t *base, usize_t size) { - if (!base || base < (const char *)PROGBASE || base + size < base || - base > (const char *)(size_t)udata.u_top) + if (!base || base < (const uint8_t *)PROGBASE || base + size < base || + base > (const uint8_t *)(size_t)udata.u_top) size = 0; - else if (base + size > (const char *)(size_t)udata.u_top) - size = (char *)(size_t)udata.u_top - base; + else if (base + size > (const uint8_t *)(size_t)udata.u_top) + size = (uint8_t *)(size_t)udata.u_top - base; if (size == 0) udata.u_error = EFAULT; return size;