mirror of
https://github.com/netwide-assembler/nasm
synced 2026-08-26 16:23:04 -04:00
nasmlib: split file.c into file.c and fileio.c; remove file.h
file.h was only included from file.c; combine the two and declare functions not used anywhere else as static. Split out the checking I/O routines into a separate routine fileio.c as they are (mostly) not host operating system specific, whereas file.c is mostly host operating system generalization code. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
parent
5dfcfc8cab
commit
795daf3d2d
6 changed files with 264 additions and 284 deletions
229
nasmlib/file.c
229
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 <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_IO_H
|
||||
# include <io.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#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 <wchar.h>
|
||||
|
||||
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)
|
||||
|
|
|
|||
204
nasmlib/file.h
204
nasmlib/file.h
|
|
@ -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 <errno.h>
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_IO_H
|
||||
# include <io.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#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 <wchar.h>
|
||||
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 <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
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 */
|
||||
91
nasmlib/fileio.c
Normal file
91
nasmlib/fileio.c
Normal file
|
|
@ -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 <io.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue