ramfs.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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 *srvname = nil;
  112. char *mtpt = nil;
  113. Qid q;
  114. fs.tree = alloctree(nil, nil, DMDIR|0777, fsdestroyfile);
  115. q = fs.tree->root->qid;
  116. ARGBEGIN{
  117. case 'D':
  118. chatty9p++;
  119. break;
  120. case 's':
  121. srvname = EARGF(usage());
  122. break;
  123. case 'm':
  124. mtpt = EARGF(usage());
  125. break;
  126. default:
  127. usage();
  128. }ARGEND;
  129. if(argc)
  130. usage();
  131. if(chatty9p)
  132. fprint(2, "ramsrv.nopipe %d srvname %s mtpt %s\n", fs.nopipe, srvname, mtpt);
  133. if(srvname == nil && mtpt == nil)
  134. sysfatal("you should at least specify a -s or -m option");
  135. postmountsrv(&fs, srvname, mtpt, MREPL|MCREATE);
  136. exits(0);
  137. }