OSDN Git Service

Support GCC-9.x gratuitous dependency on ftruncate64() function.
authorKeith Marshall <keith@users.osdn.me>
Sat, 18 Jan 2020 12:28:21 +0000 (12:28 +0000)
committerKeith Marshall <keith@users.osdn.me>
Sat, 18 Jan 2020 12:28:21 +0000 (12:28 +0000)
mingwrt/ChangeLog
mingwrt/Makefile.in
mingwrt/include/unistd.h
mingwrt/mingwex/ftruncate.c [new file with mode: 0644]
mingwrt/msvcrt-xref/msvcrt.def.in

index 498182c..40cc39a 100644 (file)
@@ -1,5 +1,18 @@
 2020-01-17  Keith Marshall  <keith@users.osdn.me>
 
 2020-01-17  Keith Marshall  <keith@users.osdn.me>
 
+       Support GCC-9.x gratuitous dependency on ftruncate64() function.
+
+       * include/unistd.h (ftruncate64): Declare prototype; implement it...
+       * mingwex/ftruncate.c: ...in this new file; it will delegate to...
+       (_chsize_s): ...this MSVCRT.DLL function, if available.
+
+       * Makefile.in (libmingwex.a): Add dependency on...
+       (ftruncate.$OBJEXT): ...this.
+
+       * msvcrt-xref/msvcrt.def.in (_chsize_s): Require dlsym look-up.
+
+2020-01-17  Keith Marshall  <keith@users.osdn.me>
+
        Preserve order of tests for integrity of header files.
 
        * tests/Makefile.in: Explicitly sort $wildcard output, within...
        Preserve order of tests for integrity of header files.
 
        * tests/Makefile.in: Explicitly sort $wildcard output, within...
index 723c4b4..aa4a00f 100644 (file)
@@ -7,7 +7,7 @@ PACKAGE_TARNAME := @PACKAGE_TARNAME@
 PACKAGE_VERSION := @PACKAGE_VERSION@
 
 # Written by Keith Marshall <keithmarshall@users.sourceforge.net>
 PACKAGE_VERSION := @PACKAGE_VERSION@
 
 # Written by Keith Marshall <keithmarshall@users.sourceforge.net>
-# Copyright (C) 2014-2018, MinGW.org Project
+# Copyright (C) 2014-2020, MinGW.org Project
 #
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 #
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
@@ -459,12 +459,12 @@ libmingwex.a: $(LIBMINGWEX_MEMALIGN_OBJECTS)
 
 # Some additional miscellaneous functions, in libmingwex.a
 #
 
 # Some additional miscellaneous functions, in libmingwex.a
 #
+libmingwex.a: $(addsuffix .$(OBJEXT), ftruncate getdelim gettimeofday)
 libmingwex.a: $(addsuffix .$(OBJEXT), glob getopt basename dirname nsleep)
 libmingwex.a: $(addsuffix .$(OBJEXT), clockapi clockres clockset clocktime)
 libmingwex.a: $(addsuffix .$(OBJEXT), insque remque tdelete tfind tsearch twalk)
 libmingwex.a: $(addsuffix .$(OBJEXT), dirent wdirent dlfcn strerror_r strtok_r)
 libmingwex.a: $(addsuffix .$(OBJEXT), mkstemp mkdtemp cryptnam setenv)
 libmingwex.a: $(addsuffix .$(OBJEXT), glob getopt basename dirname nsleep)
 libmingwex.a: $(addsuffix .$(OBJEXT), clockapi clockres clockset clocktime)
 libmingwex.a: $(addsuffix .$(OBJEXT), insque remque tdelete tfind tsearch twalk)
 libmingwex.a: $(addsuffix .$(OBJEXT), dirent wdirent dlfcn strerror_r strtok_r)
 libmingwex.a: $(addsuffix .$(OBJEXT), mkstemp mkdtemp cryptnam setenv)
-libmingwex.a: $(addsuffix .$(OBJEXT), getdelim gettimeofday)
 
 vpath %.s ${mingwrt_srcdir}/mingwex
 vpath %.sx ${mingwrt_srcdir}/mingwex
 
 vpath %.s ${mingwrt_srcdir}/mingwex
 vpath %.sx ${mingwrt_srcdir}/mingwex
index 4080ab5..f6f7bd3 100644 (file)
@@ -11,7 +11,7 @@
  *   Ramiro Polla <ramiro@lisha.ufsc.br>
  *   Gregory McGarry  <gregorymcgarry@users.sourceforge.net>
  *   Keith Marshall  <keithmarshall@users.sourceforge.net>
  *   Ramiro Polla <ramiro@lisha.ufsc.br>
  *   Gregory McGarry  <gregorymcgarry@users.sourceforge.net>
  *   Keith Marshall  <keithmarshall@users.sourceforge.net>
- * Copyright (C) 1997, 1999, 2002-2004, 2007-2009, 2014-2017,
+ * Copyright (C) 1997, 1999, 2002-2004, 2007-2009, 2014-2017, 2020,
  *   MinGW.org Project.
  *
  *
  *   MinGW.org Project.
  *
  *
@@ -132,6 +132,15 @@ __CRT_INLINE __JMPSTUB__(( FUNCTION = ftruncate, DLLENTRY = _chsize ))
 int ftruncate( int __fd, off_t __length ){ return _chsize( __fd, __length ); }
 #endif
 
 int ftruncate( int __fd, off_t __length ){ return _chsize( __fd, __length ); }
 #endif
 
+/* Although non-standard, GCC's C++ library from GCC-9.x gratuitously
+ * assumes, and requires, this 64-bit off_t variant to be available; it
+ * could be emulated by Microsoft's _chsize_s() function, which is only
+ * supported from Vista onward; therefore, to ensure support on legacy
+ * platforms, we prefer our own libmingwex.a implementation, and so,
+ * we do not provide an inline implementation.
+ */
+int __cdecl ftruncate64( int, __off64_t );
+
 _END_C_DECLS
 
 #endif /* _POSIX_C_SOURCE */
 _END_C_DECLS
 
 #endif /* _POSIX_C_SOURCE */
diff --git a/mingwrt/mingwex/ftruncate.c b/mingwrt/mingwex/ftruncate.c
new file mode 100644 (file)
index 0000000..a5820be
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * ftruncate.c
+ *
+ * Implement a 64-bit file size capable ftruncate() function; GCC-9.x
+ * gratuitously assumes that this is available, via the ftruncate64()
+ * entry point.
+ *
+ * $Id$
+ *
+ * Written by Keith Marshall <keith@users.osdn.me>
+ * Copyright (C) 2020, MinGW.org Project
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <dlfcn.h>
+#include <unistd.h>
+#include <winbase.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+/* The following in-line function is provided to facilitate abnormal return
+ * from ftruncate64(), (in which case the return value is always -1), while
+ * setting the global errno indicator to an appropriate error code.
+ */
+static __inline__ __attribute__((__always_inline__))
+int errout( int error_code ){ errno = error_code; return -1L; }
+
+/* When running on Vista, or later, or for applications which have been
+ * linked against non-free MSVCR80.DLL, or later, we may be able to simply
+ * substitute a call to Microsoft's _chsize_s() function, (which behaves
+ * as a 64-bit variant of the universally available _chsize() function).
+ * On legacy Windows versions, which are unlikely to provide _chsize_s(),
+ * we need to provide our own fallback 64-bit chsize() implementation;
+ * this may be static, but cannot be inlined, because we need a physical
+ * entry point address to which execution may be redirected.
+ */
+static int mingw_chsize64_fallback( int fd, __off64_t offset )
+{
+  /* POSIX.1 requires the file pointer to be unchanged, as a consequence
+   * of calling ftruncate(), (and Microsoft's _chsize() functions do seem
+   * to satisfy this requirement); however, to mark a new end of file, we
+   * need move the file pointer to the new end of file offset, so we need
+   * to save the original pointer now, to restore later.
+   */
+  __off64_t cur_offset = _lseeki64( fd, 0LL, SEEK_CUR );
+
+  /* In the event that the new end of file offset requires the file to be
+   * extended beyond its current end of file offset, POSIX.1 also requires
+   * NUL byte padding to be written to the extended file space, (and again,
+   * Microsoft's _chsize() functions seem to do this); we may reposition
+   * the file pointer to its current end of file offset, in preparation
+   * for the possibility that we need to fulfil this requirement.
+   */
+  __off64_t end_offset = _lseeki64( fd, 0LL, SEEK_END );
+
+  /* We will eventually need to restore the original file pointer, AFTER
+   * we have evaluated the return status code, so we will need to save
+   * this.
+   */
+  int retval;
+
+  /* There are two possible options for repositioning the end of file
+   * pointer:
+   */
+  if( offset > end_offset )
+  {
+    /* In this case, the file is to be extended beyond its current
+     * end of file offset; initialize a NUL filled buffer, which we
+     * may then copy to the extended region of the file, to satisfy
+     * the POSIX.1 requirement that this region shall be NUL filled.
+     */
+    char padding[BUFSIZ];
+    memset( padding, 0, sizeof( padding ) );
+
+    /* Recompute the desired offset, relative to the current end of
+     * file, then repeatedly write copies of the NUL filled buffer,
+     * until the file space represented by this relative offset has
+     * been completely filled; (this results in advancement of the
+     * file pointer to the desired new end of file offset).
+     */
+    offset -= end_offset;
+    while( offset > (__off64_t)(sizeof( padding )) )
+      offset -= write( fd, padding, sizeof( padding ) );
+    write( fd, padding, offset );
+  }
+  else
+    /* In the alternative case, the new end of file pointer will lie
+     * within the space already occupied by the file; we may simply
+     * seek directly to the desired offset.
+     */
+    _lseeki64( fd, offset, SEEK_SET );
+
+  /* We have now adjusted the file pointer to be coincident with the
+   * desired new end of file offset; this is exactly what is required
+   * by the Windows API function, to mark the new end of file.
+   */
+  retval = SetEndOfFile( (void *)(_get_osfhandle( fd )) )
+    ? 0 : errout( EBADF );
+
+  /* Finally, we must restore the originally saved file pointer, before
+   * we return the status code from the ftruncate() operation.
+   */
+  _lseeki64( fd, cur_offset, SEEK_SET );
+  return retval;
+}
+
+/* Regardless of the platform version, Microsoft do not provide an
+ * implementation of ftruncate64(); all link-time references to this
+ * function will be resolved by this libmingwex.a implementation.
+ */
+int ftruncate64( int fd, __off64_t offset )
+{
+  /* The offset parameter MUST be positive valued; bail out if not.
+   */
+  if( 0LL > offset ) return errout( EINVAL );
+
+  /* For offsets which may be represented by a 32-bit integer, we
+   * may ALWAYS delegate this call to Microsoft's _chsize().
+   */
+  if( INT32_MAX >= offset ) return _chsize( fd, (off_t)(offset) );
+
+  { /* For offsets which cannot be represented within 32-bits, we
+     * MAY be able to delegate this call, (and also any subsequent
+     * calls), to Microsoft's _chsize_s(); set up a redirector to
+     * handle such delegation...
+     */
+    static int (*redirector_hook)( int, __off64_t ) = NULL;
+
+    /* ...initially checking for _chsize_s() availability...
+     */
+    if(  (redirector_hook == NULL)
+    &&  ((redirector_hook = dlsym( RTLD_DEFAULT, "_chsize_s" )) == NULL)  )
+
+      /* ...and setting up a suitable fallback if not...
+       */
+      redirector_hook = mingw_chsize64_fallback;
+
+    /* ...and ultimately, on initial selection, (and directly on
+     * all subsequent calls), hand off execution to the selected
+     * delegate function.
+     */
+    return redirector_hook( fd, offset );
+  }
+}
+
+/* $RCSfile$: end of file */
index 0061bb8..bf5f808 100644 (file)
@@ -5,7 +5,7 @@
  * definition files, supporting multiple OS platform versions.
  *
  * Compiled by Keith Marshall <keithmarshall@users.sourceforge.net>
  * definition files, supporting multiple OS platform versions.
  *
  * Compiled by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2014, 2016, 2018, MinGW.org Project.
+ * Copyright (C) 2014, 2016, 2018, 2020, MinGW.org Project.
  *
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  *
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -656,7 +656,7 @@ _chmod
 _chsize
 #if __MSVCRT_VERSION__ >= 0x0600UL
 # if __MSVCRT_VERSION__ < 0x07000000UL || __MSVCRT_VERSION__ >= 0x08000000UL
 _chsize
 #if __MSVCRT_VERSION__ >= 0x0600UL
 # if __MSVCRT_VERSION__ < 0x07000000UL || __MSVCRT_VERSION__ >= 0x08000000UL
-_chsize_s
+__MINGW_DLSYM(_chsize_s)
 # endif
 #endif
 #if __MSVCRT_VERSION__ >= 0x0600UL
 # endif
 #endif
 #if __MSVCRT_VERSION__ >= 0x0600UL