diff --git a/Makefile.in b/Makefile.in index d3bae08cd..38f099dec 100644 --- a/Makefile.in +++ b/Makefile.in @@ -155,10 +155,10 @@ LIBOBJ_COM = \ nasmlib/alloc.$(O) nasmlib/asprintf.$(O) \ nasmlib/crc32b.$(O) nasmlib/crc64.$(O) nasmlib/md5c.$(O) \ nasmlib/string.$(O) nasmlib/nctype.$(O) \ - nasmlib/file.$(O) nasmlib/mmap.$(O) nasmlib/ilog2.$(O) \ - nasmlib/realpath.$(O) nasmlib/path.$(O) \ - nasmlib/filename.$(O) nasmlib/rlimit.$(O) \ - nasmlib/numstr.$(O) \ + nasmlib/file.$(O) nasmlib/fileio.$(O) nasmlib/mmap.$(O) \ + nasmlib/realpath.$(O) nasmlib/path.$(O) nasmlib/filename.$(O) \ + nasmlib/ilog2.$(O) nasmlib/numstr.$(O) \ + nasmlib/rlimit.$(O) \ nasmlib/zerobuf.$(O) nasmlib/bsi.$(O) \ nasmlib/rbtree.$(O) nasmlib/hashtbl.$(O) \ nasmlib/raa.$(O) nasmlib/saa.$(O) \ diff --git a/Mkfiles/msvc.mak b/Mkfiles/msvc.mak index 67ff5bbf3..7b3a4f7a9 100644 --- a/Mkfiles/msvc.mak +++ b/Mkfiles/msvc.mak @@ -106,10 +106,10 @@ LIBOBJ_COM = \ nasmlib\alloc.obj nasmlib\asprintf.obj \ nasmlib\crc32b.obj nasmlib\crc64.obj nasmlib\md5c.obj \ nasmlib\string.obj nasmlib\nctype.obj \ - nasmlib\file.obj nasmlib\mmap.obj nasmlib\ilog2.obj \ - nasmlib\realpath.obj nasmlib\path.obj \ - nasmlib\filename.obj nasmlib\rlimit.obj \ - nasmlib\numstr.obj \ + nasmlib\file.obj nasmlib\fileio.obj nasmlib\mmap.obj \ + nasmlib\realpath.obj nasmlib\path.obj nasmlib\filename.obj \ + nasmlib\ilog2.obj nasmlib\numstr.obj \ + nasmlib\rlimit.obj \ nasmlib\zerobuf.obj nasmlib\bsi.obj \ nasmlib\rbtree.obj nasmlib\hashtbl.obj \ nasmlib\raa.obj nasmlib\saa.obj \ diff --git a/Mkfiles/openwcom.mak b/Mkfiles/openwcom.mak index eabbb7dc9..e733b2af4 100644 --- a/Mkfiles/openwcom.mak +++ b/Mkfiles/openwcom.mak @@ -92,10 +92,10 @@ LIBOBJ_COM = & nasmlib\alloc.obj nasmlib\asprintf.obj & nasmlib\crc32b.obj nasmlib\crc64.obj nasmlib\md5c.obj & nasmlib\string.obj nasmlib\nctype.obj & - nasmlib\file.obj nasmlib\mmap.obj nasmlib\ilog2.obj & - nasmlib\realpath.obj nasmlib\path.obj & - nasmlib\filename.obj nasmlib\rlimit.obj & - nasmlib\numstr.obj & + nasmlib\file.obj nasmlib\fileio.obj nasmlib\mmap.obj & + nasmlib\realpath.obj nasmlib\path.obj nasmlib\filename.obj & + nasmlib\ilog2.obj nasmlib\numstr.obj & + nasmlib\rlimit.obj & nasmlib\zerobuf.obj nasmlib\bsi.obj & nasmlib\rbtree.obj nasmlib\hashtbl.obj & nasmlib\raa.obj nasmlib\saa.obj & diff --git a/nasmlib/file.c b/nasmlib/file.c index 718d51615..dd45f1bc4 100644 --- a/nasmlib/file.c +++ b/nasmlib/file.c @@ -1,77 +1,40 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* Copyright 1996-2017 The NASM Authors - All Rights Reserved */ -#include "file.h" +#include "compiler.h" +#include "nasmlib.h" +#include "error.h" -void nasm_read(void *ptr, size_t size, FILE *f) -{ - size_t n = fread(ptr, 1, size, f); - if (ferror(f)) { - nasm_fatal("unable to read input: %s", strerror(errno)); - } else if (n != size || feof(f)) { - nasm_fatal("fatal short read on input"); - } -} - -void nasm_write(const void *ptr, size_t size, FILE *f) -{ - size_t n = fwrite(ptr, 1, size, f); - if (n != size || ferror(f) || feof(f)) - nasm_fatal("unable to write output: %s", strerror(errno)); -} - -void fwriteint16_t(uint16_t data, FILE * fp) -{ - data = htole16(data); - nasm_write(&data, 2, fp); -} - -void fwriteint32_t(uint32_t data, FILE * fp) -{ - data = htole32(data); - nasm_write(&data, 4, fp); -} - -void fwriteint64_t(uint64_t data, FILE * fp) -{ - data = htole64(data); - nasm_write(&data, 8, fp); -} - -void fwriteaddr(uint64_t data, int size, FILE * fp) -{ - data = htole64(data); - nasm_write(&data, size, fp); -} - -void fwritezero(off_t bytes, FILE *fp) -{ - size_t blksize; - -#ifdef os_ftruncate - if (bytes >= BUFSIZ && !ferror(fp) && !feof(fp)) { - off_t pos = ftello(fp); - if (pos != (off_t)-1) { - off_t end = pos + bytes; - if (!fflush(fp) && !os_ftruncate(fileno(fp), end)) { - fseeko(fp, 0, SEEK_END); - pos = ftello(fp); - if (pos != (off_t)-1) - bytes = end - pos; /* This SHOULD be zero */ - } - } - } +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_IO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_MMAN_H +# include #endif - while (bytes > 0) { - blksize = (bytes < ZERO_BUF_SIZE) ? bytes : ZERO_BUF_SIZE; +#ifndef R_OK +# define R_OK 4 /* Classic Unix constant, same on Windows */ +#endif - nasm_write(zero_buffer, blksize, fp); - bytes -= blksize; - } -} - -#ifdef _WIN32 +#ifdef S_ISREG +/* all good */ +#elif defined(HAVE_S_ISREG) +/* exists, but not a macro */ +# define S_ISREG S_ISREG +#elif defined(S_IFMT) && defined(S_IFREG) +# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#elif defined(_S_IFMT) && defined(_S_IFREG) +# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif /* * On Windows, we want to use _wfopen(), as fopen() has a much smaller limit @@ -83,8 +46,13 @@ void fwritezero(off_t bytes, FILE *fp) * apparently Windows 10 contains a registry option to override this * limit anyway... but only for the wide character interfaces. */ +#ifdef _WIN32 +#include -os_filename os_mangle_filename(const char *filename) +typedef wchar_t *os_filename; +typedef wchar_t os_fopenflag; + +static os_filename os_mangle_filename(const char *filename) { size_t wclen; wchar_t *buf; @@ -105,6 +73,131 @@ os_filename os_mangle_filename(const char *filename) return buf; } +static inline void os_free_filename(os_filename filename) +{ + nasm_free(filename); +} + +# define os_fopen _wfopen +# define os_access _waccess + +/* + * On Win32/64, we have to use the _wstati64() function. Note that + * we can't use _wstat64() without depending on a needlessly new + * version os MSVCRT. + */ + +typedef struct _stati64 os_struct_stat; + +# define os_stat _wstati64 +# define os_fstat _fstati64 + +static inline void os_set_binary_mode(FILE *f) { + int ret = _setmode(_fileno(f), _O_BINARY); + + if (ret == -1) { + nasm_fatalf(ERR_NOFILE, "unable to set file mode to binary: %s", + strerror(errno)); + } +} + +#else /* not _WIN32 */ + +typedef const char *os_filename; +typedef char os_fopenflag; + +static inline os_filename os_mangle_filename(const char *filename) +{ + return filename; +} +static inline void os_free_filename(os_filename filename) +{ + (void)filename; /* Nothing to do */ +} + +static inline void os_set_binary_mode(FILE *f) { + (void)f; +} + +# define os_fopen fopen + +#if defined(HAVE_FACCESSAT) && defined(AT_EACCESS) +static inline int os_access(os_filename pathname, int mode) +{ + return faccessat(AT_FDCWD, pathname, mode, AT_EACCESS); +} +# define os_access os_access +#elif defined(HAVE_ACCESS) +# define os_access access +#endif + +#ifdef HAVE_STRUCT_STAT +typedef struct stat os_struct_stat; +# ifdef HAVE_STAT +# define os_stat stat +# endif +# ifdef HAVE_FSTAT +# define os_fstat fstat +# endif +#else +struct dummy_struct_stat { + int st_mode; + int st_size; +}; +typedef struct dummy_struct_stat os_struct_stat; +#endif + +#endif /* Not _WIN32 */ + +#ifdef fileno +/* all good */ +#elif defined(HAVE_FILENO) +/* exists, but not a macro */ +# define fileno fileno +#elif defined(_fileno) || defined(HAVE__FILENO) +# define fileno _fileno +#endif + +#ifndef S_ISREG +# undef os_stat +# undef os_fstat +#endif + +/* Disable these functions if they don't support something we need */ +#ifndef fileno +# undef os_fstat +# undef os_ftruncate +# undef HAVE_MMAP +#endif + +/* + * If we don't have functional versions of these functions, + * stub them out so we don't need so many #ifndefs + */ +#ifndef os_stat +static inline int os_stat(os_filename osfname, os_struct_stat *st) +{ + (void)osfname; + (void)st; + return -1; +} +#endif + +#ifndef os_fstat +static inline int os_fstat(int fd, os_struct_stat *st) +{ + (void)fd; + (void)st; + return -1; +} +#endif + +#ifndef S_ISREG +static inline bool S_ISREG(int m) +{ + (void)m; + return false; +} #endif void nasm_set_binary_mode(FILE *f) diff --git a/nasmlib/file.h b/nasmlib/file.h deleted file mode 100644 index d7d5ad2f4..000000000 --- a/nasmlib/file.h +++ /dev/null @@ -1,204 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ -/* Copyright 1996-2022 The NASM Authors - All Rights Reserved */ - -#ifndef NASMLIB_FILE_H -#define NASMLIB_FILE_H - -#include "compiler.h" -#include "nasmlib.h" -#include "error.h" - -#include - -#ifdef HAVE_FCNTL_H -# include -#endif -#ifdef HAVE_SYS_TYPES_H -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef HAVE_IO_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif -#ifdef HAVE_SYS_MMAN_H -# include -#endif - -#ifndef R_OK -# define R_OK 4 /* Classic Unix constant, same on Windows */ -#endif - -/* Can we adjust the file size without actually writing all the bytes? */ -#ifdef HAVE__CHSIZE_S -# define os_ftruncate(fd,size) _chsize_s(fd,size) -#elif defined(HAVE__CHSIZE) -# define os_ftruncate(fd,size) _chsize(fd,size) -#elif defined(HAVE_FTRUNCATE) -# define os_ftruncate(fd,size) ftruncate(fd,size) -#endif - -/* - * On Windows, we want to use _wfopen(), as fopen() has a much smaller limit - * on the path length that it supports. Furthermore, we want to prefix the - * path name with \\?\ in order to let the Windows kernel know that - * we are not limited to PATH_MAX characters. Thus, we wrap all the functions - * which take filenames... - */ -#ifdef _WIN32 -# include -typedef wchar_t *os_filename; -typedef wchar_t os_fopenflag; - -os_filename os_mangle_filename(const char *filename); -static inline void os_free_filename(os_filename filename) -{ - nasm_free(filename); -} - -# define os_fopen _wfopen -# define os_access _waccess - -/* - * On Win32/64, we have to use the _wstati64() function. Note that - * we can't use _wstat64() without depending on a needlessly new - * version os MSVCRT. - */ - -typedef struct _stati64 os_struct_stat; - -# define os_stat _wstati64 -# define os_fstat _fstati64 - -/* - * On Win32/64, freopen() and _wfreopen() fails when the mode string - * is with the letter 'b' that represents to set binary mode. On - * POSIX operating systems, the 'b' is ignored, without failure. - */ - -#include -#include - -static inline void os_set_binary_mode(FILE *f) { - int ret = _setmode(_fileno(f), _O_BINARY); - - if (ret == -1) { - nasm_fatalf(ERR_NOFILE, "unable to open file: %s", - strerror(errno)); - } -} - -#else /* not _WIN32 */ - -typedef const char *os_filename; -typedef char os_fopenflag; - -static inline os_filename os_mangle_filename(const char *filename) -{ - return filename; -} -static inline void os_free_filename(os_filename filename) -{ - (void)filename; /* Nothing to do */ -} - -static inline void os_set_binary_mode(FILE *f) { - (void)f; -} - -# define os_fopen fopen - -#if defined(HAVE_FACCESSAT) && defined(AT_EACCESS) -static inline int os_access(os_filename pathname, int mode) -{ - return faccessat(AT_FDCWD, pathname, mode, AT_EACCESS); -} -# define os_access os_access -#elif defined(HAVE_ACCESS) -# define os_access access -#endif - -#ifdef HAVE_STRUCT_STAT -typedef struct stat os_struct_stat; -# ifdef HAVE_STAT -# define os_stat stat -# endif -# ifdef HAVE_FSTAT -# define os_fstat fstat -# endif -#else -struct dummy_struct_stat { - int st_mode; - int st_size; -}; -typedef struct dummy_struct_stat os_struct_stat; -#endif - -#endif /* Not _WIN32 */ - -#ifdef S_ISREG -/* all good */ -#elif defined(HAVE_S_ISREG) -/* exists, but not a macro */ -# define S_ISREG S_ISREG -#elif defined(S_IFMT) && defined(S_IFREG) -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#elif defined(_S_IFMT) && defined(_S_IFREG) -# define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) -#endif - -#ifdef fileno -/* all good */ -#elif defined(HAVE_FILENO) -/* exists, but not a macro */ -# define fileno fileno -#elif defined(_fileno) || defined(HAVE__FILENO) -# define fileno _fileno -#endif - -#ifndef S_ISREG -# undef os_stat -# undef os_fstat -#endif - -/* Disable these functions if they don't support something we need */ -#ifndef fileno -# undef os_fstat -# undef os_ftruncate -# undef HAVE_MMAP -#endif - -/* - * If we don't have functional versions of these functions, - * stub them out so we don't need so many #ifndefs - */ -#ifndef os_stat -static inline int os_stat(os_filename osfname, os_struct_stat *st) -{ - (void)osfname; - (void)st; - return -1; -} -#endif - -#ifndef os_fstat -static inline int os_fstat(int fd, os_struct_stat *st) -{ - (void)fd; - (void)st; - return -1; -} -#endif - -#ifndef S_ISREG -static inline bool S_ISREG(int m) -{ - (void)m; - return false; -} -#endif - -#endif /* NASMLIB_FILE_H */ diff --git a/nasmlib/fileio.c b/nasmlib/fileio.c new file mode 100644 index 000000000..579b2863d --- /dev/null +++ b/nasmlib/fileio.c @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* Copyright 1996-2017 The NASM Authors - All Rights Reserved */ + +#include "compiler.h" +#include "nasmlib.h" +#include "error.h" + +void nasm_read(void *ptr, size_t size, FILE *f) +{ + size_t n = fread(ptr, 1, size, f); + if (ferror(f)) { + nasm_fatal("unable to read input: %s", strerror(errno)); + } else if (n != size || feof(f)) { + nasm_fatal("fatal short read on input"); + } +} + +void nasm_write(const void *ptr, size_t size, FILE *f) +{ + size_t n = fwrite(ptr, 1, size, f); + if (n != size || ferror(f) || feof(f)) + nasm_fatal("unable to write output: %s", strerror(errno)); +} + +void fwriteint16_t(uint16_t data, FILE * fp) +{ + data = htole16(data); + nasm_write(&data, 2, fp); +} + +void fwriteint32_t(uint32_t data, FILE * fp) +{ + data = htole32(data); + nasm_write(&data, 4, fp); +} + +void fwriteint64_t(uint64_t data, FILE * fp) +{ + data = htole64(data); + nasm_write(&data, 8, fp); +} + +void fwriteaddr(uint64_t data, int size, FILE * fp) +{ + data = htole64(data); + nasm_write(&data, size, fp); +} + +/* Can we adjust the file size without actually writing all the bytes? */ + +#ifdef HAVE_IO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifdef HAVE__CHSIZE_S +# define os_ftruncate(fd,size) _chsize_s(fd,size) +#elif defined(HAVE__CHSIZE) +# define os_ftruncate(fd,size) _chsize(fd,size) +#elif defined(HAVE_FTRUNCATE) +# define os_ftruncate(fd,size) ftruncate(fd,size) +#endif + +void fwritezero(off_t bytes, FILE *fp) +{ + size_t blksize; + +#ifdef os_ftruncate + if (bytes >= BUFSIZ && !ferror(fp) && !feof(fp)) { + off_t pos = ftello(fp); + if (pos != (off_t)-1) { + off_t end = pos + bytes; + if (!fflush(fp) && !os_ftruncate(fileno(fp), end)) { + fseeko(fp, 0, SEEK_END); + pos = ftello(fp); + if (pos != (off_t)-1) + bytes = end - pos; /* This SHOULD be zero */ + } + } + } +#endif + + while (bytes > 0) { + blksize = (bytes < ZERO_BUF_SIZE) ? bytes : ZERO_BUF_SIZE; + + nasm_write(zero_buffer, blksize, fp); + bytes -= blksize; + } +}