1570af302Sopenharmony_ci#define _GNU_SOURCE
2570af302Sopenharmony_ci#include <fcntl.h>
3570af302Sopenharmony_ci#include <unistd.h>
4570af302Sopenharmony_ci#include <unsupported_api.h>
5570af302Sopenharmony_ci
6570af302Sopenharmony_ciint daemon(int nochdir, int noclose)
7570af302Sopenharmony_ci{
8570af302Sopenharmony_ci	UNSUPPORTED_API_VOID(LITEOS_A);
9570af302Sopenharmony_ci	if (!nochdir && chdir("/"))
10570af302Sopenharmony_ci		return -1;
11570af302Sopenharmony_ci	if (!noclose) {
12570af302Sopenharmony_ci		int fd, failed = 0;
13570af302Sopenharmony_ci		if ((fd = open("/dev/null", O_RDWR)) < 0) return -1;
14570af302Sopenharmony_ci		if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0)
15570af302Sopenharmony_ci			failed++;
16570af302Sopenharmony_ci		if (fd > 2) close(fd);
17570af302Sopenharmony_ci		if (failed) return -1;
18570af302Sopenharmony_ci	}
19570af302Sopenharmony_ci
20570af302Sopenharmony_ci	switch(fork()) {
21570af302Sopenharmony_ci	case 0: break;
22570af302Sopenharmony_ci	case -1: return -1;
23570af302Sopenharmony_ci	default: _exit(0);
24570af302Sopenharmony_ci	}
25570af302Sopenharmony_ci
26570af302Sopenharmony_ci	if (setsid() < 0) return -1;
27570af302Sopenharmony_ci
28570af302Sopenharmony_ci	switch(fork()) {
29570af302Sopenharmony_ci	case 0: break;
30570af302Sopenharmony_ci	case -1: return -1;
31570af302Sopenharmony_ci	default: _exit(0);
32570af302Sopenharmony_ci	}
33570af302Sopenharmony_ci
34570af302Sopenharmony_ci	return 0;
35570af302Sopenharmony_ci}
36