1 #include "dat.h" 2 #include "fns.h" 3 #include "error.h" 4 #include <a.out.h> 5 #include <dynld.h> 6 7 /* 8 * channel-based kernel interface to dynld, for use by devdynld.c, 9 * libinterp/dlm.c, and possibly others 10 */ 11 12 static long 13 readfc(void *a, void *buf, long nbytes) 14 { 15 Chan *c = a; 16 17 if(waserror()) 18 return -1; 19 nbytes = devtab[c->type]->read(c, buf, nbytes, c->offset); 20 poperror(); 21 return nbytes; 22 } 23 24 static vlong 25 seekfc(void *a, vlong off, int t) 26 { 27 Chan *c = a; 28 29 if(c->qid.type & QTDIR || off < 0) 30 return -1; /* won't happen */ 31 switch(t){ 32 case 0: 33 lock(c); 34 c->offset = off; 35 unlock(c); 36 break; 37 case 1: 38 lock(c); 39 off += c->offset; 40 c->offset = off; 41 unlock(c); 42 break; 43 case 2: 44 return -1; /* not needed */ 45 } 46 return off; 47 } 48 49 static void 50 errfc(char *s) 51 { 52 kstrcpy(up->env->errstr, s, ERRMAX); 53 } 54 55 Dynobj* 56 kdynloadchan(Chan *c, Dynsym *tab, int ntab) 57 { 58 return dynloadgen(c, readfc, seekfc, errfc, tab, ntab, 0); 59 } 60 61 int 62 kdynloadable(Chan *c) 63 { 64 return dynloadable(c, readfc, seekfc); 65 } 66