core: Support fork, waitpid, execve.
authorJan Nieuwenhuizen <janneke@gnu.org>
Thu, 24 May 2018 17:54:42 +0000 (19:54 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Thu, 24 May 2018 17:54:42 +0000 (19:54 +0200)
* stage0/x86.M1 (SYS_fork, SYS_waitpid, SYS_execve): New define.
* lib/linux-gcc.c (fork, waitpid, execve): New function.
* lib/linux-mes.c (fork, waitpid, execve): New function.
* lib/libc.c (wait): New function.
* include/unistd.h (fork, execve): Declare.
* include/sys/wait.h (waitpid, wait): Declare.
* module/mes/posix.mes (search-path, execlp, system*, waitpid): New function.
* src/posix.c (primitive_fork, execl): New function.

include/sys/wait.h
include/unistd.h
lib/libc.c
lib/linux-gcc.c
lib/linux-mes.c
module/mes/posix.mes
src/posix.c
stage0/x86.M1

index f90c419dbb8cc029a30c031c4126c25b8cb910a3..37bb299cd2e819bf158e46511909bc5f6c441482 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-comment-start: "//";comment-end:""-*-
  * Mes --- Maxwell Equations of Software
- * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+ * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  *
  * This file is part of Mes.
  *
 #if __GNUC__ && POSIX
 #undef __MES_SYS_WAIT_H
 #include_next <sys/wait.h>
-#endif // (__GNUC__ && POSIX)
+#else // !(__GNUC__ && POSIX)
 
-#endif // __MES_SYS_WAIT_H
+#ifndef __MES_PID_T
+#define __MES_PID_T
+typedef int pid_t;
+#endif
+
+pid_t waitpid (pid_t pid, int *status_ptr, int options);
+pid_t wait (int *status_ptr);
 
+#endif // !(__GNUC__ && POSIX)
+
+#endif // __MES_SYS_WAIT_H
index 1c4086ada331d1865f22ba69306b9790ba3798ad..dc11ec78187c462abf4fc2782ce76058c1fccd8f 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-comment-start: "//";comment-end:""-*-
  * Mes --- Maxwell Equations of Software
- * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+ * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  *
  * This file is part of Mes.
  *
@@ -49,7 +49,9 @@ typedef long ssize_t;
 
 int access (char const *s, int mode);
 int close (int fd);
+int execve (char const *file, char *const argv[], char *const env[]);
 int execvp (char const *file, char *const argv[]);
+int fork ();
 char *getcwd (char *buf, size_t size);
 int isatty (int fd);
 off_t lseek (int fd, off_t offset, int whence);
index 7f0bf1c12c2aaad088e06a2b24fa26a6a200124d..639395657406f956febb519d652d9326ceba1d41 100644 (file)
@@ -444,4 +444,10 @@ isatty (int fd)
   return ioctl (fd, TCGETS, 0) & 0xf0;
 }
 
+int
+wait (int *status_ptr)
+{
+  return waitpid  (-1, status_ptr, 0);
+}
+
 #endif //!POSIX
index 4f357b10f4b31d134974fa56ac3d8c90d2ebd4ce..3dfbf6230c2dac415ef1fd66f946aec1b2b73ae3 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-comment-start: "//";comment-end:""-*-
  * Mes --- Maxwell Equations of Software
- * Copyright © 2016,2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+ * Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
  *
  * This file is part of Mes.
  *
 #include <stdio.h>
 #include <mlibc.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
 
 #if !POSIX
 
+int
+fork ()
+{
+#if !__TINYC__
+  int r;
+  //syscall (SYS_fork, fd));
+  asm (
+       "mov    $0x02,%%eax\n\t"
+       "int    $0x80\n\t"
+       "mov    %%eax,%0\n\t"
+       : "=r" (r)
+       : //no inputs
+       : "eax"
+       );
+  return r;
+#endif
+}
+
 int
 read (int fd, void* buf, size_t n)
 {
@@ -77,6 +97,52 @@ open (char const *s, int flags, ...)
 #endif
 }
 
+pid_t
+waitpid (pid_t pid, int *status_ptr, int options)
+{
+#if !__TINYC__
+  int r;
+  //syscall (SYS_execve, file_name, argv, env));
+  asm (
+       "mov    %1,%%ebx\n\t"
+       "mov    %2,%%ecx\n\t"
+       "mov    %3,%%edx\n\t"
+
+       "mov    $0x07,%%eax\n\t"
+       "int    $0x80\n\t"
+
+       "mov    %%eax,%0\n\t"
+       : "=r" (r)
+       : "" (pid), "" (status_ptr), "" (options)
+       : "eax", "ebx", "ecx", "edx"
+       );
+  return r;
+#endif
+}
+
+int
+execve (char const* file_name, char *const argv[], char *const env[])
+{
+#if !__TINYC__
+  int r;
+  //syscall (SYS_execve, file_name, argv, env));
+  asm (
+       "mov    %1,%%ebx\n\t"
+       "mov    %2,%%ecx\n\t"
+       "mov    %3,%%edx\n\t"
+
+       "mov    $0x0b,%%eax\n\t"
+       "int    $0x80\n\t"
+
+       "mov    %%eax,%0\n\t"
+       : "=r" (r)
+       : "" (file_name), "" (argv), "" (env)
+       : "eax", "ebx", "ecx", "edx"
+       );
+  return r;
+#endif
+}
+
 int
 chmod (char const *s, int mode)
 {
index 75dee3a9bada284373e3a856bf7605cbb08d616b..f525381eee1af06325bc0699426e34543568492e 100644 (file)
  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+void
+fork ()
+{
+  asm ("mov____$i32,%eax SYS_fork");
+  asm ("int____$0x80");
+}
+
 void
 read ()
 {
@@ -40,6 +47,28 @@ open ()
   asm ("int____$0x80");
 }
 
+void
+waitpid ()
+{
+  asm ("mov____0x8(%ebp),%ebx !8");
+  asm ("mov____0x8(%ebp),%ecx !12");
+  asm ("mov____0x8(%ebp),%edx !16");
+
+  asm ("mov____$i32,%eax SYS_waitpid");
+  asm ("int____$0x80");
+}
+
+void
+execve ()
+{
+  asm ("mov____0x8(%ebp),%ebx !8");
+  asm ("mov____0x8(%ebp),%ecx !12");
+  asm ("mov____0x8(%ebp),%edx !16");
+
+  asm ("mov____$i32,%eax SYS_execve");
+  asm ("int____$0x80");
+}
+
 void
 chmod ()
 {
index 1eec487a98f85b7c6b318d9982edaaefd1adc737..5c039a60e3641388ebab995cb84234739df75074 100644 (file)
     (if (and ext
              (string-suffix? ext base)) (string-drop-right base (string-length ext))
              base)))
+
+(define (search-path path file-name)
+  (if (access? file-name R_OK) file-name
+      (let loop ((path path))
+        (and (pair? path)
+             (let ((f (string-append (car path) "/" file-name)))
+               (if (access? f R_OK) f
+                   (loop (cdr path))))))))
+
+(define (execlp file-name args)
+  (let ((executable (if (string-index file-name #\/) file-name
+                        (search-path (string-split (getenv "PATH") #\:) file-name))))
+    (execl executable args)))
+
+(define (system* file-name . args)
+  (let ((pid (primitive-fork)))
+    (cond ((zero? pid) (apply execlp file-name (list args)))
+          ((= -1 pid) (error "fork failed:" file-name))
+          (else (let ((pid+status (waitpid 0)))
+                  (cdr pid+status))))))
+
+(define (waitpid pid . options)
+  (let ((options (if (null? options) 0 (car options))))
+    (core:waitpid pid options)))
index 2d483c9ab32a9108c265047ae906b7afdc055594..41772f6037c5c54400b42283f2d41701cc573dd0 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <fcntl.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -139,11 +140,9 @@ write_byte (SCM x) ///((arity . n))
 
 char string_to_cstring_buf[1024];
 char const*
-string_to_cstring (SCM s)
+string_to_cstring_ (SCM s, char *buf)
 {
-  //static char buf[1024];
-  //char *p = buf;
-  char *p = string_to_cstring_buf;
+  char *p = buf;
   s = STRING(s);
   while (s != cell_nil)
     {
@@ -151,8 +150,13 @@ string_to_cstring (SCM s)
       s = cdr (s);
     }
   *p = 0;
-  //return buf;
-  return string_to_cstring_buf;
+  return buf;
+}
+
+char const*
+string_to_cstring (SCM s)
+{
+  return string_to_cstring_ (s, string_to_cstring_buf);
 }
 
 SCM
@@ -256,3 +260,37 @@ isatty_p (SCM port)
 {
   return isatty (VALUE (port)) ? cell_t : cell_f;
 }
+
+SCM
+primitive_fork ()
+{
+  return MAKE_NUMBER (fork ());
+}
+
+SCM
+execl_ (SCM file_name, SCM args) ///((name . "execl"))
+{
+  char *c_argv[10];
+  int i = 0;
+  int n = 0;
+  c_argv[i++] = string_to_cstring_ (file_name, string_to_cstring_buf+n);
+  n += length__ (STRING (file_name)) + 1;
+  while (args != cell_nil)
+    {
+      assert (TYPE (CAR (args)) == TSTRING);
+      assert (i < 20);
+      c_argv[i++] = string_to_cstring_ (CAR (args), string_to_cstring_buf+n);
+      n += length__ (STRING (CAR (args))) + 1;
+      args = CDR (args);
+    }
+  c_argv[i] = 0;
+  return MAKE_NUMBER (execve (c_argv[0], c_argv, g_environment));
+}
+
+SCM
+waitpid_ (SCM pid, SCM options)
+{
+  int status;
+  int child = waitpid (VALUE (pid), &status, VALUE (options));
+  return cons (MAKE_NUMBER (child), MAKE_NUMBER (status));
+}
index 268f3277c421a133d8e03758ecb820109c07dbb4..3c1e0f6fb8cb2474ce67cfa5dd3f500c0f02bf1b 100644 (file)
@@ -215,11 +215,14 @@ DEFINE movzwl_0x8(%ebp),%eax 0fb745
 DEFINE movzwl_0x8(%ebp),%eax 0fb745
 
 DEFINE SYS_exit   01000000
+DEFINE SYS_fork   02000000
 DEFINE SYS_read   03000000
 DEFINE SYS_write  04000000
 DEFINE SYS_open   05000000
 DEFINE SYS_close  06000000
+DEFINE SYS_waitpid 07000000
 DEFINE SYS_unlink 0a000000
+DEFINE SYS_execve 0b000000
 DEFINE SYS_chmod  0f000000
 DEFINE SYS_lseek  13000000
 DEFINE SYS_access 21000000