diff options
| author | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
|---|---|---|
| committer | Charles.Forsyth <devnull@localhost> | 2006-12-22 17:07:39 +0000 |
| commit | 37da2899f40661e3e9631e497da8dc59b971cbd0 (patch) | |
| tree | cbc6d4680e347d906f5fa7fca73214418741df72 /libinterp/readmod.c | |
| parent | 54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff) | |
20060303a
Diffstat (limited to 'libinterp/readmod.c')
| -rw-r--r-- | libinterp/readmod.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/libinterp/readmod.c b/libinterp/readmod.c new file mode 100644 index 00000000..eebc9ba5 --- /dev/null +++ b/libinterp/readmod.c @@ -0,0 +1,84 @@ +#include "lib9.h" +#include "isa.h" +#include "interp.h" +#include "kernel.h" +#include "dynld.h" + +Module* +readmod(char *path, Module *m, int sync) +{ + Dir *d; + int fd, n, dynld; + uchar *code; + Module *ans; + ulong length; + + if(path[0] == '$') { + if(m == nil) + kwerrstr("module not built-in"); + return m; + } + + ans = nil; + code = nil; + length = 0; + dynld = 0; + + if(sync) + release(); + + d = nil; + fd = kopen(path, OREAD); + if(fd < 0) + goto done; + + if((d = kdirfstat(fd)) == nil) + goto done; + + if(m != nil) { + if(d->dev == m->dev && d->type == m->dtype && + d->mtime == m->mtime && + d->qid.type == m->qid.type && d->qid.path == m->qid.path && d->qid.vers == m->qid.vers) { + ans = m; + goto done; + } + } + + if(d->length < 0 || d->length >= 8*1024*1024){ + kwerrstr("implausible length"); + goto done; + } + if((d->mode&0111) && dynldable(fd)){ + dynld = 1; + goto done1; + } + length = d->length; + code = mallocz(length, 0); + if(code == nil) + goto done; + + n = kread(fd, code, length); + if(n != length) { + free(code); + code = nil; + } +done: + if(fd >= 0) + kclose(fd); +done1: + if(sync) + acquire(); + if(m != nil && ans == nil) + unload(m); + if(code != nil) { + ans = parsemod(path, code, length, d); + free(code); + } + else if(dynld){ + kseek(fd, 0, 0); + ans = newdyncode(fd, path, d); + kclose(fd); + } + free(d); + return ans; +} |
