osdep.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * QEMU low level functions
  3. *
  4. * Copyright (c) 2003 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <stdarg.h>
  27. #include <stdbool.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include <unistd.h>
  31. #include <fcntl.h>
  32. /* Needed early for CONFIG_BSD etc. */
  33. #include "config-host.h"
  34. #if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
  35. #include <sys/mman.h>
  36. #endif
  37. #ifdef CONFIG_SOLARIS
  38. #include <sys/types.h>
  39. #include <sys/statvfs.h>
  40. /* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
  41. discussion about Solaris header problems */
  42. extern int madvise(caddr_t, size_t, int);
  43. #endif
  44. #include "qemu-common.h"
  45. #include "trace.h"
  46. #include "qemu_socket.h"
  47. #include "monitor.h"
  48. static bool fips_enabled = false;
  49. static const char *qemu_version = QEMU_VERSION;
  50. int socket_set_cork(int fd, int v)
  51. {
  52. #if defined(SOL_TCP) && defined(TCP_CORK)
  53. return setsockopt(fd, SOL_TCP, TCP_CORK, &v, sizeof(v));
  54. #else
  55. return 0;
  56. #endif
  57. }
  58. int qemu_madvise(void *addr, size_t len, int advice)
  59. {
  60. if (advice == QEMU_MADV_INVALID) {
  61. errno = EINVAL;
  62. return -1;
  63. }
  64. #if defined(CONFIG_MADVISE)
  65. return madvise(addr, len, advice);
  66. #elif defined(CONFIG_POSIX_MADVISE)
  67. return posix_madvise(addr, len, advice);
  68. #else
  69. errno = EINVAL;
  70. return -1;
  71. #endif
  72. }
  73. #ifndef _WIN32
  74. /*
  75. * Dups an fd and sets the flags
  76. */
  77. static int qemu_dup_flags(int fd, int flags)
  78. {
  79. int ret;
  80. int serrno;
  81. int dup_flags;
  82. int setfl_flags;
  83. #ifdef F_DUPFD_CLOEXEC
  84. ret = fcntl(fd, F_DUPFD_CLOEXEC, 0);
  85. #else
  86. ret = dup(fd);
  87. if (ret != -1) {
  88. qemu_set_cloexec(ret);
  89. }
  90. #endif
  91. if (ret == -1) {
  92. goto fail;
  93. }
  94. dup_flags = fcntl(ret, F_GETFL);
  95. if (dup_flags == -1) {
  96. goto fail;
  97. }
  98. if ((flags & O_SYNC) != (dup_flags & O_SYNC)) {
  99. errno = EINVAL;
  100. goto fail;
  101. }
  102. /* Set/unset flags that we can with fcntl */
  103. setfl_flags = O_APPEND | O_ASYNC | O_NONBLOCK;
  104. #ifdef O_NOATIME
  105. setfl_flags |= O_NOATIME;
  106. #endif
  107. #ifdef O_DIRECT
  108. setfl_flags |= O_DIRECT;
  109. #endif
  110. dup_flags &= ~setfl_flags;
  111. dup_flags |= (flags & setfl_flags);
  112. if (fcntl(ret, F_SETFL, dup_flags) == -1) {
  113. goto fail;
  114. }
  115. /* Truncate the file in the cases that open() would truncate it */
  116. if (flags & O_TRUNC ||
  117. ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))) {
  118. if (ftruncate(ret, 0) == -1) {
  119. goto fail;
  120. }
  121. }
  122. return ret;
  123. fail:
  124. serrno = errno;
  125. if (ret != -1) {
  126. close(ret);
  127. }
  128. errno = serrno;
  129. return -1;
  130. }
  131. #endif
  132. /*
  133. * Opens a file with FD_CLOEXEC set
  134. */
  135. int qemu_open(const char *name, int flags, ...)
  136. {
  137. int ret;
  138. int mode = 0;
  139. #ifndef _WIN32
  140. const char *fdset_id_str;
  141. /* Attempt dup of fd from fd set */
  142. if (strstart(name, "/dev/fdset/", &fdset_id_str)) {
  143. int64_t fdset_id;
  144. int fd, dupfd;
  145. fdset_id = qemu_parse_fdset(fdset_id_str);
  146. if (fdset_id == -1) {
  147. errno = EINVAL;
  148. return -1;
  149. }
  150. fd = monitor_fdset_get_fd(fdset_id, flags);
  151. if (fd == -1) {
  152. return -1;
  153. }
  154. dupfd = qemu_dup_flags(fd, flags);
  155. if (dupfd == -1) {
  156. return -1;
  157. }
  158. ret = monitor_fdset_dup_fd_add(fdset_id, dupfd);
  159. if (ret == -1) {
  160. close(dupfd);
  161. errno = EINVAL;
  162. return -1;
  163. }
  164. return dupfd;
  165. }
  166. #endif
  167. if (flags & O_CREAT) {
  168. va_list ap;
  169. va_start(ap, flags);
  170. mode = va_arg(ap, int);
  171. va_end(ap);
  172. }
  173. #ifdef O_CLOEXEC
  174. ret = open(name, flags | O_CLOEXEC, mode);
  175. #else
  176. ret = open(name, flags, mode);
  177. if (ret >= 0) {
  178. qemu_set_cloexec(ret);
  179. }
  180. #endif
  181. return ret;
  182. }
  183. int qemu_close(int fd)
  184. {
  185. int64_t fdset_id;
  186. /* Close fd that was dup'd from an fdset */
  187. fdset_id = monitor_fdset_dup_fd_find(fd);
  188. if (fdset_id != -1) {
  189. int ret;
  190. ret = close(fd);
  191. if (ret == 0) {
  192. monitor_fdset_dup_fd_remove(fd);
  193. }
  194. return ret;
  195. }
  196. return close(fd);
  197. }
  198. /*
  199. * A variant of write(2) which handles partial write.
  200. *
  201. * Return the number of bytes transferred.
  202. * Set errno if fewer than `count' bytes are written.
  203. *
  204. * This function don't work with non-blocking fd's.
  205. * Any of the possibilities with non-bloking fd's is bad:
  206. * - return a short write (then name is wrong)
  207. * - busy wait adding (errno == EAGAIN) to the loop
  208. */
  209. ssize_t qemu_write_full(int fd, const void *buf, size_t count)
  210. {
  211. ssize_t ret = 0;
  212. ssize_t total = 0;
  213. while (count) {
  214. ret = write(fd, buf, count);
  215. if (ret < 0) {
  216. if (errno == EINTR)
  217. continue;
  218. break;
  219. }
  220. count -= ret;
  221. buf += ret;
  222. total += ret;
  223. }
  224. return total;
  225. }
  226. /*
  227. * Opens a socket with FD_CLOEXEC set
  228. */
  229. int qemu_socket(int domain, int type, int protocol)
  230. {
  231. int ret;
  232. #ifdef SOCK_CLOEXEC
  233. ret = socket(domain, type | SOCK_CLOEXEC, protocol);
  234. if (ret != -1 || errno != EINVAL) {
  235. return ret;
  236. }
  237. #endif
  238. ret = socket(domain, type, protocol);
  239. if (ret >= 0) {
  240. qemu_set_cloexec(ret);
  241. }
  242. return ret;
  243. }
  244. /*
  245. * Accept a connection and set FD_CLOEXEC
  246. */
  247. int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
  248. {
  249. int ret;
  250. #ifdef CONFIG_ACCEPT4
  251. ret = accept4(s, addr, addrlen, SOCK_CLOEXEC);
  252. if (ret != -1 || errno != ENOSYS) {
  253. return ret;
  254. }
  255. #endif
  256. ret = accept(s, addr, addrlen);
  257. if (ret >= 0) {
  258. qemu_set_cloexec(ret);
  259. }
  260. return ret;
  261. }
  262. /*
  263. * A variant of send(2) which handles partial write.
  264. *
  265. * Return the number of bytes transferred, which is only
  266. * smaller than `count' if there is an error.
  267. *
  268. * This function won't work with non-blocking fd's.
  269. * Any of the possibilities with non-bloking fd's is bad:
  270. * - return a short write (then name is wrong)
  271. * - busy wait adding (errno == EAGAIN) to the loop
  272. */
  273. ssize_t qemu_send_full(int fd, const void *buf, size_t count, int flags)
  274. {
  275. ssize_t ret = 0;
  276. ssize_t total = 0;
  277. while (count) {
  278. ret = send(fd, buf, count, flags);
  279. if (ret < 0) {
  280. if (errno == EINTR) {
  281. continue;
  282. }
  283. break;
  284. }
  285. count -= ret;
  286. buf += ret;
  287. total += ret;
  288. }
  289. return total;
  290. }
  291. /*
  292. * A variant of recv(2) which handles partial write.
  293. *
  294. * Return the number of bytes transferred, which is only
  295. * smaller than `count' if there is an error.
  296. *
  297. * This function won't work with non-blocking fd's.
  298. * Any of the possibilities with non-bloking fd's is bad:
  299. * - return a short write (then name is wrong)
  300. * - busy wait adding (errno == EAGAIN) to the loop
  301. */
  302. ssize_t qemu_recv_full(int fd, void *buf, size_t count, int flags)
  303. {
  304. ssize_t ret = 0;
  305. ssize_t total = 0;
  306. while (count) {
  307. ret = qemu_recv(fd, buf, count, flags);
  308. if (ret <= 0) {
  309. if (ret < 0 && errno == EINTR) {
  310. continue;
  311. }
  312. break;
  313. }
  314. count -= ret;
  315. buf += ret;
  316. total += ret;
  317. }
  318. return total;
  319. }
  320. void qemu_set_version(const char *version)
  321. {
  322. qemu_version = version;
  323. }
  324. const char *qemu_get_version(void)
  325. {
  326. return qemu_version;
  327. }
  328. void fips_set_state(bool requested)
  329. {
  330. #ifdef __linux__
  331. if (requested) {
  332. FILE *fds = fopen("/proc/sys/crypto/fips_enabled", "r");
  333. if (fds != NULL) {
  334. fips_enabled = (fgetc(fds) == '1');
  335. fclose(fds);
  336. }
  337. }
  338. #else
  339. fips_enabled = false;
  340. #endif /* __linux__ */
  341. #ifdef _FIPS_DEBUG
  342. fprintf(stderr, "FIPS mode %s (requested %s)\n",
  343. (fips_enabled ? "enabled" : "disabled"),
  344. (requested ? "enabled" : "disabled"));
  345. #endif
  346. }
  347. bool fips_get_state(void)
  348. {
  349. return fips_enabled;
  350. }