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