1 #include "lib9.h"
2 #include "isa.h"
3 #include "interp.h"
4 #include "kernel.h"
5 #include "dynld.h"
6
7 Module*
readmod(char * path,Module * m,int sync)8 readmod(char *path, Module *m, int sync)
9 {
10 Dir *d;
11 int fd, n, dynld;
12 uchar *code;
13 Module *ans;
14 ulong length;
15
16 if(path[0] == '$') {
17 if(m == nil)
18 kwerrstr("module not built-in");
19 return m;
20 }
21
22 ans = nil;
23 code = nil;
24 length = 0;
25 dynld = 0;
26
27 if(sync)
28 release();
29
30 d = nil;
31 fd = kopen(path, OREAD);
32 if(fd < 0)
33 goto done;
34
35 if((d = kdirfstat(fd)) == nil)
36 goto done;
37
38 if(m != nil) {
39 if(d->dev == m->dev && d->type == m->dtype &&
40 d->mtime == m->mtime &&
41 d->qid.type == m->qid.type && d->qid.path == m->qid.path && d->qid.vers == m->qid.vers) {
42 ans = m;
43 goto done;
44 }
45 }
46
47 if(d->length < 0 || d->length >= 8*1024*1024){
48 kwerrstr("implausible length");
49 goto done;
50 }
51 if((d->mode&0111) && dynldable(fd)){
52 dynld = 1;
53 goto done1;
54 }
55 length = d->length;
56 code = mallocz(length, 0);
57 if(code == nil)
58 goto done;
59
60 n = kread(fd, code, length);
61 if(n != length) {
62 free(code);
63 code = nil;
64 }
65 done:
66 if(fd >= 0)
67 kclose(fd);
68 done1:
69 if(sync)
70 acquire();
71 if(m != nil && ans == nil)
72 unload(m);
73 if(code != nil) {
74 ans = parsemod(path, code, length, d);
75 free(code);
76 }
77 else if(dynld){
78 kseek(fd, 0, 0);
79 ans = newdyncode(fd, path, d);
80 kclose(fd);
81 }
82 free(d);
83 return ans;
84 }
85