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