]> Savannah Git Hosting - gnulib.git/commitdiff
truncate: New module.
authorBruno Haible <bruno@clisp.org>
Sat, 13 May 2017 00:54:37 +0000 (02:54 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 13 May 2017 00:54:37 +0000 (02:54 +0200)
* 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.

ChangeLog
doc/posix-functions/truncate.texi
lib/truncate.c [new file with mode: 0644]
lib/unistd.in.h
m4/truncate.m4 [new file with mode: 0644]
m4/unistd_h.m4
modules/truncate [new file with mode: 0644]
modules/unistd
tests/test-unistd-c++.cc

index 72a0560baf754dbe29c037cf2f7dc47386eebc63..c8556f38abd00ab8b2e5d3f2aa6574092a03cd03 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2017-05-13  Bruno Haible  <bruno@clisp.org>
+
+       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  <bruno@clisp.org>
 
        windows-stat-timespec: New module.
index a21f09893edd6c822876cc5eda143d1bd3e484e3..b52f2b37f7a64a1ac6dbff86e83b3bc04fb907da 100644 (file)
@@ -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 (file)
index 0000000..8ca5c0c
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+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;
+}
index d9f741fea55bbf7b1e62f12899befaa0d2a78b47..8222fd252c5672ae5c0a54c955b457ab11b09161 100644 (file)
@@ -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
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html>.  */
+# 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 (file)
index 0000000..9d348eb
--- /dev/null
@@ -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 <http://mingw-w64.sourcearchive.com/documentation/2.0-1/ftruncate64_8c_source.html>).
+          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], [:])
index 25aef19ec9db7b3ce662ca3436250f79cabb168c..cc44677d9eb20825cc7506ff9494f7c819b2e139 100644 (file)
@@ -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 (file)
index 0000000..e141b1a
--- /dev/null
@@ -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:
+<unistd.h>
+
+License:
+GPL
+
+Maintainer:
+all
index 8af837ca59eb51a5dba3a2fff5955e2dc3825858..c258110785b6c19ed178d9ddcd8a5bdddf6a4527 100644 (file)
@@ -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' \
index a19acc899c149ccd3351271b88bad2bead18f521..14cdb4ab92958971ea162c1a7d2cc0e5a9c2e2bc 100644 (file)
@@ -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));