file.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. #ifndef NASMLIB_FILE_H
  34. #define NASMLIB_FILE_H
  35. #include "compiler.h"
  36. #include "nasmlib.h"
  37. #include "error.h"
  38. #include <errno.h>
  39. #ifdef HAVE_FCNTL_H
  40. # include <fcntl.h>
  41. #endif
  42. #ifdef HAVE_SYS_TYPES_H
  43. #endif
  44. #ifdef HAVE_SYS_STAT_H
  45. # include <sys/stat.h>
  46. #endif
  47. #ifdef HAVE_IO_H
  48. # include <io.h>
  49. #endif
  50. #ifdef HAVE_UNISTD_H
  51. # include <unistd.h>
  52. #endif
  53. #ifdef HAVE_SYS_MMAN_H
  54. # include <sys/mman.h>
  55. #endif
  56. #ifndef R_OK
  57. # define R_OK 4 /* Classic Unix constant, same on Windows */
  58. #endif
  59. /* Can we adjust the file size without actually writing all the bytes? */
  60. #ifdef HAVE__CHSIZE_S
  61. # define os_ftruncate(fd,size) _chsize_s(fd,size)
  62. #elif defined(HAVE__CHSIZE)
  63. # define os_ftruncate(fd,size) _chsize(fd,size)
  64. #elif defined(HAVE_FTRUNCATE)
  65. # define os_ftruncate(fd,size) ftruncate(fd,size)
  66. #endif
  67. /*
  68. * On Windows, we want to use _wfopen(), as fopen() has a much smaller limit
  69. * on the path length that it supports. Furthermore, we want to prefix the
  70. * path name with \\?\ in order to let the Windows kernel know that
  71. * we are not limited to PATH_MAX characters. Thus, we wrap all the functions
  72. * which take filenames...
  73. */
  74. #ifdef _WIN32
  75. # include <wchar.h>
  76. typedef wchar_t *os_filename;
  77. typedef wchar_t os_fopenflag;
  78. os_filename os_mangle_filename(const char *filename);
  79. static inline void os_free_filename(os_filename filename)
  80. {
  81. nasm_free(filename);
  82. }
  83. # define os_fopen _wfopen
  84. # define os_access _waccess
  85. /*
  86. * On Win32/64, we have to use the _wstati64() function. Note that
  87. * we can't use _wstat64() without depending on a needlessly new
  88. * version os MSVCRT.
  89. */
  90. typedef struct _stati64 os_struct_stat;
  91. # define os_stat _wstati64
  92. # define os_fstat _fstati64
  93. /*
  94. * On Win32/64, freopen() and _wfreopen() fails when the mode string
  95. * is with the letter 'b' that represents to set binary mode. On
  96. * POSIX operating systems, the 'b' is ignored, without failure.
  97. */
  98. #include <io.h>
  99. #include <fcntl.h>
  100. static inline void os_set_binary_mode(FILE *f) {
  101. int ret = _setmode(_fileno(f), _O_BINARY);
  102. if (ret == -1) {
  103. nasm_fatalf(ERR_NOFILE, "unable to open file: %s",
  104. strerror(errno));
  105. }
  106. }
  107. #else /* not _WIN32 */
  108. typedef const char *os_filename;
  109. typedef char os_fopenflag;
  110. static inline os_filename os_mangle_filename(const char *filename)
  111. {
  112. return filename;
  113. }
  114. static inline void os_free_filename(os_filename filename)
  115. {
  116. (void)filename; /* Nothing to do */
  117. }
  118. static inline void os_set_binary_mode(FILE *f) {
  119. (void)f;
  120. }
  121. # define os_fopen fopen
  122. #if defined(HAVE_FACCESSAT) && defined(AT_EACCESS)
  123. static inline int os_access(os_filename pathname, int mode)
  124. {
  125. return faccessat(AT_FDCWD, pathname, mode, AT_EACCESS);
  126. }
  127. # define os_access os_access
  128. #elif defined(HAVE_ACCESS)
  129. # define os_access access
  130. #endif
  131. #ifdef HAVE_STRUCT_STAT
  132. typedef struct stat os_struct_stat;
  133. # ifdef HAVE_STAT
  134. # define os_stat stat
  135. # endif
  136. # ifdef HAVE_FSTAT
  137. # define os_fstat fstat
  138. # endif
  139. #else
  140. struct dummy_struct_stat {
  141. int st_mode;
  142. int st_size;
  143. };
  144. typedef struct dummy_struct_stat os_struct_stat;
  145. #endif
  146. #endif /* Not _WIN32 */
  147. #ifdef S_ISREG
  148. /* all good */
  149. #elif defined(HAVE_S_ISREG)
  150. /* exists, but not a macro */
  151. # define S_ISREG S_ISREG
  152. #elif defined(S_IFMT) && defined(S_IFREG)
  153. # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
  154. #elif defined(_S_IFMT) && defined(_S_IFREG)
  155. # define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
  156. #endif
  157. #ifdef fileno
  158. /* all good */
  159. #elif defined(HAVE_FILENO)
  160. /* exists, but not a macro */
  161. # define fileno fileno
  162. #elif defined(_fileno) || defined(HAVE__FILENO)
  163. # define fileno _fileno
  164. #endif
  165. #ifndef S_ISREG
  166. # undef os_stat
  167. # undef os_fstat
  168. #endif
  169. /* Disable these functions if they don't support something we need */
  170. #ifndef fileno
  171. # undef os_fstat
  172. # undef os_ftruncate
  173. # undef HAVE_MMAP
  174. #endif
  175. /*
  176. * If we don't have functional versions of these functions,
  177. * stub them out so we don't need so many #ifndefs
  178. */
  179. #ifndef os_stat
  180. static inline int os_stat(os_filename osfname, os_struct_stat *st)
  181. {
  182. (void)osfname;
  183. (void)st;
  184. return -1;
  185. }
  186. #endif
  187. #ifndef os_fstat
  188. static inline int os_fstat(int fd, os_struct_stat *st)
  189. {
  190. (void)osfname;
  191. (void)st;
  192. return -1;
  193. }
  194. #endif
  195. #ifndef S_ISREG
  196. static inline bool S_ISREG(int m)
  197. {
  198. (void)m;
  199. return false;
  200. }
  201. #endif
  202. #endif /* NASMLIB_FILE_H */