nasmlib: allow writing of sparse files

On systems that support it, allow the writing of sparse files.
This can be useful for some file formats (like binary, or ELF if the
alignments are very large) that can contain large amounts of zeroes.

This is not inherently portable code, so condition it on certain known
systems.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
H. Peter Anvin 2016-02-18 14:24:40 -08:00
parent 28ec7d1ddf
commit e65e81b172
3 changed files with 43 additions and 2 deletions

View File

@ -111,6 +111,9 @@ AC_CHECK_HEADERS(strings.h)
dnl Look for <stdbool.h>
AC_HEADER_STDBOOL
dnl Look for <io.h>
AC_CHECK_HEADERS(io.h)
dnl Look for <unistd.h>
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))

View File

@ -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;

View File

@ -44,7 +44,13 @@
#include <stdio.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
# include <strings.h>
#endif
#ifdef HAVE_IO_H
# include <io.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
/*