1570af302Sopenharmony_ci#define _GNU_SOURCE
2570af302Sopenharmony_ci#include <unistd.h>
3570af302Sopenharmony_ci#include <signal.h>
4570af302Sopenharmony_ci#include "syscall.h"
5570af302Sopenharmony_ci#include "pthread_impl.h"
6570af302Sopenharmony_ci#ifndef __LITEOS__
7570af302Sopenharmony_ci#include "proc_xid_impl.h"
8570af302Sopenharmony_ci#endif
9570af302Sopenharmony_ci
10570af302Sopenharmony_cihidden pid_t __vfork(void)
11570af302Sopenharmony_ci{
12570af302Sopenharmony_ci	/* vfork syscall cannot be made from C code */
13570af302Sopenharmony_ci#ifdef SYS_fork
14570af302Sopenharmony_ci	return syscall(SYS_fork);
15570af302Sopenharmony_ci#else
16570af302Sopenharmony_ci	return syscall(SYS_clone, SIGCHLD, 0);
17570af302Sopenharmony_ci#endif
18570af302Sopenharmony_ci}
19570af302Sopenharmony_ci
20570af302Sopenharmony_cipid_t vfork(void)
21570af302Sopenharmony_ci{
22570af302Sopenharmony_ci	pthread_t self = __pthread_self();
23570af302Sopenharmony_ci	pid_t parent_pid = self->pid;
24570af302Sopenharmony_ci	self->pid = 0;
25570af302Sopenharmony_ci#ifdef __LITEOS__
26570af302Sopenharmony_ci	pid_t ret = __vfork();
27570af302Sopenharmony_ci	if (ret != 0) {
28570af302Sopenharmony_ci		self->pid = parent_pid;
29570af302Sopenharmony_ci	} else {
30570af302Sopenharmony_ci		self->proc_tid = -1;
31570af302Sopenharmony_ci	}
32570af302Sopenharmony_ci#else
33570af302Sopenharmony_ci	int parent_by_vfork = self->by_vfork;
34570af302Sopenharmony_ci	self->by_vfork = 1;
35570af302Sopenharmony_ci	pid_t ret = __vfork();
36570af302Sopenharmony_ci	if (ret != 0) {
37570af302Sopenharmony_ci		self->pid = parent_pid;
38570af302Sopenharmony_ci		self->by_vfork = parent_by_vfork;
39570af302Sopenharmony_ci	} else {
40570af302Sopenharmony_ci		self->proc_tid = -1;
41570af302Sopenharmony_ci		__clear_proc_pid();
42570af302Sopenharmony_ci	}
43570af302Sopenharmony_ci#endif
44570af302Sopenharmony_ci	return ret;
45570af302Sopenharmony_ci}
46