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:""-*-
|
/* -*-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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)))
|
||||||
|
|
50
src/posix.c
50
src/posix.c
|
@ -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));
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue