blob: 4f0420ec69d09af44f5557f9e24443754a7eb51a [file] [log] [blame]
H. Peter Anvin92223642017-02-23 18:39:00 -08001/* ----------------------------------------------------------------------- *
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
34#ifndef NASMLIB_FILE_H
35#define NASMLIB_FILE_H
36
37#include "compiler.h"
38#include "nasmlib.h"
H. Peter Anvinb20bc732017-03-07 19:23:03 -080039#include "error.h"
H. Peter Anvin92223642017-02-23 18:39:00 -080040
41#include <errno.h>
42
43#ifdef HAVE_FCNTL_H
44# include <fcntl.h>
45#endif
H. Peter Anvin675e7b72017-04-05 21:19:03 -070046#ifdef HAVE_SYS_TYPES_H
H. Peter Anvin675e7b72017-04-05 21:19:03 -070047#endif
H. Peter Anvin92223642017-02-23 18:39:00 -080048#ifdef HAVE_SYS_STAT_H
49# include <sys/stat.h>
50#endif
51#ifdef HAVE_IO_H
52# include <io.h>
53#endif
54#ifdef HAVE_UNISTD_H
55# include <unistd.h>
56#endif
57#ifdef HAVE_SYS_MMAN_H
58# include <sys/mman.h>
59#endif
60
H. Peter Anvin92223642017-02-23 18:39:00 -080061#ifndef R_OK
62# define R_OK 4 /* Classic Unix constant, same on Windows */
63#endif
64
65/* Can we adjust the file size without actually writing all the bytes? */
H. Peter Anvin31184292017-04-06 15:30:56 -070066#ifdef HAVE__CHSIZE_S
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -070067# define os_ftruncate(fd,size) _chsize_s(fd,size)
H. Peter Anvin31184292017-04-06 15:30:56 -070068#elif defined(HAVE__CHSIZE)
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -070069# define os_ftruncate(fd,size) _chsize(fd,size)
H. Peter Anvin31184292017-04-06 15:30:56 -070070#elif defined(HAVE_FTRUNCATE)
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -070071# define os_ftruncate(fd,size) ftruncate(fd,size)
H. Peter Anvin92223642017-02-23 18:39:00 -080072#endif
73
74/*
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -070075 * On Windows, we want to use _wfopen(), as fopen() has a much smaller limit
76 * on the path length that it supports. Furthermore, we want to prefix the
77 * path name with \\?\ in order to let the Windows kernel know that
78 * we are not limited to PATH_MAX characters. Thus, we wrap all the functions
79 * which take filenames...
H. Peter Anvin92223642017-02-23 18:39:00 -080080 */
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -070081#ifdef _WIN32
82# include <wchar.h>
83typedef wchar_t *os_filename;
84typedef wchar_t os_fopenflag;
85
86os_filename os_mangle_filename(const char *filename);
87static inline void os_free_filename(os_filename filename)
88{
89 nasm_free(filename);
90}
91
92# define os_fopen _wfopen
93# define os_access _waccess
94
95/*
96 * On Win32/64, we have to use the _wstati64() function. Note that
97 * we can't use _wstat64() without depending on a needlessly new
98 * version os MSVCRT.
99 */
100
101typedef struct _stati64 os_struct_stat;
102
103# define os_stat _wstati64
104# define os_fstat _fstati64
105
106#else /* not _WIN32 */
107
108typedef const char *os_filename;
109typedef char os_fopenflag;
110
111static inline os_filename os_mangle_filename(const char *filename)
112{
113 return filename;
114}
115static inline void os_free_filename(os_filename filename)
116{
117 (void)filename; /* Nothing to do */
118}
119
120# define os_fopen fopen
121
122#if defined(HAVE_FACCESSAT) && defined(AT_EACCESS)
123static 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
H. Peter Anvin31184292017-04-06 15:30:56 -0700130#endif
131
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -0700132#ifdef HAVE_STRUCT_STAT
133typedef struct stat os_struct_stat;
H. Peter Anvin31184292017-04-06 15:30:56 -0700134# ifdef HAVE_STAT
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -0700135# define os_stat stat
H. Peter Anvin31184292017-04-06 15:30:56 -0700136# endif
137# ifdef HAVE_FSTAT
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -0700138# define os_fstat fstat
H. Peter Anvin92223642017-02-23 18:39:00 -0800139# endif
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -0700140#else
141struct dummy_struct_stat {
142 int st_mode;
143 int st_size;
144};
145typedef struct dummy_struct_stat os_struct_stat;
H. Peter Anvin92223642017-02-23 18:39:00 -0800146#endif
147
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -0700148#endif /* Not _WIN32 */
149
150#ifdef S_ISREG
151/* all good */
152#elif defined(HAVE_S_ISREG)
153/* exists, but not a macro */
154# define S_ISREG S_ISREG
155#elif defined(S_IFMT) && defined(S_IFREG)
156# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
157#elif defined(_S_IFMT) && defined(_S_IFREG)
158# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
H. Peter Anvin31184292017-04-06 15:30:56 -0700159#endif
160
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -0700161#ifdef fileno
162/* all good */
163#elif defined(HAVE_FILENO)
164/* exists, but not a macro */
165# define fileno fileno
166#elif defined(_fileno) || defined(HAVE__FILENO)
167# define fileno _fileno
168#endif
169
170#ifndef S_ISREG
171# undef os_stat
172# undef os_fstat
173#endif
174
175/* Disable these functions if they don't support something we need */
176#ifndef fileno
177# undef os_fstat
178# undef os_ftruncate
H. Peter Anvin31184292017-04-06 15:30:56 -0700179# undef HAVE_MMAP
H. Peter Anvin (Intel)471120f2019-05-15 13:07:21 -0700180#endif
181
182/*
183 * If we don't have functional versions of these functions,
184 * stub them out so we don't need so many #ifndefs
185 */
186#ifndef os_stat
187static inline int os_stat(os_filename osfname, os_struct_stat *st)
188{
189 (void)osfname;
190 (void)st;
191 return -1;
192}
193#endif
194
195#ifndef os_fstat
196static inline int os_fstat(int fd, os_struct_stat *st)
197{
198 (void)osfname;
199 (void)st;
200 return -1;
201}
202#endif
203
204#ifndef S_ISREG
205static inline bool S_ISREG(int m)
206{
207 (void)m;
208 return false;
209}
H. Peter Anvin31184292017-04-06 15:30:56 -0700210#endif
211
H. Peter Anvin92223642017-02-23 18:39:00 -0800212#endif /* NASMLIB_FILE_H */