file.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /* ----------------------------------------------------------------------- *
  2. *
  3. * Copyright 1996-2017 The NASM Authors - All Rights Reserved
  4. * See the file AUTHORS included with the NASM distribution for
  5. * the specific copyright holders.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following
  9. * conditions are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above
  14. * copyright notice, this list of conditions and the following
  15. * disclaimer in the documentation and/or other materials provided
  16. * with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  19. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  20. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  30. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * ----------------------------------------------------------------------- */
  33. #include "file.h"
  34. void nasm_read(void *ptr, size_t size, FILE *f)
  35. {
  36. size_t n = fread(ptr, 1, size, f);
  37. if (ferror(f)) {
  38. nasm_fatal(0, "unable to read input: %s", strerror(errno));
  39. } else if (n != size || feof(f)) {
  40. nasm_fatal(0, "fatal short read on input");
  41. }
  42. }
  43. void nasm_write(const void *ptr, size_t size, FILE *f)
  44. {
  45. size_t n = fwrite(ptr, 1, size, f);
  46. if (n != size || ferror(f) || feof(f))
  47. nasm_fatal(0, "unable to write output: %s", strerror(errno));
  48. }
  49. void fwriteint16_t(uint16_t data, FILE * fp)
  50. {
  51. data = cpu_to_le16(data);
  52. nasm_write(&data, 2, fp);
  53. }
  54. void fwriteint32_t(uint32_t data, FILE * fp)
  55. {
  56. data = cpu_to_le32(data);
  57. nasm_write(&data, 4, fp);
  58. }
  59. void fwriteint64_t(uint64_t data, FILE * fp)
  60. {
  61. data = cpu_to_le64(data);
  62. nasm_write(&data, 8, fp);
  63. }
  64. void fwriteaddr(uint64_t data, int size, FILE * fp)
  65. {
  66. data = cpu_to_le64(data);
  67. nasm_write(&data, size, fp);
  68. }
  69. void fwritezero(off_t bytes, FILE *fp)
  70. {
  71. size_t blksize;
  72. #ifdef nasm_ftruncate
  73. if (bytes >= BUFSIZ && !ferror(fp) && !feof(fp)) {
  74. off_t pos = ftello(fp);
  75. if (pos >= 0) {
  76. pos += bytes;
  77. if (!fflush(fp) &&
  78. !nasm_ftruncate(fileno(fp), pos) &&
  79. !fseeko(fp, pos, SEEK_SET))
  80. return;
  81. }
  82. }
  83. #endif
  84. while (bytes > 0) {
  85. blksize = (bytes < ZERO_BUF_SIZE) ? bytes : ZERO_BUF_SIZE;
  86. nasm_write(zero_buffer, blksize, fp);
  87. bytes -= blksize;
  88. }
  89. }
  90. FILE *nasm_open_read(const char *filename, enum file_flags flags)
  91. {
  92. FILE *f = NULL;
  93. bool again = true;
  94. #ifdef __GLIBC__
  95. /*
  96. * Try to open this file with memory mapping for speed, unless we are
  97. * going to do it "manually" with nasm_map_file()
  98. */
  99. if (!(flags & NF_FORMAP)) {
  100. f = fopen(filename, (flags & NF_TEXT) ? "rtm" : "rbm");
  101. again = (!f) && (errno == EINVAL); /* Not supported, try without m */
  102. }
  103. #endif
  104. if (again)
  105. f = fopen(filename, (flags & NF_TEXT) ? "rt" : "rb");
  106. if (!f && (flags & NF_FATAL))
  107. nasm_fatal(ERR_NOFILE, "unable to open input file: `%s': %s",
  108. filename, strerror(errno));
  109. return f;
  110. }
  111. FILE *nasm_open_write(const char *filename, enum file_flags flags)
  112. {
  113. FILE *f;
  114. f = fopen(filename, (flags & NF_TEXT) ? "wt" : "wb");
  115. if (!f && (flags & NF_FATAL))
  116. nasm_fatal(ERR_NOFILE, "unable to open output file: `%s': %s",
  117. filename, strerror(errno));
  118. return f;
  119. }
  120. /*
  121. * Report the existence of a file
  122. */
  123. bool nasm_file_exists(const char *filename)
  124. {
  125. #if defined(HAVE_FACCESSAT) && defined(AT_EACCESS)
  126. return faccessat(AT_FDCWD, filename, R_OK, AT_EACCESS) == 0;
  127. #elif defined(HAVE_ACCESS)
  128. return access(filename, R_OK) == 0;
  129. #else
  130. FILE *f;
  131. f = fopen(filename, "rb");
  132. if (f) {
  133. fclose(f);
  134. return true;
  135. } else {
  136. return false;
  137. }
  138. #endif
  139. }
  140. /*
  141. * Report file size. This MAY move the file pointer.
  142. */
  143. off_t nasm_file_size(FILE *f)
  144. {
  145. #ifdef HAVE__FILELENGTHI64
  146. return _filelengthi64(fileno(f));
  147. #elif defined(nasm_fstat)
  148. nasm_struct_stat st;
  149. if (nasm_fstat(fileno(f), &st))
  150. return (off_t)-1;
  151. return st.st_size;
  152. #else
  153. if (fseeko(f, 0, SEEK_END))
  154. return (off_t)-1;
  155. return ftello(f);
  156. #endif
  157. }
  158. /*
  159. * Report file size given pathname
  160. */
  161. off_t nasm_file_size_by_path(const char *pathname)
  162. {
  163. #ifdef nasm_stat
  164. nasm_struct_stat st;
  165. if (nasm_stat(pathname, &st))
  166. return (off_t)-1;
  167. return st.st_size;
  168. #else
  169. FILE *fp;
  170. off_t len;
  171. fp = nasm_open_read(pathname, NF_BINARY);
  172. if (!fp)
  173. return (off_t)-1;
  174. len = nasm_file_size(fp);
  175. fclose(fp);
  176. return len;
  177. #endif
  178. }
  179. /*
  180. * Report the timestamp on a file, returns true if successful
  181. */
  182. bool nasm_file_time(time_t *t, const char *pathname)
  183. {
  184. #ifdef nasm_stat
  185. nasm_struct_stat st;
  186. if (nasm_stat(pathname, &st))
  187. return false;
  188. *t = st.st_mtime;
  189. return true;
  190. #else
  191. return false; /* No idea how to do this on this OS */
  192. #endif
  193. }