Renamed rfork(2) to sfork(2) to avoid compatibility issues.

sfork is much like rfork except sharing is default for everything.

Eventually, I'll make a rfork(3) wrapper function around sfork(2) to
provide compatibility to BSD programs.

I don't like Linux clone(2): that's some messy function.
This commit is contained in:
Jonas 'Sortie' Termansen 2012-04-04 00:29:25 +02:00
parent 2331a1a234
commit 05b29ce25a
5 changed files with 40 additions and 27 deletions

View File

@ -32,14 +32,6 @@
#include <sortix/seek.h> #include <sortix/seek.h>
#include <sortix/unistd.h> #include <sortix/unistd.h>
/* BSD compatibility: The problem with RFMEM is that isn't default to share, but
default to make a copy. However, Sortix rforks wants to make sharing default
and forking only happens if you ask for it. The Sortix RFFMEM extension
reverses this logic. */
#if defined(RFMEM) && !defined(_BSD_SOURCE) && !defined(_WANT_RFMEM)
#undef RFMEM
#endif
#define _SORTIX_ALWAYS_SBRK #define _SORTIX_ALWAYS_SBRK
__BEGIN_DECLS __BEGIN_DECLS
@ -190,7 +182,7 @@ size_t pwriteall(int fd, const void* buf, size_t count, off_t off);
size_t pwriteleast(int fd, const void* buf, size_t least, size_t max, off_t off); size_t pwriteleast(int fd, const void* buf, size_t least, size_t max, off_t off);
size_t readall(int fd, void* buf, size_t count); size_t readall(int fd, void* buf, size_t count);
size_t readleast(int fd, void* buf, size_t least, size_t max); size_t readleast(int fd, void* buf, size_t least, size_t max);
pid_t rfork(int flags); pid_t sfork(int flags);
int uptime(uintmax_t* usecssinceboot); int uptime(uintmax_t* usecssinceboot);
size_t writeall(int fd, const void* buf, size_t count); size_t writeall(int fd, const void* buf, size_t count);
size_t writeleast(int fd, const void* buf, size_t least, size_t max); size_t writeleast(int fd, const void* buf, size_t least, size_t max);

View File

@ -35,7 +35,7 @@ namespace Maxsi
DEFN_SYSCALL1_VOID(SysExit, SYSCALL_EXIT, int); DEFN_SYSCALL1_VOID(SysExit, SYSCALL_EXIT, int);
DEFN_SYSCALL3(int, SysExecVE, SYSCALL_EXEC, const char*, char* const*, char* const*); DEFN_SYSCALL3(int, SysExecVE, SYSCALL_EXEC, const char*, char* const*, char* const*);
DEFN_SYSCALL0(pid_t, SysFork, SYSCALL_FORK); DEFN_SYSCALL0(pid_t, SysFork, SYSCALL_FORK);
DEFN_SYSCALL1(pid_t, SysRFork, SYSCALL_RFORK, int); DEFN_SYSCALL1(pid_t, SysSFork, SYSCALL_SFORK, int);
DEFN_SYSCALL0(pid_t, SysGetPID, SYSCALL_GETPID); DEFN_SYSCALL0(pid_t, SysGetPID, SYSCALL_GETPID);
DEFN_SYSCALL0(pid_t, SysGetParentPID, SYSCALL_GETPPID); DEFN_SYSCALL0(pid_t, SysGetParentPID, SYSCALL_GETPPID);
DEFN_SYSCALL3(pid_t, SysWait, SYSCALL_WAIT, pid_t, int*, int); DEFN_SYSCALL3(pid_t, SysWait, SYSCALL_WAIT, pid_t, int*, int);
@ -76,9 +76,9 @@ namespace Maxsi
return SysFork(); return SysFork();
} }
extern "C" int rfork(int flags) extern "C" pid_t sfork(int flags)
{ {
return SysRFork(flags); return SysSFork(flags);
} }
DUAL_FUNCTION(pid_t, getpid, GetPID, ()) DUAL_FUNCTION(pid_t, getpid, GetPID, ())

View File

@ -74,7 +74,7 @@
#define SYSCALL_KERNELINFO 48 #define SYSCALL_KERNELINFO 48
#define SYSCALL_PREAD 49 #define SYSCALL_PREAD 49
#define SYSCALL_PWRITE 50 #define SYSCALL_PWRITE 50
#define SYSCALL_RFORK 51 #define SYSCALL_SFORK 51
#define SYSCALL_MAX_NUM 52 /* index of highest constant + 1 */ #define SYSCALL_MAX_NUM 52 /* index of highest constant + 1 */
#endif #endif

View File

@ -34,16 +34,37 @@ __BEGIN_DECLS
#define X_OK 1 /* Test for execute permission. */ #define X_OK 1 /* Test for execute permission. */
#define F_OK 0 /* Test for existence. */ #define F_OK 0 /* Test for existence. */
#define RFCLONE (1<<0) /* Creates child, otherwise affect current process. */ /* The sfork system call is much like the rfork system call found in Plan 9 and
#define RFPID (1<<1) /* Allocates new PID. */ BSD systems, however it works slightly differently and was renamed to avoid
#define RFFDG (1<<2) /* Fork file descriptor table. */ conflicts with existing programs. In particular, it never forks an item
#define RFMEM (1<<3) /* Shares address space. */ unless its bit is set, whereas rfork sometimes forks an item by default. If
#define RFFMEM (1<<4) /* Forks address space. */ you wish to fork certain items simply set the proper flags. Note that since
#define RFCWD (1<<5) /* Forks current directory pointer. */ flags may be added from time to time, you should use various compound flags
#define RFNS (1<<6) /* Forks namespace. */ defined below such as SFFORK and SFALL. It can be useful do combine these
compount flags with bitoperations, for instance "I want traditional fork,
except share the working dir pointer" is sfork(SFFORK & ~SFCWD). */
#define SFPROC (1<<0) /* Creates child, otherwise affect current process. */
#define SFPID (1<<1) /* Allocates new PID. */
#define SFFD (1<<2) /* Fork file descriptor table. */
#define SFMEM (1<<3) /* Forks address space. */
#define SFCWD (1<<4) /* Forks current directory pointer. */
#define SFROOT (1<<5) /* Forks root directory pointer. */
#define SFNAME (1<<6) /* Forks namespace. */
#define SFSIG (1<<7) /* Forks signal table. */
#define SFCSIG (1<<8) /* Child will have no pending signals, like fork(2). */
#define RFPROC (RFCLONE | RFPID | RFFMEM | RFCWD) /* Create new process. */ /* Provides traditional fork(2) behavior; use this instead of the above values
#define RFFORK (RFPROC | RFFDG) /* Traditional fork(2) behavior. */ if you want "as fork(2), but also fork foo", or "as fork(2), except bar". In
those cases it is better to sfork(SFFORK & ~SFFOO); or sfork(SFFORK | SFBAR);
as that would allow to add new flags to SFFORK if a new kernel feature is
added to the system that applications don't know about yet. */
#define SFFORK (SFPROC | SFPID | SFFD | SFMEM | SFCWD | SFROOT | SFCSIG)
/* This allows creating a process that is completely forked from the original
process, unlike SFFORK which does share a few things (such as the process
namespace). Note that there is a few unset high bits in this value, these
are reserved and must not be set. */
#define SFALL ((1<<20)-1)
__END_DECLS __END_DECLS

View File

@ -432,10 +432,10 @@ namespace Sortix
return SysExevVEStage2(state); return SysExevVEStage2(state);
} }
pid_t SysRFork(int flags) pid_t SysSFork(int flags)
{ {
// TODO: Properly support rfork(2). // TODO: Properly support sfork(2).
if ( flags != RFFORK ) { Error::Set(ENOSYS); return -1; } if ( flags != SFFORK ) { Error::Set(ENOSYS); return -1; }
// Prepare the state of the clone. // Prepare the state of the clone.
Syscall::SyscallRegs()->result = 0; Syscall::SyscallRegs()->result = 0;
@ -449,7 +449,7 @@ namespace Sortix
pid_t SysFork() pid_t SysFork()
{ {
return SysRFork(RFFORK); return SysSFork(SFFORK);
} }
pid_t SysGetPID() pid_t SysGetPID()
@ -755,7 +755,7 @@ namespace Sortix
{ {
Syscall::Register(SYSCALL_EXEC, (void*) SysExecVE); Syscall::Register(SYSCALL_EXEC, (void*) SysExecVE);
Syscall::Register(SYSCALL_FORK, (void*) SysFork); Syscall::Register(SYSCALL_FORK, (void*) SysFork);
Syscall::Register(SYSCALL_RFORK, (void*) SysRFork); Syscall::Register(SYSCALL_SFORK, (void*) SysSFork);
Syscall::Register(SYSCALL_GETPID, (void*) SysGetPID); Syscall::Register(SYSCALL_GETPID, (void*) SysGetPID);
Syscall::Register(SYSCALL_GETPPID, (void*) SysGetParentPID); Syscall::Register(SYSCALL_GETPPID, (void*) SysGetParentPID);
Syscall::Register(SYSCALL_EXIT, (void*) SysExit); Syscall::Register(SYSCALL_EXIT, (void*) SysExit);