dynldc.c 999 B

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