qemu-file-stdio.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * QEMU System Emulator
  3. *
  4. * Copyright (c) 2003-2008 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 "qemu-common.h"
  25. #include "block/coroutine.h"
  26. #include "migration/qemu-file.h"
  27. typedef struct QEMUFileStdio {
  28. FILE *stdio_file;
  29. QEMUFile *file;
  30. } QEMUFileStdio;
  31. static int stdio_get_fd(void *opaque)
  32. {
  33. QEMUFileStdio *s = opaque;
  34. return fileno(s->stdio_file);
  35. }
  36. static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,
  37. int size)
  38. {
  39. QEMUFileStdio *s = opaque;
  40. int res;
  41. res = fwrite(buf, 1, size, s->stdio_file);
  42. if (res != size) {
  43. return -errno;
  44. }
  45. return res;
  46. }
  47. static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
  48. {
  49. QEMUFileStdio *s = opaque;
  50. FILE *fp = s->stdio_file;
  51. int bytes;
  52. for (;;) {
  53. clearerr(fp);
  54. bytes = fread(buf, 1, size, fp);
  55. if (bytes != 0 || !ferror(fp)) {
  56. break;
  57. }
  58. if (errno == EAGAIN) {
  59. yield_until_fd_readable(fileno(fp));
  60. } else if (errno != EINTR) {
  61. break;
  62. }
  63. }
  64. return bytes;
  65. }
  66. static int stdio_pclose(void *opaque)
  67. {
  68. QEMUFileStdio *s = opaque;
  69. int ret;
  70. ret = pclose(s->stdio_file);
  71. if (ret == -1) {
  72. ret = -errno;
  73. } else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
  74. /* close succeeded, but non-zero exit code: */
  75. ret = -EIO; /* fake errno value */
  76. }
  77. g_free(s);
  78. return ret;
  79. }
  80. static int stdio_fclose(void *opaque)
  81. {
  82. QEMUFileStdio *s = opaque;
  83. int ret = 0;
  84. if (qemu_file_is_writable(s->file)) {
  85. int fd = fileno(s->stdio_file);
  86. struct stat st;
  87. ret = fstat(fd, &st);
  88. if (ret == 0 && S_ISREG(st.st_mode)) {
  89. /*
  90. * If the file handle is a regular file make sure the
  91. * data is flushed to disk before signaling success.
  92. */
  93. ret = fsync(fd);
  94. if (ret != 0) {
  95. ret = -errno;
  96. return ret;
  97. }
  98. }
  99. }
  100. if (fclose(s->stdio_file) == EOF) {
  101. ret = -errno;
  102. }
  103. g_free(s);
  104. return ret;
  105. }
  106. static const QEMUFileOps stdio_pipe_read_ops = {
  107. .get_fd = stdio_get_fd,
  108. .get_buffer = stdio_get_buffer,
  109. .close = stdio_pclose
  110. };
  111. static const QEMUFileOps stdio_pipe_write_ops = {
  112. .get_fd = stdio_get_fd,
  113. .put_buffer = stdio_put_buffer,
  114. .close = stdio_pclose
  115. };
  116. QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
  117. {
  118. FILE *stdio_file;
  119. QEMUFileStdio *s;
  120. if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
  121. fprintf(stderr, "qemu_popen: Argument validity check failed\n");
  122. return NULL;
  123. }
  124. stdio_file = popen(command, mode);
  125. if (stdio_file == NULL) {
  126. return NULL;
  127. }
  128. s = g_malloc0(sizeof(QEMUFileStdio));
  129. s->stdio_file = stdio_file;
  130. if (mode[0] == 'r') {
  131. s->file = qemu_fopen_ops(s, &stdio_pipe_read_ops);
  132. } else {
  133. s->file = qemu_fopen_ops(s, &stdio_pipe_write_ops);
  134. }
  135. return s->file;
  136. }
  137. static const QEMUFileOps stdio_file_read_ops = {
  138. .get_fd = stdio_get_fd,
  139. .get_buffer = stdio_get_buffer,
  140. .close = stdio_fclose
  141. };
  142. static const QEMUFileOps stdio_file_write_ops = {
  143. .get_fd = stdio_get_fd,
  144. .put_buffer = stdio_put_buffer,
  145. .close = stdio_fclose
  146. };
  147. QEMUFile *qemu_fopen(const char *filename, const char *mode)
  148. {
  149. QEMUFileStdio *s;
  150. if (qemu_file_mode_is_not_valid(mode)) {
  151. return NULL;
  152. }
  153. s = g_malloc0(sizeof(QEMUFileStdio));
  154. s->stdio_file = fopen(filename, mode);
  155. if (!s->stdio_file) {
  156. goto fail;
  157. }
  158. if (mode[0] == 'w') {
  159. s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
  160. } else {
  161. s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
  162. }
  163. return s->file;
  164. fail:
  165. g_free(s);
  166. return NULL;
  167. }