1 #include "lib9.h" 2 #include "isa.h" 3 #include "interp.h" 4 #include "kernel.h" 5 #include "dynld.h" 6 7 Module* 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