Skip to content

Commit fb476df

Browse files
brooniet-8ch
authored andcommitted
tools/nolibc: Provide vfork()
To allow testing of vfork() support in the arm64 basic-gcs test provide an implementation for nolibc, using the vfork() syscall if one is available and otherwise clone3(). We implement in terms of clone3() since the order of the arguments for clone() varies between architectures. As for fork() SPARC returns the parent PID rather than 0 in the child for vfork() so needs custom handling. Signed-off-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Thomas Weißschuh <[email protected]>
1 parent 8c11625 commit fb476df

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

tools/include/nolibc/arch-sparc.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,20 @@ pid_t sys_fork(void)
188188
}
189189
#define sys_fork sys_fork
190190

191+
static __attribute__((unused))
192+
pid_t sys_vfork(void)
193+
{
194+
pid_t parent, ret;
195+
196+
parent = getpid();
197+
ret = my_syscall0(__NR_vfork);
198+
199+
/* The syscall returns the parent pid in the child instead of 0 */
200+
if (ret == parent)
201+
return 0;
202+
else
203+
return ret;
204+
}
205+
#define sys_vfork sys_vfork
206+
191207
#endif /* _NOLIBC_ARCH_SPARC_H */

tools/include/nolibc/sys.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/time.h>
2323
#include <linux/auxvec.h>
2424
#include <linux/fcntl.h> /* for O_* and AT_* */
25+
#include <linux/sched.h> /* for clone_args */
2526
#include <linux/stat.h> /* for statx() */
2627

2728
#include "errno.h"
@@ -340,6 +341,34 @@ pid_t fork(void)
340341
return __sysret(sys_fork());
341342
}
342343

344+
#ifndef sys_vfork
345+
static __attribute__((unused))
346+
pid_t sys_vfork(void)
347+
{
348+
#if defined(__NR_vfork)
349+
return my_syscall0(__NR_vfork);
350+
#elif defined(__NR_clone3)
351+
/*
352+
* clone() could be used but has different argument orders per
353+
* architecture.
354+
*/
355+
struct clone_args args = {
356+
.flags = CLONE_VM | CLONE_VFORK,
357+
.exit_signal = SIGCHLD,
358+
};
359+
360+
return my_syscall2(__NR_clone3, &args, sizeof(args));
361+
#else
362+
return __nolibc_enosys(__func__);
363+
#endif
364+
}
365+
#endif
366+
367+
static __attribute__((unused))
368+
pid_t vfork(void)
369+
{
370+
return __sysret(sys_vfork());
371+
}
343372

344373
/*
345374
* int fsync(int fd);

0 commit comments

Comments
 (0)