-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathsvhub_load.c
More file actions
134 lines (104 loc) · 2.04 KB
/
svhub_load.c
File metadata and controls
134 lines (104 loc) · 2.04 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/dents.h>
#include <string.h>
#include <format.h>
#include "common.h"
#include "svhub.h"
static void addfile(char* base, int blen)
{
struct proc* rc;
if((rc = find_by_name(base))) {
rc->flags &= ~P_STALE;
return;
}
if(!(rc = grab_proc_slot()))
return report("cannot create proc", NULL, 0);
memset(rc, 0, sizeof(*rc));
memcpy(rc->name, base, blen);
}
static void tryfile(int at, char* base)
{
int blen = strlen(base);
struct stat st;
if(sys_fstatat(at, base, &st, 0))
return;
if((st.mode & S_IFMT) != S_IFREG)
return;
if(!(st.mode & 0111))
return;
if(blen > NAMELEN - 1)
return;
addfile(base, blen);
}
int load_dir_ents(void)
{
char* dir = INITDIR;
int fd, ret;
int len = 4096;
char* buf = origbrk;
void* new = sys_brk(buf + len);
if((ret = brk_error(buf, new)) < 0)
return ret;
if((fd = sys_open(dir, O_RDONLY | O_DIRECTORY)) < 0) {
report("open", dir, fd);
return fd;
}
while((ret = sys_getdents(fd, buf, len)) > 0) {
char* ptr = buf;
char* end = buf + ret;
while(ptr < end) {
struct dirent* de = (struct dirent*) ptr;
if(!de->reclen)
break;
ptr += de->reclen;
if(dotddot(de->name))
continue;
switch(de->type) {
case DT_UNKNOWN:
case DT_REG:
case DT_LNK: break;
default: continue;
}
tryfile(fd, de->name);
}
} if(ret < 0) {
report("getdents", dir, ret);
}
sys_close(fd);
sys_brk(origbrk);
return ret;
}
static void mark_stale(struct proc* rc)
{
rc->flags |= P_STALE;
}
static void unmark_stale(struct proc* rc)
{
rc->flags &= ~P_STALE;
}
static void disable_stale(struct proc* rc)
{
if(!(rc->flags & P_STALE))
return;
if(rc->pid <= 0)
free_proc_slot(rc);
else
rc->flags |= P_DISABLED;
}
static void foreach_rec(void (*func)(struct proc* rc))
{
struct proc* rc;
for(rc = firstrec(); rc; rc = nextrec(rc))
func(rc);
}
int reload_procs(void)
{
foreach_rec(mark_stale);
int ret = load_dir_ents();
if(ret >= 0)
foreach_rec(disable_stale);
else
foreach_rec(unmark_stale);
return ret;
}