From: Bruno Haible Date: Sat, 13 May 2017 00:54:37 +0000 (+0200) Subject: truncate: New module. X-Git-Tag: v1.0~6161 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=f4d71054e7f7c36adf8fb4c3b953d725e9f9408d;p=gnulib.git truncate: New module. * lib/unistd.in.h (truncate): New declaration. * lib/truncate.c: New file. * m4/truncate.m4: New file. * m4/unistd_h.m4 (gl_UNISTD_H): Test whether 'truncate' is declared. (gl_UNISTD_H_DEFAULTS): Initialize GNULIB_TRUNCATE, HAVE_TRUNCATE, REPLACE_TRUNCATE. * modules/unistd (Makefile.am): Substitute GNULIB_TRUNCATE, HAVE_TRUNCATE, REPLACE_TRUNCATE. * modules/truncate: New file. * tests/test-unistd-c++.cc (truncate): Test signature. * doc/posix-functions/truncate.texi: Mention the new module. --- diff --git a/ChangeLog b/ChangeLog index 72a0560baf..c8556f38ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2017-05-13 Bruno Haible + + truncate: New module. + * lib/unistd.in.h (truncate): New declaration. + * lib/truncate.c: New file. + * m4/truncate.m4: New file. + * m4/unistd_h.m4 (gl_UNISTD_H): Test whether 'truncate' is declared. + (gl_UNISTD_H_DEFAULTS): Initialize GNULIB_TRUNCATE, HAVE_TRUNCATE, + REPLACE_TRUNCATE. + * modules/unistd (Makefile.am): Substitute GNULIB_TRUNCATE, + HAVE_TRUNCATE, REPLACE_TRUNCATE. + * modules/truncate: New file. + * tests/test-unistd-c++.cc (truncate): Test signature. + * doc/posix-functions/truncate.texi: Mention the new module. + 2017-05-13 Bruno Haible windows-stat-timespec: New module. diff --git a/doc/posix-functions/truncate.texi b/doc/posix-functions/truncate.texi index a21f09893e..b52f2b37f7 100644 --- a/doc/posix-functions/truncate.texi +++ b/doc/posix-functions/truncate.texi @@ -4,14 +4,10 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/truncate.html} -Gnulib module: --- +Gnulib module: truncate Portability problems fixed by Gnulib: @itemize -@end itemize - -Portability problems not fixed by Gnulib: -@itemize @item This function is missing on some platforms: mingw, MSVC 9. @@ -20,3 +16,7 @@ On platforms where @code{off_t} is a 32-bit type, this function is not applicable to arbitrary lengths for files larger than 2 GB. The fix is to use the @code{AC_SYS_LARGEFILE} macro. @end itemize + +Portability problems not fixed by Gnulib: +@itemize +@end itemize diff --git a/lib/truncate.c b/lib/truncate.c new file mode 100644 index 0000000000..8ca5c0c52c --- /dev/null +++ b/lib/truncate.c @@ -0,0 +1,51 @@ +/* truncate emulations for native Windows. + Copyright (C) 2017 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, see . */ + +#include + +/* Specification. */ +#include + +#include +#include + +int +truncate (const char *filename, off_t length) +{ + int fd; + + if (length == 0) + { + fd = open (filename, O_WRONLY | O_TRUNC); + if (fd < 0) + return -1; + } + else + { + fd = open (filename, O_WRONLY); + if (fd < 0) + return -1; + if (ftruncate (fd, length) < 0) + { + int saved_errno = errno; + close (fd); + errno = saved_errno; + return -1; + } + } + close (fd); + return 0; +} diff --git a/lib/unistd.in.h b/lib/unistd.in.h index d9f741fea5..8222fd252c 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -1457,6 +1457,36 @@ _GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - " #endif +#if @GNULIB_TRUNCATE@ +/* Change the size of the file designated by FILENAME to become equal to LENGTH. + Return 0 if successful, otherwise -1 and errno set. + See the POSIX:2008 specification + . */ +# if @REPLACE_TRUNCATE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef truncate +# define truncate rpl_truncate +# endif +_GL_FUNCDECL_RPL (truncate, int, (const char *filename, off_t length) + _GL_ARG_NONNULL ((1))); +_GL_CXXALIAS_RPL (truncate, int, (const char *filename, off_t length)); +# else +# if !@HAVE_TRUNCATE@ +_GL_FUNCDECL_SYS (truncate, int, (const char *filename, off_t length) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (truncate, int, (const char *filename, off_t length)); +# endif +_GL_CXXALIASWARN (truncate); +#elif defined GNULIB_POSIXCHECK +# undef truncate +# if HAVE_RAW_DECL_TRUNCATE +_GL_WARN_ON_USE (truncate, "truncate is unportable - " + "use gnulib module truncate for portability"); +# endif +#endif + + #if @GNULIB_TTYNAME_R@ /* Store at most BUFLEN characters of the pathname of the terminal FD is open on in BUF. Return 0 on success, otherwise an error number. */ diff --git a/m4/truncate.m4 b/m4/truncate.m4 new file mode 100644 index 0000000000..9d348ebfc3 --- /dev/null +++ b/m4/truncate.m4 @@ -0,0 +1,33 @@ +# truncate.m4 serial 1 -*- Autoconf -*- +dnl Copyright (C) 2017 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_TRUNCATE], +[ + AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([truncate]) + if test $ac_cv_func_truncate = yes; then + m4_ifdef([gl_LARGEFILE], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + mingw*) + dnl Native Windows, and Large File Support is requested. + dnl The mingw64 truncate64() function is based on ftruncate64(), + dnl which is unreliable (it may delete the file, see + dnl ). + dnl Use gnulib's ftruncate() and truncate() implementation instead. + REPLACE_TRUNCATE=1 + ;; + esac + ], [ + : + ]) + else + HAVE_TRUNCATE=0 + fi +]) + +# Prerequisites of lib/truncate.c. +AC_DEFUN([gl_PREREQ_TRUNCATE], [:]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 25aef19ec9..cc44677d9e 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 69 +# unistd_h.m4 serial 70 dnl Copyright (C) 2006-2017 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -46,8 +46,8 @@ AC_DEFUN([gl_UNISTD_H], gethostname getlogin getlogin_r getpagesize getusershell setusershell endusershell group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite - readlink readlinkat rmdir sethostname sleep symlink symlinkat ttyname_r - unlink unlinkat usleep]) + readlink readlinkat rmdir sethostname sleep symlink symlinkat + truncate ttyname_r unlink unlinkat usleep]) ]) AC_DEFUN([gl_UNISTD_MODULE_INDICATOR], @@ -102,6 +102,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], GNULIB_SLEEP=0; AC_SUBST([GNULIB_SLEEP]) GNULIB_SYMLINK=0; AC_SUBST([GNULIB_SYMLINK]) GNULIB_SYMLINKAT=0; AC_SUBST([GNULIB_SYMLINKAT]) + GNULIB_TRUNCATE=0; AC_SUBST([GNULIB_TRUNCATE]) GNULIB_TTYNAME_R=0; AC_SUBST([GNULIB_TTYNAME_R]) GNULIB_UNISTD_H_NONBLOCKING=0; AC_SUBST([GNULIB_UNISTD_H_NONBLOCKING]) GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE]) @@ -139,6 +140,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP]) HAVE_SYMLINK=1; AC_SUBST([HAVE_SYMLINK]) HAVE_SYMLINKAT=1; AC_SUBST([HAVE_SYMLINKAT]) + HAVE_TRUNCATE=1; AC_SUBST([HAVE_TRUNCATE]) HAVE_UNLINKAT=1; AC_SUBST([HAVE_UNLINKAT]) HAVE_USLEEP=1; AC_SUBST([HAVE_USLEEP]) HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON]) @@ -179,6 +181,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], REPLACE_SLEEP=0; AC_SUBST([REPLACE_SLEEP]) REPLACE_SYMLINK=0; AC_SUBST([REPLACE_SYMLINK]) REPLACE_SYMLINKAT=0; AC_SUBST([REPLACE_SYMLINKAT]) + REPLACE_TRUNCATE=0; AC_SUBST([REPLACE_TRUNCATE]) REPLACE_TTYNAME_R=0; AC_SUBST([REPLACE_TTYNAME_R]) REPLACE_UNLINK=0; AC_SUBST([REPLACE_UNLINK]) REPLACE_UNLINKAT=0; AC_SUBST([REPLACE_UNLINKAT]) diff --git a/modules/truncate b/modules/truncate new file mode 100644 index 0000000000..e141b1a6b5 --- /dev/null +++ b/modules/truncate @@ -0,0 +1,32 @@ +Description: +truncate() function: truncate a file to a specified length. + +Files: +lib/truncate.c +m4/truncate.m4 + +Depends-on: +unistd +sys_types +largefile +open [test $HAVE_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1] +ftruncate [test $HAVE_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1] + +configure.ac: +gl_FUNC_TRUNCATE +if test $HAVE_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1; then + AC_LIBOBJ([truncate]) + gl_PREREQ_TRUNCATE +fi +gl_UNISTD_MODULE_INDICATOR([truncate]) + +Makefile.am: + +Include: + + +License: +GPL + +Maintainer: +all diff --git a/modules/unistd b/modules/unistd index 8af837ca59..c258110785 100644 --- a/modules/unistd +++ b/modules/unistd @@ -77,6 +77,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's/@''GNULIB_SLEEP''@/$(GNULIB_SLEEP)/g' \ -e 's/@''GNULIB_SYMLINK''@/$(GNULIB_SYMLINK)/g' \ -e 's/@''GNULIB_SYMLINKAT''@/$(GNULIB_SYMLINKAT)/g' \ + -e 's/@''GNULIB_TRUNCATE''@/$(GNULIB_TRUNCATE)/g' \ -e 's/@''GNULIB_TTYNAME_R''@/$(GNULIB_TTYNAME_R)/g' \ -e 's/@''GNULIB_UNISTD_H_GETOPT''@/0$(GNULIB_${gl_include_guard_prefix}_UNISTD_H_GETOPT)/g' \ -e 's/@''GNULIB_UNISTD_H_NONBLOCKING''@/$(GNULIB_UNISTD_H_NONBLOCKING)/g' \ @@ -114,6 +115,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \ -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \ -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \ + -e 's|@''HAVE_TRUNCATE''@|$(HAVE_TRUNCATE)|g' \ -e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \ -e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \ -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \ @@ -155,6 +157,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \ -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \ -e 's|@''REPLACE_SYMLINKAT''@|$(REPLACE_SYMLINKAT)|g' \ + -e 's|@''REPLACE_TRUNCATE''@|$(REPLACE_TRUNCATE)|g' \ -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \ -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \ -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \ diff --git a/tests/test-unistd-c++.cc b/tests/test-unistd-c++.cc index a19acc899c..14cdb4ab92 100644 --- a/tests/test-unistd-c++.cc +++ b/tests/test-unistd-c++.cc @@ -200,6 +200,10 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::symlinkat, int, (char const *, int, char const *)); #endif +#if GNULIB_TEST_TRUNCATE +SIGNATURE_CHECK (GNULIB_NAMESPACE::truncate, int, (const char *, off_t)); +#endif + #if GNULIB_TEST_TTYNAME_R SIGNATURE_CHECK (GNULIB_NAMESPACE::ttyname_r, int, (int fd, char *buf, size_t buflen));