fuzix: break out execve()
authorAlan Cox <alan@etchedpixels.co.uk>
Tue, 11 Nov 2014 11:53:09 +0000 (11:53 +0000)
committerAlan Cox <alan@etchedpixels.co.uk>
Tue, 11 Nov 2014 11:53:09 +0000 (11:53 +0000)
We need to split this into pieces and also allow some of it to be
cpu specific

13 files changed:
Kernel/Makefile
Kernel/platform-micropack/uzi.lnk
Kernel/platform-msx1/uzi.lnk
Kernel/platform-msx2/uzi.lnk
Kernel/platform-nc100/uzi.lnk
Kernel/platform-pcw8256/uzi.lnk
Kernel/platform-px4plus/uzi.lnk
Kernel/platform-trs80/uzi.lnk
Kernel/platform-z80pack-lite/uzi.lnk
Kernel/platform-z80pack/uzi.lnk
Kernel/platform-zx128/uzi.lnk
Kernel/syscall_exec.c [new file with mode: 0644]
Kernel/syscall_other.c

index 145ea38..9689a4a 100644 (file)
@@ -1,9 +1,9 @@
 TARGET_LIST = platform-nc100 platform-micropack platform-pcw8256 platform-socz80 platform-zx128 platform-trs80 platform-z80pack platform-z80pack-lite 
 
-#export TARGET= zx128
-#export CPU = z80
-export TARGET = 6809test
-export CPU = 6809
+export TARGET= msx1
+export CPU = z80
+#export TARGET = 6809test
+#export CPU = 6809
 #export TARGET = 6502test
 #export CPU = 6502
 export VERSION = "0.1"
@@ -73,7 +73,7 @@ CDSRCS = start.c
 C1SRCS =  version.c kdata.c filesys.c
 C1SRCS += inode.c syscall_fs.c process.c usermem.c timer.c
 C2SRCS =  devio.c syscall_proc.c
-C2SRCS += syscall_fs2.c syscall_other.c
+C2SRCS += syscall_fs2.c syscall_other.c syscall_exec.c
 C2SRCS += bank16k.c bank32k.c bankfixed.c single.c simple.c
 C2SRCS += tty.c devsys.c
 C2SRCS += mm.c swap.c
index f60fd67..5388962 100644 (file)
@@ -21,6 +21,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_fs2.rel
 syscall_proc.rel
index 1b01d6c..020641c 100644 (file)
@@ -24,6 +24,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_fs2.rel
 syscall_proc.rel
index d5c5a4f..c5c74c8 100644 (file)
@@ -24,6 +24,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_fs2.rel
 syscall_proc.rel
index 3f1a0b0..359b058 100644 (file)
@@ -19,6 +19,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_proc.rel
 syscall_fs2.rel
index fc57c9e..ad871b8 100644 (file)
@@ -22,6 +22,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_fs2.rel
 syscall_proc.rel
index ed8313a..3d08458 100644 (file)
@@ -24,6 +24,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_fs2.rel
 syscall_proc.rel
index a61ac50..6176ff6 100644 (file)
@@ -21,6 +21,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_fs2.rel
 syscall_proc.rel
index 4554f44..dd10bb5 100644 (file)
@@ -20,6 +20,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_proc.rel
 syscall_other.rel
index 4d7e312..37f7c20 100644 (file)
@@ -21,6 +21,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_fs2.rel
 syscall_proc.rel
index a56d60d..506980d 100644 (file)
@@ -22,6 +22,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+syscall_exec.rel
 syscall_fs.rel
 syscall_fs2.rel
 syscall_proc.rel
diff --git a/Kernel/syscall_exec.c b/Kernel/syscall_exec.c
new file mode 100644 (file)
index 0000000..b6e352a
--- /dev/null
@@ -0,0 +1,321 @@
+#include <kernel.h>
+#include <version.h>
+#include <kdata.h>
+#include <printf.h>
+#include <timer.h>
+
+
+/* User's execve() call. All other flavors are library routines. */
+/*******************************************
+execve (name, argv, envp)        Function 23
+char *name;
+char *argv[];
+char *envp[];
+********************************************/
+#define name (char *)udata.u_argn
+#define argv (char **)udata.u_argn1
+#define envp (char **)udata.u_argn2
+
+int16_t _execve(void)
+{
+       inoptr ino, emu_ino;
+       unsigned char *buf;
+       blkno_t blk;
+       char **nargv;           /* In user space */
+       char **nenvp;           /* In user space */
+       struct s_argblk *abuf, *ebuf;
+       int16_t (**sigp) ();
+       int argc;
+       uint16_t emu_size, emu_copy;
+       uint8_t *progptr, *emu_ptr, *emu_base;
+       int j;
+       uint16_t top = (uint16_t)ramtop;
+       uint8_t c;
+       uint16_t blocks;
+
+       kputs("execve\n");
+
+       if (!(ino = n_open(name, NULLINOPTR)))
+               return (-1);
+
+       kputs("Found it\n");
+       if (!((getperm(ino) & OTH_EX) &&
+             (ino->c_node.i_mode & F_REG) &&
+             (ino->c_node.i_mode & (OWN_EX | OTH_EX | GRP_EX)))) {
+               udata.u_error = EACCES;
+               goto nogood;
+       }
+
+       setftime(ino, A_TIME);
+
+       /* Read in the first block of the new program */
+       buf = bread(ino->c_dev, bmap(ino, 0, 1), 0);
+
+    /****************************************
+     * Get magic number into var magic
+     * C3    : executable file no C/D sep.
+     * 00FF  :     "        "  with C/D sep. (not supported in FUZIX)
+     * other : maybe shell script (nogood2)
+     ****************************************/
+       if ((*buf & 0xff) != EMAGIC) {
+               udata.u_error = ENOEXEC;
+               goto nogood2;
+       }
+       kputs("Magic\n");
+
+       /*
+        *      Executables might be CP/M or Fuzix (we don't support legacy
+        *      UZI binaries).
+        */
+       if (buf[3] == 'F' && buf[4] == 'Z' && buf[5] == 'X' && buf[6] == '1') {
+               top = buf[7] | ((unsigned int)buf[8] << 8);
+               if (top == 0)   /* Legacy 'all space' binary */
+                       top = (uint16_t)ramtop;
+               emu_ino = 0;    // no emulation, thanks
+       } else {
+#ifdef CONFIG_CPM_EMU
+               // open the emulator code on disk
+               emu_ino = kn_open(CPM_EMULATOR_FILENAME, NULLINOPTR);
+               if (!emu_ino) {
+                       kprintf("Cannot load emulator: %s\n",
+                               CPM_EMULATOR_FILENAME);
+                       udata.u_error = ENOEXEC;
+                       goto nogood2;
+               }
+               top = (uint16_t)ramtop;
+#else
+               emu_size;
+               emu_copy;
+               emu_ptr;
+               udata.u_error = ENOEXEC;
+               goto nogood2;
+#endif
+       }
+
+       /* Binary doesn't fit */
+       if (top < ino->c_node.i_size + 1024) {
+               udata.u_error = ENOMEM;
+               goto nogood2;
+       }
+
+       /* Gather the arguments, and put them in temporary buffers. */
+       abuf = (struct s_argblk *) tmpbuf();
+       /* Put environment in another buffer. */
+       ebuf = (struct s_argblk *) tmpbuf();
+
+       /* Read args and environment from process memory */
+       if (rargs(argv, abuf) || rargs(envp, ebuf))
+               goto nogood3;   /* SN */
+
+       /* This must be the last test as it makes changes if it works */
+       if (pagemap_realloc(top))
+               goto nogood3;
+
+       /* From this point on we are commmited to the exec() completing */
+       udata.u_top = top;
+
+       /* setuid, setgid if executable requires it */
+       if (ino->c_node.i_mode & SET_UID)
+               udata.u_euid = ino->c_node.i_uid;
+
+       if (ino->c_node.i_mode & SET_GID)
+               udata.u_egid = ino->c_node.i_gid;
+
+       /* We are definitely going to succeed with the exec,
+        * so we can start writing over the old program
+        */
+       uput(buf, PROGBASE, 512);       /* Move 1st Block to user bank */
+       brelse(buf);
+
+       c = ugetc(PROGBASE);
+       if (c != 0xC3)
+               kprintf("Botched uput\n");
+
+       /* At this point, we are committed to reading in and
+        * executing the program. */
+
+       for (j = 0; j < UFTSIZE; ++j) {
+               if (udata.u_cloexec & (1 << j))
+                       doclose(j);
+       }
+       udata.u_cloexec = 0;
+
+#ifdef CONFIG_CPM_EMU
+       // Load the CP/M emulator if it is required
+       if (emu_ino) {
+               emu_size = emu_ino->c_node.i_size;
+               // round up to nearest multiple of 256 bytes, fit it in below ramtop
+               emu_ptr =
+                   (char *) (udata.u_top - ((emu_size + 255) & 0xff00));
+               emu_base = emu_ptr;
+               blk = 0;
+
+               while (emu_size) {
+                       buf = bread(emu_ino->c_dev, bmap(emu_ino, blk, 1), 0);  // read block
+                       emu_copy = min(512, emu_size);
+                       uput(buf, emu_ptr, emu_copy);   // copy to userspace
+                       bufdiscard((bufptr) buf);
+                       brelse((bufptr) buf);   // release block
+                       // adjust pointers
+                       emu_ptr += emu_copy;
+                       emu_size -= emu_copy;
+                       blk++;
+               }
+               // close emulator file
+               i_deref(emu_ino);
+
+               /*
+                * zero out the remainder of memory between the top of the emulator and top
+                * of process memory
+                */
+
+               uzero(emu_ptr, top - emu_ptr);
+       } else
+#endif
+       {
+               emu_base = (uint8_t *)top;
+       }
+
+       /* emu_base now points at the byte after the last byte the program can occupy */
+
+       /*
+        *  Read in the rest of the program, block by block
+        *  We use bufdiscard so that we load the entire app through the
+        *  same buffer to avoid cycling our small cache on this. Indirect blocks
+        *  will still be cached. - Hat tip to Steve Hosgood's OMU for that trick
+        */
+       progptr = PROGBASE + 512;       // we copied the first block already
+
+       /* Compute this once otherwise each loop we must recalculate this
+          as the compiler isn't entitled to assume the loop didn't change it */
+       blocks = ino->c_node.i_size >> 9;
+
+       for (blk = 1; blk <= blocks; ++blk) {
+               buf = bread(ino->c_dev, bmap(ino, blk, 1), 0);
+               uput(buf, progptr, 512);
+               bufdiscard((bufptr) buf);
+               brelse((bufptr) buf);
+               progptr += 512;
+       }
+       i_deref(ino);
+       udata.u_break = (int) progptr;  //  Set initial break for program
+
+       // zero all remaining process memory above the last block loaded.
+       uzero(progptr, emu_base - progptr);
+
+       // Turn off caught signals
+       for (sigp = udata.u_sigvec; sigp < udata.u_sigvec + NSIGS; ++sigp)
+               *sigp = SIG_DFL;
+
+       // place the arguments, environment and stack at the top of userspace memory,
+
+       // Write back the arguments and the environment
+       nargv = wargs(((char *) emu_base - 2), abuf, &argc);
+       nenvp = wargs((char *) (nargv), ebuf, NULL);
+
+       // Fill in udata.u_name with Program invocation name
+       uget((void *) ugetw(nargv), udata.u_name, 8);
+       memcpy(udata.u_ptab->p_name, udata.u_name, 8);
+
+       brelse(abuf);
+       brelse(ebuf);
+
+       // Shove argc and the address of argv just below envp
+       uputw((uint16_t) nargv, nenvp - 1);
+       uputw((uint16_t) argc, nenvp - 2);
+
+       // Set stack pointer for the program
+       udata.u_isp = nenvp - 2;
+
+       // Start execution (never returns)
+#ifdef CONFIG_CPM_EMU
+       if (emu_ino)
+               doexec(emu_base);
+       else
+#endif
+               doexec(PROGBASE);
+
+       // tidy up in various failure modes:
+      nogood3:
+       brelse(abuf);
+       brelse(ebuf);
+#ifdef CONFIG_CPM_EMU
+       if (emu_ino)
+               i_deref(emu_ino);
+#endif
+      nogood2:
+       brelse(buf);
+      nogood:
+       i_deref(ino);
+       return (-1);
+}
+
+#undef name
+#undef argv
+#undef envp
+
+/* SN    TODO      max (1024) 512 bytes for argv
+               and max  512 bytes for environ
+*/
+
+bool rargs(char **userspace_argv, struct s_argblk * argbuf)
+{
+       char *ptr;              /* Address of base of arg strings in user space */
+       uint8_t c;
+       uint8_t *bufp;
+
+       argbuf->a_argc = 0;     /* Store argc in argbuf */
+       bufp = argbuf->a_buf;
+
+       while ((ptr = (char *) ugetw(userspace_argv++)) != NULL) {
+               ++(argbuf->a_argc);     /* Store argc in argbuf. */
+               do {
+                       *bufp++ = c = ugetc(ptr++);
+                       if (bufp > argbuf->a_buf + 500) {
+                               udata.u_error = E2BIG;
+                               return true;    // failed
+                       }
+               }
+               while (c);
+       }
+       argbuf->a_arglen = bufp - (uint8_t *)argbuf->a_buf;     /*Store total string size. */
+       return false;           // success
+}
+
+
+char **wargs(char *ptr, struct s_argblk *argbuf, int *cnt)     // ptr is in userspace
+{
+       char **argv;            /* Address of users argv[], just below ptr */
+       int argc, arglen;
+       char **argbase;
+       uint8_t *sptr;
+
+       sptr = argbuf->a_buf;
+
+       /* Move them into the users address space, at the very top */
+       ptr -= (arglen = argbuf->a_arglen);
+
+       if (arglen) {
+               uput(sptr, ptr, arglen);
+       }
+
+       /* Set argv to point below the argument strings */
+       argc = argbuf->a_argc;
+       argbase = argv = (char **) ptr - (argc + 1);
+
+       if (cnt) {
+               *cnt = argc;
+       }
+
+       /* Set each element of argv[] to point to its argument string */
+       while (argc--) {
+               uputw((uint16_t) ptr, argv++);
+               if (argc) {
+                       do
+                               ++ptr;
+                       while (*sptr++);
+               }
+       }
+       uputw(0, argv);         /*;;26Feb- Add Null Pointer to end of array */
+       return ((char **) argbase);
+}
index b14276a..4413385 100644 (file)
@@ -368,320 +368,6 @@ int16_t _umount(void)
 #undef spec
 
 
-/* User's execve() call. All other flavors are library routines. */
-/*******************************************
-execve (name, argv, envp)        Function 23
-char *name;
-char *argv[];
-char *envp[];
-********************************************/
-#define name (char *)udata.u_argn
-#define argv (char **)udata.u_argn1
-#define envp (char **)udata.u_argn2
-
-int16_t _execve(void)
-{
-       inoptr ino, emu_ino;
-       unsigned char *buf;
-       blkno_t blk;
-       char **nargv;           /* In user space */
-       char **nenvp;           /* In user space */
-       struct s_argblk *abuf, *ebuf;
-       int16_t (**sigp) ();
-       int argc;
-       uint16_t emu_size, emu_copy;
-       uint8_t *progptr, *emu_ptr, *emu_base;
-       int j;
-       uint16_t top = (uint16_t)ramtop;
-       uint8_t c;
-       uint16_t blocks;
-
-       kputs("execve\n");
-
-       if (!(ino = n_open(name, NULLINOPTR)))
-               return (-1);
-
-       kputs("Found it\n");
-       if (!((getperm(ino) & OTH_EX) &&
-             (ino->c_node.i_mode & F_REG) &&
-             (ino->c_node.i_mode & (OWN_EX | OTH_EX | GRP_EX)))) {
-               udata.u_error = EACCES;
-               goto nogood;
-       }
-
-       setftime(ino, A_TIME);
-
-       /* Read in the first block of the new program */
-       buf = bread(ino->c_dev, bmap(ino, 0, 1), 0);
-
-    /****************************************
-     * Get magic number into var magic
-     * C3    : executable file no C/D sep.
-     * 00FF  :     "        "  with C/D sep. (not supported in FUZIX)
-     * other : maybe shell script (nogood2)
-     ****************************************/
-       if ((*buf & 0xff) != EMAGIC) {
-               udata.u_error = ENOEXEC;
-               goto nogood2;
-       }
-       kputs("Magic\n");
-
-       /*
-        *      Executables might be CP/M or Fuzix (we don't support legacy
-        *      UZI binaries).
-        */
-       if (buf[3] == 'F' && buf[4] == 'Z' && buf[5] == 'X' && buf[6] == '1') {
-               top = buf[7] | ((unsigned int)buf[8] << 8);
-               if (top == 0)   /* Legacy 'all space' binary */
-                       top = (uint16_t)ramtop;
-               emu_ino = 0;    // no emulation, thanks
-       } else {
-#ifdef CONFIG_CPM_EMU
-               // open the emulator code on disk
-               emu_ino = kn_open(CPM_EMULATOR_FILENAME, NULLINOPTR);
-               if (!emu_ino) {
-                       kprintf("Cannot load emulator: %s\n",
-                               CPM_EMULATOR_FILENAME);
-                       udata.u_error = ENOEXEC;
-                       goto nogood2;
-               }
-               top = (uint16_t)ramtop;
-#else
-               emu_size;
-               emu_copy;
-               emu_ptr;
-               udata.u_error = ENOEXEC;
-               goto nogood2;
-#endif
-       }
-
-       /* Binary doesn't fit */
-       if (top < ino->c_node.i_size + 1024) {
-               udata.u_error = ENOMEM;
-               goto nogood2;
-       }
-
-       /* Gather the arguments, and put them in temporary buffers. */
-       abuf = (struct s_argblk *) tmpbuf();
-       /* Put environment in another buffer. */
-       ebuf = (struct s_argblk *) tmpbuf();
-
-       /* Read args and environment from process memory */
-       if (rargs(argv, abuf) || rargs(envp, ebuf))
-               goto nogood3;   /* SN */
-
-       /* This must be the last test as it makes changes if it works */
-       if (pagemap_realloc(top))
-               goto nogood3;
-
-       /* From this point on we are commmited to the exec() completing */
-       udata.u_top = top;
-
-       /* setuid, setgid if executable requires it */
-       if (ino->c_node.i_mode & SET_UID)
-               udata.u_euid = ino->c_node.i_uid;
-
-       if (ino->c_node.i_mode & SET_GID)
-               udata.u_egid = ino->c_node.i_gid;
-
-       /* We are definitely going to succeed with the exec,
-        * so we can start writing over the old program
-        */
-       uput(buf, PROGBASE, 512);       /* Move 1st Block to user bank */
-       brelse(buf);
-
-       c = ugetc(PROGBASE);
-       if (c != 0xC3)
-               kprintf("Botched uput\n");
-
-       /* At this point, we are committed to reading in and
-        * executing the program. */
-
-       for (j = 0; j < UFTSIZE; ++j) {
-               if (udata.u_cloexec & (1 << j))
-                       doclose(j);
-       }
-       udata.u_cloexec = 0;
-
-#ifdef CONFIG_CPM_EMU
-       // Load the CP/M emulator if it is required
-       if (emu_ino) {
-               emu_size = emu_ino->c_node.i_size;
-               // round up to nearest multiple of 256 bytes, fit it in below ramtop
-               emu_ptr =
-                   (char *) (udata.u_top - ((emu_size + 255) & 0xff00));
-               emu_base = emu_ptr;
-               blk = 0;
-
-               while (emu_size) {
-                       buf = bread(emu_ino->c_dev, bmap(emu_ino, blk, 1), 0);  // read block
-                       emu_copy = min(512, emu_size);
-                       uput(buf, emu_ptr, emu_copy);   // copy to userspace
-                       bufdiscard((bufptr) buf);
-                       brelse((bufptr) buf);   // release block
-                       // adjust pointers
-                       emu_ptr += emu_copy;
-                       emu_size -= emu_copy;
-                       blk++;
-               }
-               // close emulator file
-               i_deref(emu_ino);
-
-               /*
-                * zero out the remainder of memory between the top of the emulator and top
-                * of process memory
-                */
-
-               uzero(emu_ptr, top - emu_ptr);
-       } else
-#endif
-       {
-               emu_base = (uint8_t *)top;
-       }
-
-       /* emu_base now points at the byte after the last byte the program can occupy */
-
-       /*
-        *  Read in the rest of the program, block by block
-        *  We use bufdiscard so that we load the entire app through the
-        *  same buffer to avoid cycling our small cache on this. Indirect blocks
-        *  will still be cached. - Hat tip to Steve Hosgood's OMU for that trick
-        */
-       progptr = PROGBASE + 512;       // we copied the first block already
-
-       /* Compute this once otherwise each loop we must recalculate this
-          as the compiler isn't entitled to assume the loop didn't change it */
-       blocks = ino->c_node.i_size >> 9;
-
-       for (blk = 1; blk <= blocks; ++blk) {
-               buf = bread(ino->c_dev, bmap(ino, blk, 1), 0);
-               uput(buf, progptr, 512);
-               bufdiscard((bufptr) buf);
-               brelse((bufptr) buf);
-               progptr += 512;
-       }
-       i_deref(ino);
-       udata.u_break = (int) progptr;  //  Set initial break for program
-
-       // zero all remaining process memory above the last block loaded.
-       uzero(progptr, emu_base - progptr);
-
-       // Turn off caught signals
-       for (sigp = udata.u_sigvec; sigp < udata.u_sigvec + NSIGS; ++sigp)
-               *sigp = SIG_DFL;
-
-       // place the arguments, environment and stack at the top of userspace memory,
-
-       // Write back the arguments and the environment
-       nargv = wargs(((char *) emu_base - 2), abuf, &argc);
-       nenvp = wargs((char *) (nargv), ebuf, NULL);
-
-       // Fill in udata.u_name with Program invocation name
-       uget((void *) ugetw(nargv), udata.u_name, 8);
-       memcpy(udata.u_ptab->p_name, udata.u_name, 8);
-
-       brelse(abuf);
-       brelse(ebuf);
-
-       // Shove argc and the address of argv just below envp
-       uputw((uint16_t) nargv, nenvp - 1);
-       uputw((uint16_t) argc, nenvp - 2);
-
-       // Set stack pointer for the program
-       udata.u_isp = nenvp - 2;
-
-       // Start execution (never returns)
-#ifdef CONFIG_CPM_EMU
-       if (emu_ino)
-               doexec(emu_base);
-       else
-#endif
-               doexec(PROGBASE);
-
-       // tidy up in various failure modes:
-      nogood3:
-       brelse(abuf);
-       brelse(ebuf);
-#ifdef CONFIG_CPM_EMU
-       if (emu_ino)
-               i_deref(emu_ino);
-#endif
-      nogood2:
-       brelse(buf);
-      nogood:
-       i_deref(ino);
-       return (-1);
-}
-
-#undef name
-#undef argv
-#undef envp
-
-/* SN    TODO      max (1024) 512 bytes for argv
-               and max  512 bytes for environ
-*/
-
-bool rargs(char **userspace_argv, struct s_argblk * argbuf)
-{
-       char *ptr;              /* Address of base of arg strings in user space */
-       uint8_t c;
-       uint8_t *bufp;
-
-       argbuf->a_argc = 0;     /* Store argc in argbuf */
-       bufp = argbuf->a_buf;
-
-       while ((ptr = (char *) ugetw(userspace_argv++)) != NULL) {
-               ++(argbuf->a_argc);     /* Store argc in argbuf. */
-               do {
-                       *bufp++ = c = ugetc(ptr++);
-                       if (bufp > argbuf->a_buf + 500) {
-                               udata.u_error = E2BIG;
-                               return true;    // failed
-                       }
-               }
-               while (c);
-       }
-       argbuf->a_arglen = bufp - (uint8_t *)argbuf->a_buf;     /*Store total string size. */
-       return false;           // success
-}
-
-
-char **wargs(char *ptr, struct s_argblk *argbuf, int *cnt)     // ptr is in userspace
-{
-       char **argv;            /* Address of users argv[], just below ptr */
-       int argc, arglen;
-       char **argbase;
-       uint8_t *sptr;
-
-       sptr = argbuf->a_buf;
-
-       /* Move them into the users address space, at the very top */
-       ptr -= (arglen = argbuf->a_arglen);
-
-       if (arglen) {
-               uput(sptr, ptr, arglen);
-       }
-
-       /* Set argv to point below the argument strings */
-       argc = argbuf->a_argc;
-       argbase = argv = (char **) ptr - (argc + 1);
-
-       if (cnt) {
-               *cnt = argc;
-       }
-
-       /* Set each element of argv[] to point to its argument string */
-       while (argc--) {
-               uputw((uint16_t) ptr, argv++);
-               if (argc) {
-                       do
-                               ++ptr;
-                       while (*sptr++);
-               }
-       }
-       uputw(0, argv);         /*;;26Feb- Add Null Pointer to end of array */
-       return ((char **) argbase);
-}
 
 /*******************************************
 profil (samples, size, offset, scale) Function 56