-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathinit.c
More file actions
105 lines (80 loc) · 1.81 KB
/
init.c
File metadata and controls
105 lines (80 loc) · 1.81 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <sys/file.h>
#include <sys/fpath.h>
#include <sys/creds.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <config.h>
#include <util.h>
#include <main.h>
ERRTAG("init");
static void check_pid_one(void)
{
if(sys_getpid() != 1)
fail("not running as pid 1", NULL, 0);
}
static int open_something(void)
{
int fd;
if((fd = sys_open("/dev/null", O_RDWR)) >= 0)
return fd;
if((fd = sys_open("/", O_PATH)) >= 0)
return fd;
return -ENOENT;
}
static int dup_to_std_012(int fd)
{
if((fd < 1) && (sys_dup2(fd, STDOUT) < 0))
return -1;
if((fd < 2) && (sys_dup2(fd, STDERR) < 0))
return -1;
if(fd > 2 && (sys_close(fd) < 0))
return -1;
return 0;
}
static void setup_std_fds(void)
{
int fd, ret;
if(sys_fcntl(STDERR, F_GETFD) >= 0)
return;
if((fd = open_something()) < 0)
_exit(0xFE);
if((ret = dup_to_std_012(fd)) < 0)
_exit(0xFD);
}
static void mount(char* dir, char* fstype, int flags)
{
int ret;
struct stat st;
if((ret = sys_stat(dir, &st)) < 0)
return;
if((st.mode & S_IFMT) != S_IFDIR)
return;
if((ret = sys_mount("none", dir, fstype, flags, NULL)) >= 0)
return;
if(ret == -EBUSY)
return;
fail("mount", dir, ret);
}
static void mount_basic_filesystems(void)
{
mount("/sys", "sysfs", MS_NOSUID | MS_NOEXEC | MS_NODEV);
mount("/run", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV);
mount("/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV);
mount("/dev", "devtmpfs", MS_NOSUID | MS_NOEXEC);
}
static noreturn void invoke_next_stage(int argc, char** argv)
{
char* path = BASE_ETC "/boot/sysinit";
char* base = basename(path);
char** envp = argv + argc + 1;
argv[0] = base;
int ret = sys_execve(path, argv, envp);
fail(NULL, path, ret);
}
int main(int argc, char** argv)
{
check_pid_one();
setup_std_fds();
mount_basic_filesystems();
invoke_next_stage(argc, argv);
}