fs.c 5.7 KB

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