fs.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. /* Copyright (C) 2014 Stony Brook University
  4. This file is part of Graphene Library OS.
  5. Graphene Library OS is free software: you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public License
  7. as published by the Free Software Foundation, either version 3 of the
  8. License, or (at your option) any later version.
  9. Graphene Library OS is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. /*
  16. * fs.c
  17. *
  18. * This file contains codes for implementation of 'str' filesystem.
  19. */
  20. #include <shim_internal.h>
  21. #include <shim_fs.h>
  22. #include <shim_profile.h>
  23. #include <pal.h>
  24. #include <pal_error.h>
  25. #include <errno.h>
  26. #include <linux/stat.h>
  27. #include <linux/fcntl.h>
  28. #include <asm/fcntl.h>
  29. #include <asm/mman.h>
  30. #include <asm/unistd.h>
  31. #include <asm/prctl.h>
  32. int str_open (struct shim_handle * hdl, struct shim_dentry * dent,
  33. int flags)
  34. {
  35. struct shim_str_data * data = dent->data;
  36. /* when str file is opened, it must have a data */
  37. if (!dent->data)
  38. return -ENOENT;
  39. REF_INC(data->ref_count);
  40. hdl->dentry = dent;
  41. hdl->flags = flags;
  42. return 0;
  43. }
  44. int str_dput (struct shim_dentry * dent)
  45. {
  46. struct shim_str_data * data = dent->data;
  47. if (!data || REF_DEC(data->ref_count) > 1)
  48. return 0;
  49. if (data->str) {
  50. free(data->str);
  51. data->str = NULL;
  52. }
  53. data->len = 0;
  54. data->buf_size = 0;
  55. free(dent->data);
  56. dent->data = NULL;
  57. return 0;
  58. }
  59. int str_close (struct shim_handle * hdl)
  60. {
  61. if (hdl->flags && (O_WRONLY|O_RDWR)) {
  62. int ret = str_flush(hdl);
  63. if (ret < 0)
  64. return ret;
  65. }
  66. str_dput(hdl->dentry);
  67. return 0;
  68. }
  69. int str_read (struct shim_handle * hdl, void * buf,
  70. size_t count)
  71. {
  72. int ret = 0;
  73. if (!(hdl->acc_mode && MAY_READ)) {
  74. ret = -EACCES;
  75. goto out;
  76. }
  77. struct shim_str_handle * strhdl = &hdl->info.str;
  78. assert(hdl->dentry);
  79. assert(strhdl->data);
  80. struct shim_str_data * data = strhdl->data;
  81. if (!data->str) {
  82. debug("str_data has no str\n");
  83. ret = -EACCES;
  84. goto out;
  85. }
  86. if (!strhdl->ptr)
  87. strhdl->ptr = data->str;
  88. int offset = strhdl->ptr - data->str;
  89. int remain = data->len - offset;
  90. if (count >= remain) {
  91. memcpy(buf, strhdl->ptr, remain);
  92. strhdl->ptr += remain;
  93. ret = remain;
  94. goto out;
  95. }
  96. memcpy(buf, strhdl->ptr, count);
  97. strhdl->ptr += count;
  98. ret = count;
  99. out:
  100. return ret;
  101. }
  102. int str_write (struct shim_handle * hdl, const void * buf,
  103. size_t count)
  104. {
  105. if (!(hdl->acc_mode && MAY_WRITE))
  106. return -EACCES;
  107. struct shim_str_handle * strhdl = &hdl->info.str;
  108. assert(hdl->dentry);
  109. assert(strhdl->data);
  110. struct shim_str_data * data = strhdl->data;
  111. if (!data->str ||
  112. strhdl->ptr + count > data->str + data->buf_size) {
  113. int newlen = 0;
  114. if (data->str) {
  115. newlen = data->buf_size * 2;
  116. while (strhdl->ptr + count > data->str + newlen)
  117. newlen *= 2;
  118. } else {
  119. newlen = count;
  120. }
  121. char * newbuf = malloc(newlen);
  122. if (!newbuf)
  123. return -ENOMEM;
  124. if (data->str) {
  125. memcpy(newbuf, data->str, data->len);
  126. free(data->str);
  127. }
  128. strhdl->ptr = newbuf + (strhdl->ptr - data->str);
  129. data->str = newbuf;
  130. data->buf_size = newlen;
  131. }
  132. memcpy(strhdl->ptr, buf, count);
  133. strhdl->ptr += count;
  134. data->dirty = true;
  135. if (strhdl->ptr >= data->str + data->len)
  136. data->len = strhdl->ptr - data->str;
  137. return count;
  138. }
  139. int str_seek (struct shim_handle * hdl, off_t offset,
  140. int whence)
  141. {
  142. struct shim_str_handle * strhdl = &hdl->info.str;
  143. assert(hdl->dentry);
  144. assert(strhdl->data);
  145. struct shim_str_data * data = strhdl->data;
  146. switch(whence) {
  147. case SEEK_SET:
  148. if (offset < 0)
  149. return -EINVAL;
  150. strhdl->ptr = data->str;
  151. if (strhdl->ptr > data->str + data->len)
  152. strhdl->ptr = data->str + data->len;
  153. break;
  154. case SEEK_CUR:
  155. if (offset >= 0) {
  156. strhdl->ptr += offset;
  157. if (strhdl->ptr > data->str + data->len)
  158. strhdl->ptr = data->str + data->len;
  159. } else {
  160. strhdl->ptr -= offset;
  161. if (strhdl->ptr < data->str)
  162. strhdl->ptr = data->str;
  163. }
  164. break;
  165. case SEEK_END:
  166. if (offset < 0)
  167. return -EINVAL;
  168. strhdl->ptr = data->str + data->len - offset;
  169. if (strhdl->ptr < data->str)
  170. strhdl->ptr = data->str;
  171. break;
  172. }
  173. return strhdl->ptr - data->str;
  174. }
  175. int str_flush (struct shim_handle * hdl)
  176. {
  177. struct shim_str_handle * strhdl = &hdl->info.str;
  178. assert(hdl->dentry);
  179. assert(strhdl->data);
  180. struct shim_str_data * data = strhdl->data;
  181. if (!data->dirty)
  182. return 0;
  183. if (!data->modify)
  184. return -EACCES;
  185. return data->modify(hdl);
  186. }
  187. struct shim_fs_ops str_fs_ops = {
  188. .close = &str_close,
  189. .read = &str_read,
  190. .write = &str_write,
  191. .seek = &str_seek,
  192. .flush = &str_flush,
  193. };
  194. struct shim_d_ops str_d_ops = {
  195. .open = &str_open,
  196. .dput = &str_dput,
  197. };