summaryrefslogtreecommitdiffhomepage
path: root/src/cmds/ntux_cmd_spawn.c
blob: b4d8c688a3e761cea464883c286aa16b9cd04041 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/***********************************************************/
/*  ntux: native translation und extension                 */
/*  Copyright (C) 2016--2021  SysDeer Technologies, LLC    */
/*  Released under GPLv2 and GPLv3; see COPYING.NTUX.      */
/***********************************************************/

#include <psxabi/sys_sysapi.h>
#include <psxabi/sys_errno.h>

#include <ntux/ntux.h>
#include "ntux_driver_impl.h"
#include "ntux_nolibc_impl.h"
#include "ntux_errinfo_impl.h"

int ntux_cmd_spawn(const struct ntux_driver_ctx * dctx)
{
	int32_t		status;
	pid_t		pid;
	const char **	argv;
	const char **	envp;
	unsigned char * program;

	/* init */
	ntux_driver_set_ectx(
		dctx,0,
		dctx->cctx->sargv[0]);

	argv    = (const char **)dctx->cctx->sargv;
	envp    = (const char **)dctx->cctx->senvp;
	program = (unsigned char *)dctx->cctx->sargv[0];

	/* spawn */
	pid = __sys_vfork();

	/* failed? */
	if (pid < 0)
		if (ntux_errno_set(dctx,pid))
			return NTUX_SYSTEM_ERROR(dctx);

	/* child */
	if (pid == 0)
		if ((status = __sys_execve(program,argv,envp)))
			if (ntux_errno_set(dctx,status))
				if (NTUX_SYSTEM_ERROR(dctx))
					__sys_exit(0);

	/* parent */
	struct ntux_driver_ctx_impl * ictx = ntux_get_driver_ictx(dctx);

	__sys_wait4(
		pid,
		&ictx->cctx.status,
		0,0);

	return 0;
}