ramfs.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <auth.h>
  4. #include <fcall.h>
  5. #include <thread.h>
  6. #include <9p.h>
  7. static char Ebad[] = "something bad happened";
  8. static char Enomem[] = "no memory";
  9. typedef struct Ramfile Ramfile;
  10. struct Ramfile {
  11. char *data;
  12. int ndata;
  13. };
  14. void
  15. fsread(Req *r)
  16. {
  17. Ramfile *rf;
  18. vlong offset;
  19. long count;
  20. rf = r->fid->file->aux;
  21. offset = r->ifcall.offset;
  22. count = r->ifcall.count;
  23. //print("read %ld %lld\n", *count, offset);
  24. if(offset >= rf->ndata){
  25. r->ofcall.count = 0;
  26. respond(r, nil);
  27. return;
  28. }
  29. if(offset+count >= rf->ndata)
  30. count = rf->ndata - offset;
  31. memmove(r->ofcall.data, rf->data+offset, count);
  32. r->ofcall.count = count;
  33. respond(r, nil);
  34. }
  35. void
  36. fswrite(Req *r)
  37. {
  38. void *v;
  39. Ramfile *rf;
  40. vlong offset;
  41. long count;
  42. rf = r->fid->file->aux;
  43. offset = r->ifcall.offset;
  44. count = r->ifcall.count;
  45. if(offset+count >= rf->ndata){
  46. v = realloc(rf->data, offset+count);
  47. if(v == nil){
  48. respond(r, Enomem);
  49. return;
  50. }
  51. rf->data = v;
  52. rf->ndata = offset+count;
  53. r->fid->file->length = rf->ndata;
  54. }
  55. memmove(rf->data+offset, r->ifcall.data, count);
  56. r->ofcall.count = count;
  57. respond(r, nil);
  58. }
  59. void
  60. fscreate(Req *r)
  61. {
  62. Ramfile *rf;
  63. File *f;
  64. if(f = createfile(r->fid->file, r->ifcall.name, r->fid->uid, r->ifcall.perm, nil)){
  65. rf = emalloc9p(sizeof *rf);
  66. f->aux = rf;
  67. r->fid->file = f;
  68. r->ofcall.qid = f->qid;
  69. respond(r, nil);
  70. return;
  71. }
  72. respond(r, Ebad);
  73. }
  74. void
  75. fsopen(Req *r)
  76. {
  77. Ramfile *rf;
  78. rf = r->fid->file->aux;
  79. if(rf && (r->ifcall.mode&OTRUNC)){
  80. rf->ndata = 0;
  81. r->fid->file->length = 0;
  82. }
  83. respond(r, nil);
  84. }
  85. void
  86. fsdestroyfile(File *f)
  87. {
  88. Ramfile *rf;
  89. //fprint(2, "clunk\n");
  90. rf = f->aux;
  91. if(rf){
  92. free(rf->data);
  93. free(rf);
  94. }
  95. }
  96. Srv fs = {
  97. .open= fsopen,
  98. .read= fsread,
  99. .write= fswrite,
  100. .create= fscreate,
  101. };
  102. void
  103. usage(void)
  104. {
  105. fprint(2, "usage: ramfs [-D] [-s srvname] [-m mtpt]\n");
  106. exits("usage");
  107. }
  108. void
  109. main(int argc, char **argv)
  110. {
  111. char *addr = nil;
  112. char *srvname = nil;
  113. char *mtpt = nil;
  114. Qid q;
  115. fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile);
  116. q = fs.tree->root->qid;
  117. ARGBEGIN{
  118. case 'D':
  119. chatty9p++;
  120. break;
  121. case 'a':
  122. addr = EARGF(usage());
  123. break;
  124. case 's':
  125. srvname = EARGF(usage());
  126. break;
  127. case 'm':
  128. mtpt = EARGF(usage());
  129. break;
  130. default:
  131. usage();
  132. }ARGEND;
  133. if(argc)
  134. usage();
  135. if(chatty9p)
  136. fprint(2, "ramsrv.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srvname, mtpt);
  137. if(addr == nil && srvname == nil && mtpt == nil)
  138. sysfatal("must specify -a, -s, or -m option");
  139. if(addr)
  140. listensrv(&fs, addr);
  141. if(srvname || mtpt)
  142. postmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
  143. exits(0);
  144. }