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
|
/* bootlog.c */
/* diet -Os gcc -o bootlog bootlog.c -Wall -W */
#include <unistd.h>
#include <alloca.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h> /* rename */
#include <sys/wait.h>
#include "../ninitfeatures.h"
#define BRKINCR 1024
static int xx_write(int fd, void *buf, size_t len);
static int do_io(void *buf, int len);
static int mk_backup();
static char *root, *last, *end;
static char *flag_rename, *name;
static int flagstderr, flagstdout, m;
int fd = -1;
static void *setbrk(ssize_t incr) {
void *x = sbrk(incr);
if ((void *)-1 == x) return x;
if (root == 0) root = last = x;
end = x + incr;
return 0;
}
static void flush_root() {
if (mk_backup()) return;
if (fd < 0) fd = open(name, O_WRONLY | m, 0644);
if (fd < 0 || root==0) return;
xx_write(fd, root, last-root);
last = root;
setbrk((ssize_t)BRKINCR - (end-root));
}
static void loop(unsigned long len) {
int r;
if (flag_rename) {
char *d, *s = name;
d = flag_rename = alloca(str_len(name) + 5);
while (*s) *d++ = *s++;
d[0] = '~';
d[1] = 0;
}
while (len) {
if (last >= end) flush_root();
if (last >= end && setbrk(BRKINCR)) break;
r = do_io(last, end - last);
if (r==0) break;
if (r<0) continue;
if ((unsigned long)r > len) r = len;
last += r;
len -= r;
}
if (last >= end || len==0) {
char tmp[1024];
while (do_io(tmp,sizeof(tmp)));
}
mk_backup();
flag_rename = 0;
flush_root();
fsync(fd);
close(fd);
}
#include "bootlog.h"
|