core: Support fork, waitpid, execve.

* 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.
This commit is contained in:
Jan Nieuwenhuizen 2018-05-24 19:54:42 +02:00
parent 2d97595147
commit e4d0298d1b
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
8 changed files with 188 additions and 11 deletions

View file

@ -1,6 +1,6 @@
/* -*-comment-start: "//";comment-end:""-*- /* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software * 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. * This file is part of Mes.
* *
@ -23,7 +23,16 @@
#if __GNUC__ && POSIX #if __GNUC__ && POSIX
#undef __MES_SYS_WAIT_H #undef __MES_SYS_WAIT_H
#include_next <sys/wait.h> #include_next <sys/wait.h>
#endif // (__GNUC__ && POSIX) #else // !(__GNUC__ && POSIX)
#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 #endif // __MES_SYS_WAIT_H

View file

@ -1,6 +1,6 @@
/* -*-comment-start: "//";comment-end:""-*- /* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software * 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. * This file is part of Mes.
* *
@ -49,7 +49,9 @@ typedef long ssize_t;
int access (char const *s, int mode); int access (char const *s, int mode);
int close (int fd); int close (int fd);
int execve (char const *file, char *const argv[], char *const env[]);
int execvp (char const *file, char *const argv[]); int execvp (char const *file, char *const argv[]);
int fork ();
char *getcwd (char *buf, size_t size); char *getcwd (char *buf, size_t size);
int isatty (int fd); int isatty (int fd);
off_t lseek (int fd, off_t offset, int whence); off_t lseek (int fd, off_t offset, int whence);

View file

@ -444,4 +444,10 @@ isatty (int fd)
return ioctl (fd, TCGETS, 0) & 0xf0; return ioctl (fd, TCGETS, 0) & 0xf0;
} }
int
wait (int *status_ptr)
{
return waitpid (-1, status_ptr, 0);
}
#endif //!POSIX #endif //!POSIX

View file

@ -1,6 +1,6 @@
/* -*-comment-start: "//";comment-end:""-*- /* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software * 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. * This file is part of Mes.
* *
@ -21,9 +21,29 @@
#include <stdio.h> #include <stdio.h>
#include <mlibc.h> #include <mlibc.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#if !POSIX #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 int
read (int fd, void* buf, size_t n) read (int fd, void* buf, size_t n)
{ {
@ -77,6 +97,52 @@ open (char const *s, int flags, ...)
#endif #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 int
chmod (char const *s, int mode) chmod (char const *s, int mode)
{ {

View file

@ -18,6 +18,13 @@
* along with Mes. If not, see <http://www.gnu.org/licenses/>. * along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/ */
void
fork ()
{
asm ("mov____$i32,%eax SYS_fork");
asm ("int____$0x80");
}
void void
read () read ()
{ {
@ -40,6 +47,28 @@ open ()
asm ("int____$0x80"); 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 void
chmod () chmod ()
{ {

View file

@ -31,3 +31,27 @@
(if (and ext (if (and ext
(string-suffix? ext base)) (string-drop-right base (string-length ext)) (string-suffix? ext base)) (string-drop-right base (string-length ext))
base))) 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)))

View file

@ -19,6 +19,7 @@
*/ */
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
@ -139,11 +140,9 @@ write_byte (SCM x) ///((arity . n))
char string_to_cstring_buf[1024]; char string_to_cstring_buf[1024];
char const* char const*
string_to_cstring (SCM s) string_to_cstring_ (SCM s, char *buf)
{ {
//static char buf[1024]; char *p = buf;
//char *p = buf;
char *p = string_to_cstring_buf;
s = STRING(s); s = STRING(s);
while (s != cell_nil) while (s != cell_nil)
{ {
@ -151,8 +150,13 @@ string_to_cstring (SCM s)
s = cdr (s); s = cdr (s);
} }
*p = 0; *p = 0;
//return buf; return buf;
return string_to_cstring_buf; }
char const*
string_to_cstring (SCM s)
{
return string_to_cstring_ (s, string_to_cstring_buf);
} }
SCM SCM
@ -256,3 +260,37 @@ isatty_p (SCM port)
{ {
return isatty (VALUE (port)) ? cell_t : cell_f; 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));
}

View file

@ -215,11 +215,14 @@ DEFINE movzwl_0x8(%ebp),%eax 0fb745
DEFINE movzwl_0x8(%ebp),%eax 0fb745 DEFINE movzwl_0x8(%ebp),%eax 0fb745
DEFINE SYS_exit 01000000 DEFINE SYS_exit 01000000
DEFINE SYS_fork 02000000
DEFINE SYS_read 03000000 DEFINE SYS_read 03000000
DEFINE SYS_write 04000000 DEFINE SYS_write 04000000
DEFINE SYS_open 05000000 DEFINE SYS_open 05000000
DEFINE SYS_close 06000000 DEFINE SYS_close 06000000
DEFINE SYS_waitpid 07000000
DEFINE SYS_unlink 0a000000 DEFINE SYS_unlink 0a000000
DEFINE SYS_execve 0b000000
DEFINE SYS_chmod 0f000000 DEFINE SYS_chmod 0f000000
DEFINE SYS_lseek 13000000 DEFINE SYS_lseek 13000000
DEFINE SYS_access 21000000 DEFINE SYS_access 21000000