diff --git a/configure.in b/configure.in index e762777f..98e151ca 100644 --- a/configure.in +++ b/configure.in @@ -111,6 +111,9 @@ AC_CHECK_HEADERS(strings.h) dnl Look for AC_HEADER_STDBOOL +dnl Look for +AC_CHECK_HEADERS(io.h) + dnl Look for AC_CHECK_HEADERS(unistd.h) @@ -135,6 +138,11 @@ AC_CHECK_FUNCS(canonicalize_file_name) AC_CHECK_FUNCS(_fullpath) AC_CHECK_FUNCS(pathconf) +AC_TYPE_OFF_T +AC_FUNC_FSEEKO +AC_CHECK_FUNCS([ftruncate _chsize _chsize_s]) +AC_CHECK_FUNCS([fileno]) + PA_HAVE_FUNC(__builtin_ctz, (0U)) PA_HAVE_FUNC(__builtin_ctzl, (0UL)) PA_HAVE_FUNC(__builtin_ctzll, (0ULL)) diff --git a/nasmlib.c b/nasmlib.c index 49f1e470..eb0217d1 100644 --- a/nasmlib.c +++ b/nasmlib.c @@ -165,7 +165,7 @@ no_return nasm_assert_failed(const char *file, int line, const char *msg) void nasm_write(const void *ptr, size_t size, FILE *f) { size_t n = fwrite(ptr, 1, size, f); - if (n != size) + if (n != size || ferror(f) || feof(f)) nasm_error(ERR_FATAL, "unable to write output: %s", strerror(errno)); } @@ -459,10 +459,37 @@ void fwriteaddr(uint64_t data, int size, FILE * fp) #endif +#ifndef HAVE_FSEEKO +# define fseeko fseek +# define ftello ftell +#endif + +#ifdef HAVE_FILENO /* Useless without fileno() */ +# ifdef HAVE__CHSIZE_S +# define nasm_ftruncate(fd,size) _chsize_s(fd,size) +# elif defined(HAVE__CHSIZE) +# define nasm_ftruncate(fd,size) _chsize(fd,size) +# elif defined(HAVE_FTRUNCATE) +# define nasm_ftruncate(fd,size) ftruncate(fd,size) +# endif +#endif + void fwritezero(size_t bytes, FILE *fp) { size_t blksize; +#ifdef nasm_ftruncate + if (bytes >= BUFSIZ && !ferror(fp) && !feof(fp)) { + off_t pos = ftello(fp); + if (pos >= 0) { + if (!fflush(fp) && + !nasm_ftruncate(fileno(fp), pos + bytes) && + !fseeko(fp, pos+bytes, SEEK_SET)) + return; + } + } +#endif + while (bytes) { blksize = (bytes < ZERO_BUF_SIZE) ? bytes : ZERO_BUF_SIZE; diff --git a/nasmlib.h b/nasmlib.h index 96c488a4..534324db 100644 --- a/nasmlib.h +++ b/nasmlib.h @@ -44,7 +44,13 @@ #include #include #ifdef HAVE_STRINGS_H -#include +# include +#endif +#ifdef HAVE_IO_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include #endif /*