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:
parent
2d97595147
commit
e4d0298d1b
|
@ -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.
|
||||
*
|
||||
|
@ -23,7 +23,16 @@
|
|||
#if __GNUC__ && POSIX
|
||||
#undef __MES_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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
@ -21,9 +21,29 @@
|
|||
#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)
|
||||
{
|
||||
|
|
|
@ -18,6 +18,13 @@
|
|||
* 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 ()
|
||||
{
|
||||
|
|
|
@ -31,3 +31,27 @@
|
|||
(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)))
|
||||
|
|
50
src/posix.c
50
src/posix.c
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue