-
Notifications
You must be signed in to change notification settings - Fork 0
/
total.c
58 lines (55 loc) · 2.35 KB
/
total.c
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
/* Open, fstat, mmap, close, and sum all files specified in av[] */
#include <fcntl.h> /* O_ macros */
#include <stdio.h> /* fprintf, stderr */
#include <string.h> /* strerror() */
#include <sys/mman.h> /* PROT_* MAP_* */
#include <sys/stat.h> /* struct stat */
#include "linux/batch.h" /* syscall_t, scall<N> macros, batch */
char *mapall(char *path, long *len, int *eno) { /* could take prot/flags/etc. */
struct stat st;
/* Might also init ret[] to impossible -4095 (greatest abs errno) */
long ret[10]={0}, fdAdr=(long)&ret[0], szAdr=(long)&st.st_size,r;
syscall_t b[10] = { /* 0 1 2 3 4 5 .arg[]s */
/*0*/scall3(open , -1,0,0, path, O_RDONLY, 0), // get fd
/*1*/scall2(wdcpy, -1,0,0, &b[4].arg[0], fdAdr), // ->fstat
/*2*/scall2(wdcpy, -1,0,0, &b[8].arg[0], fdAdr), // ->close post mapFail
/*3*/scall2(wdcpy, -1,0,0, &b[9].arg[0], fdAdr), // ->close post mapOk
/*4*/scall2(fstat, +3,0,0, 0, &st), // <0 =>skip cp,cp,mmap
/*5*/scall2(wdcpy, -1,0,0, &b[7].arg[1], szAdr), // sz to mmap
/*6*/scall2(wdcpy, -1,0,0, &b[7].arg[4], fdAdr), // fd to mmap
/*7*/scall6(mmap , 0,1,1, 0, 0, PROT_READ, MAP_SHARED, 0, 0),
/*8*/scall1(close, -1,-1,-1, 0), // -1s: Always Exit; For the < 9 test
/*9*/scall1(close, -1,0,0, 0) }; // Test ret[9] in user space
if ((r = batch(ret, b, 10, 0, 0)) < 9) { // rval is highest done INDEX
if (eno) { // Might instead return all of ret[]|A thinning
while (r > 0 && ret[r] >= 0) r--;
*eno = -ret[r]; // but the call instigating exit..
} //..is not a bad simulation.
return (char *)-1;
}
if (ret[9] < 0) { // If all >=0 but final close, re-try the close.
*eno = -ret[9]; // Like fstat fail, this can only occur on odd/
close(ret[0]); //..remote FSes. This leaks like close-fail post
} //..fail-mmap, but it's all we can really do.
if (len)
*len = st.st_size;
return (char *)ret[7];
}
int sum(char *buf, long len) {
long i, s = 0;
for (i = 0; i < len; i++)
s += buf[i];
return s;
}
int main(int ac __attribute((unused)), char **av) {
int eno;
long total = 0, len = 0;
char *p;
for (av++; *av; av++)
if ((p = mapall(*av, &len, &eno)) != (char *)-1)
total += sum(p, len);
else
fprintf(stderr, "sum: \"%s\": %s\n", *av, strerror(eno));
printf("grand total: %ld\n", total);
return 0;
}