kernel: kiss char * goodbye as much as possible, also fix pipe open
authorAlan Cox <alan@linux.intel.com>
Thu, 28 Feb 2019 21:36:24 +0000 (21:36 +0000)
committerAlan Cox <alan@linux.intel.com>
Thu, 28 Feb 2019 21:36:24 +0000 (21:36 +0000)
Also fix the pipe open semantics for named pipes (I hope).

Kernel/filesys.c
Kernel/include/kernel.h
Kernel/syscall_fs.c
Kernel/syscall_fs2.c
Kernel/syscall_fs3.c
Kernel/syscall_other.c
Kernel/syscall_proc.c
Kernel/usermem.c

index 043871e..803c3c9 100644 (file)
  * 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 */
index 348a9c7..0f74de4 100644 (file)
@@ -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 */
index 5e9d2e9..48a9dbf 100644 (file)
@@ -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)
index 2ee0512..f7b5a3d 100644 (file)
@@ -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
index d628b9d..59411ce 100644 (file)
@@ -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)
index e735779..884e29a 100644 (file)
@@ -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)
 {
index 2658f9b..2544176 100644 (file)
@@ -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)
index 511fe4d..70998f7 100644 (file)
 #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;