fs.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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 'socket' 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/mman.h>
  27. #include <asm/unistd.h>
  28. #include <asm/prctl.h>
  29. #include <asm/fcntl.h>
  30. static int socket_close (struct shim_handle * hdl)
  31. {
  32. /* XXX: Shouldn't this do something? */
  33. __UNUSED(hdl);
  34. return 0;
  35. }
  36. static ssize_t socket_read (struct shim_handle * hdl, void * buf, size_t count)
  37. {
  38. struct shim_sock_handle * sock = &hdl->info.sock;
  39. if (!count)
  40. return 0;
  41. lock(&hdl->lock);
  42. if (sock->sock_type == SOCK_STREAM &&
  43. sock->sock_state != SOCK_ACCEPTED &&
  44. sock->sock_state != SOCK_CONNECTED &&
  45. sock->sock_state != SOCK_BOUNDCONNECTED) {
  46. sock->error = ENOTCONN;
  47. unlock(&hdl->lock);
  48. return -ENOTCONN;
  49. }
  50. if (sock->sock_type == SOCK_DGRAM &&
  51. sock->sock_state != SOCK_CONNECTED &&
  52. sock->sock_state != SOCK_BOUNDCONNECTED) {
  53. sock->error = EDESTADDRREQ;
  54. unlock(&hdl->lock);
  55. return -EDESTADDRREQ;
  56. }
  57. unlock(&hdl->lock);
  58. PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0);
  59. if (!bytes)
  60. switch(PAL_NATIVE_ERRNO) {
  61. case PAL_ERROR_ENDOFSTREAM:
  62. return 0;
  63. default: {
  64. int err = PAL_ERRNO;
  65. lock(&hdl->lock);
  66. sock->error = err;
  67. unlock(&hdl->lock);
  68. return -err;
  69. }
  70. }
  71. assert((ssize_t) bytes > 0);
  72. return (ssize_t) bytes;
  73. }
  74. static ssize_t socket_write (struct shim_handle * hdl, const void * buf, size_t count)
  75. {
  76. struct shim_sock_handle * sock = &hdl->info.sock;
  77. lock(&hdl->lock);
  78. if (sock->sock_type == SOCK_STREAM &&
  79. sock->sock_state != SOCK_ACCEPTED &&
  80. sock->sock_state != SOCK_CONNECTED &&
  81. sock->sock_state != SOCK_BOUNDCONNECTED) {
  82. sock->error = ENOTCONN;
  83. unlock(&hdl->lock);
  84. return -ENOTCONN;
  85. }
  86. if (sock->sock_type == SOCK_DGRAM &&
  87. sock->sock_state != SOCK_CONNECTED &&
  88. sock->sock_state != SOCK_BOUNDCONNECTED) {
  89. sock->error = EDESTADDRREQ;
  90. unlock(&hdl->lock);
  91. return -EDESTADDRREQ;
  92. }
  93. unlock(&hdl->lock);
  94. if (!count)
  95. return 0;
  96. PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void *) buf, NULL);
  97. if (!bytes) {
  98. int err;
  99. switch(PAL_NATIVE_ERRNO) {
  100. case PAL_ERROR_CONNFAILED:
  101. err = EPIPE;
  102. break;
  103. default:
  104. err = PAL_ERRNO;
  105. break;
  106. }
  107. lock(&hdl->lock);
  108. sock->error = err;
  109. unlock(&hdl->lock);
  110. return -err;
  111. }
  112. assert((ssize_t) bytes > 0);
  113. return (ssize_t) bytes;
  114. }
  115. static int socket_hstat (struct shim_handle * hdl, struct stat * stat)
  116. {
  117. if (!stat)
  118. return 0;
  119. PAL_STREAM_ATTR attr;
  120. if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr))
  121. return -PAL_ERRNO;
  122. memset(stat, 0, sizeof(struct stat));
  123. stat->st_ino = 0;
  124. stat->st_size = (off_t) attr.pending_size;
  125. stat->st_mode = S_IFSOCK;
  126. return 0;
  127. }
  128. static int socket_checkout (struct shim_handle * hdl)
  129. {
  130. hdl->fs = NULL;
  131. return 0;
  132. }
  133. static off_t socket_poll (struct shim_handle * hdl, int poll_type)
  134. {
  135. struct shim_sock_handle * sock = &hdl->info.sock;
  136. off_t ret = 0;
  137. lock(&hdl->lock);
  138. if (poll_type & FS_POLL_RD) {
  139. if (sock->sock_type == SOCK_STREAM) {
  140. if (sock->sock_state == SOCK_CREATED ||
  141. sock->sock_state == SOCK_BOUND ||
  142. sock->sock_state == SOCK_SHUTDOWN) {
  143. ret = -ENOTCONN;
  144. goto out;
  145. }
  146. }
  147. if (sock->sock_type == SOCK_DGRAM &&
  148. sock->sock_state == SOCK_SHUTDOWN) {
  149. ret = -ENOTCONN;
  150. goto out;
  151. }
  152. }
  153. if (poll_type & FS_POLL_WR) {
  154. if (sock->sock_type == SOCK_STREAM) {
  155. if (sock->sock_state == SOCK_CREATED ||
  156. sock->sock_state == SOCK_BOUND ||
  157. sock->sock_state == SOCK_LISTENED ||
  158. sock->sock_state == SOCK_SHUTDOWN) {
  159. ret = -ENOTCONN;
  160. goto out;
  161. }
  162. }
  163. if (sock->sock_type == SOCK_DGRAM &&
  164. sock->sock_state == SOCK_SHUTDOWN) {
  165. ret = -ENOTCONN;
  166. goto out;
  167. }
  168. }
  169. if (!hdl->pal_handle) {
  170. ret = -EBADF;
  171. goto out;
  172. }
  173. PAL_STREAM_ATTR attr;
  174. if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr)) {
  175. ret = -PAL_ERRNO;
  176. goto out;
  177. }
  178. if (poll_type == FS_POLL_SZ) {
  179. ret = attr.pending_size;
  180. goto out;
  181. }
  182. ret = 0;
  183. if (attr.disconnected)
  184. ret |= FS_POLL_ER;
  185. if ((poll_type & FS_POLL_RD) && attr.readable)
  186. ret |= FS_POLL_RD;
  187. if ((poll_type & FS_POLL_WR) && attr.writable)
  188. ret |= FS_POLL_WR;
  189. out:
  190. if (ret < 0) {
  191. debug("socket_poll failed (%ld)\n", ret);
  192. sock->error = -ret;
  193. }
  194. unlock(&hdl->lock);
  195. return ret;
  196. }
  197. static int socket_setflags (struct shim_handle * hdl, int flags)
  198. {
  199. if (!hdl->pal_handle)
  200. return 0;
  201. PAL_STREAM_ATTR attr;
  202. if (!DkStreamAttributesQueryByHandle(hdl->pal_handle, &attr))
  203. return -PAL_ERRNO;
  204. if (attr.nonblocking) {
  205. if (flags & O_NONBLOCK)
  206. return 0;
  207. attr.nonblocking = PAL_FALSE;
  208. } else {
  209. if (!(flags & O_NONBLOCK))
  210. return 0;
  211. attr.nonblocking = PAL_TRUE;
  212. }
  213. if (!DkStreamAttributesSetByHandle(hdl->pal_handle, &attr))
  214. return -PAL_ERRNO;
  215. return 0;
  216. }
  217. struct shim_fs_ops socket_fs_ops = {
  218. .close = &socket_close,
  219. .read = &socket_read,
  220. .write = &socket_write,
  221. .hstat = &socket_hstat,
  222. .checkout = &socket_checkout,
  223. .poll = &socket_poll,
  224. .setflags = &socket_setflags,
  225. };
  226. struct shim_mount socket_builtin_fs = { .type = "socket",
  227. .fs_ops = &socket_fs_ops, };