From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-3.7 required=3.0 tests=AWL,BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL, SPF_HELO_PASS,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 2F5051F4B4 for ; Tue, 5 Jan 2021 07:24:09 +0000 (UTC) Received: from localhost ([::1]:47074 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwghL-0000Oj-J1 for normalperson@yhbt.net; Tue, 05 Jan 2021 02:24:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:33278) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwghE-0000OE-3y for bug-gnulib@gnu.org; Tue, 05 Jan 2021 02:24:00 -0500 Received: from mo4-p00-ob.smtp.rzone.de ([85.215.255.23]:18949) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwghB-00089N-4v for bug-gnulib@gnu.org; Tue, 05 Jan 2021 02:23:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1609831434; s=strato-dkim-0002; d=clisp.org; h=Message-ID:Date:Subject:To:From:From:Subject:Sender; bh=rI/PHKwRxMwouJR/Jqwm3aQ8ixNf5RgQtzeMIn337cM=; b=K9dKK+tDk/VetAG5qJPyUAmhrfaA2YCfnRksIsv40p2f+B8Slb4FNUwF3G3QFhqtU7 k2ZskJ+YBWJQlyFgubpeBNQw4FcHMI98XPMXBMiNmmnhPE7YkD0v+C6CeDIfvmzABIvb 3CxOhl/rlIHqLNjNV3fWkjrNTa7dl4Fq6xosT4cEakdegkZssbdF322q1LUi8CyoU4iD qwC3qQJTz+d0rk5Z9qxTnC6idPFSkrXJgecz8CIuNsA/ojcv3XP9M+hBTcbHv+nz9aak PH8TvSsug+FtCX9s/QVQ/5LkI4vunjBo5dNdV3Go5vtpJIWPg820pEWvnfKuD4VY6nrL 6SRA== X-RZG-AUTH: ":Ln4Re0+Ic/6oZXR1YgKryK8brlshOcZlIWs+iCP5vnk6shH+AHjwLuWOHqf3yZdW" X-RZG-CLASS-ID: mo00 Received: from bruno.haible.de by smtp.strato.de (RZmta 47.10.7 DYNA|AUTH) with ESMTPSA id e012d5x057Nsk8Z (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (curve X9_62_prime256v1 with 256 ECDH bits, eq. 3072 bits RSA)) (Client did not present a certificate); Tue, 5 Jan 2021 08:23:54 +0100 (CET) From: Bruno Haible To: bug-gnulib@gnu.org Subject: truncate: Work around trailing slash bug in truncate() on AIX Date: Tue, 05 Jan 2021 08:23:53 +0100 Message-ID: <229978919.4vjs2AzNYo@omega> User-Agent: KMail/5.1.3 (Linux/4.4.0-197-generic; KDE/5.18.0; x86_64; ; ) MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Received-SPF: none client-ip=85.215.255.23; envelope-from=bruno@clisp.org; helo=mo4-p00-ob.smtp.rzone.de X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_PASS=-0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: bug-gnulib@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Gnulib discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnulib-bounces+normalperson=yhbt.net@gnu.org Sender: "bug-gnulib" On AIX 7.2, I see this test failure: FAIL: test-truncate =================== ../../gltests/test-truncate.c:95: assertion 'truncate (BASE "file/", 0) == -1' failed FAIL test-truncate (exit status: 134) Yet another function which need a trailing slash workaround. This patch fixes it. Here, the usual idiom with '#undef truncate' does not work, because AIX does '#define truncate truncate64' and we really need to call truncate64 not the truncate function which takes only a 32-bit offset. 2021-01-05 Bruno Haible truncate: Work around trailing slash bug in truncate() on AIX 7.2. * m4/truncate.m4 (gl_FUNC_TRUNCATE): Add a test whether truncate rejects trailing slashes. Set REPLACE_TRUNCATE and define TRUNCATE_TRAILING_SLASH_BUG if not. * lib/truncate.c (orig_truncate): New function. (truncate): Add alternative implementation when TRUNCATE_TRAILING_SLASH_BUG is defined. * modules/truncate (Depends-on): Add sys_stat, stat. diff --git a/lib/truncate.c b/lib/truncate.c index 143edf1..ec375d6 100644 --- a/lib/truncate.c +++ b/lib/truncate.c @@ -14,6 +14,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, see . */ +/* If the user's config.h happens to include , let it include only + the system's here, so that orig_faccessat doesn't recurse to + rpl_faccessat. */ +#define _GL_INCLUDING_UNISTD_H #include /* Specification. */ @@ -21,10 +25,38 @@ #include #include +#include +#include +#undef _GL_INCLUDING_UNISTD_H + +#if TRUNCATE_TRAILING_SLASH_BUG +static int +orig_truncate (const char *filename, off_t length) +{ + return truncate (filename, length); +} +#endif + +/* Write "unistd.h" here, not , otherwise OSF/1 5.1 DTK cc + eliminates this include because of the preliminary #include + above. */ +#include "unistd.h" int truncate (const char *filename, off_t length) { +#if TRUNCATE_TRAILING_SLASH_BUG + /* Use the original truncate(), but correct the trailing slash handling. */ + size_t len = strlen (filename); + if (len && filename[len - 1] == '/') + { + struct stat st; + if (stat (filename, &st) == 0) + errno = (S_ISDIR (st.st_mode) ? EISDIR : ENOTDIR); + return -1; + } + return orig_truncate (filename, length); +#else int fd; if (length == 0) @@ -48,4 +80,5 @@ truncate (const char *filename, off_t length) } close (fd); return 0; +#endif } diff --git a/m4/truncate.m4 b/m4/truncate.m4 index 1751a50..737e47f 100644 --- a/m4/truncate.m4 +++ b/m4/truncate.m4 @@ -1,4 +1,4 @@ -# truncate.m4 serial 2 -*- Autoconf -*- +# truncate.m4 serial 3 -*- Autoconf -*- dnl Copyright (C) 2017-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -7,6 +7,8 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_TRUNCATE], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_FUNCS_ONCE([truncate]) dnl AC_CHECK_FUNC is not enough here, because when compiling for Android 4.4 dnl or older with _FILE_OFFSET_BITS=64, truncate() is not declared. There @@ -15,7 +17,6 @@ AC_DEFUN([gl_FUNC_TRUNCATE], AC_CHECK_DECL([truncate], , , [[#include ]]) if test $ac_cv_have_decl_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. @@ -29,6 +30,45 @@ AC_DEFUN([gl_FUNC_TRUNCATE], ], [ : ]) + if test $REPLACE_TRUNCATE = 0; then + dnl Check for AIX 7.2 bug with trailing slash. + AC_CACHE_CHECK([whether truncate rejects trailing slashes], + [gl_cv_func_truncate_works], + [echo foo > conftest.tmp + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + ]], + [[int result = 0; + if (!truncate ("conftest.tmp/", 2)) + result |= 1; + return result; + ]]) + ], + [gl_cv_func_truncate_works=yes], + [gl_cv_func_truncate_works=no], + [case "$host_os" in + # Guess yes on Linux systems. + linux-* | linux) gl_cv_func_truncate_works="guessing yes" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_truncate_works="guessing yes" ;; + # Guess no on AIX systems. + aix*) gl_cv_func_truncate_works="guessing no" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_truncate_works="$gl_cross_guess_normal" ;; + esac + ]) + rm -f conftest.tmp + ]) + case "$gl_cv_func_truncate_works" in + *yes) ;; + *) + AC_DEFINE([TRUNCATE_TRAILING_SLASH_BUG], [1], + [Define to 1 if truncate mishandles trailing slash.]) + REPLACE_TRUNCATE=1 + ;; + esac + fi else HAVE_DECL_TRUNCATE=0 if test $ac_cv_func_truncate = yes; then diff --git a/modules/truncate b/modules/truncate index b6fb377..82814fe 100644 --- a/modules/truncate +++ b/modules/truncate @@ -9,6 +9,8 @@ Depends-on: unistd sys_types largefile +sys_stat +stat [test $REPLACE_TRUNCATE = 1] open [test $HAVE_DECL_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1] ftruncate [test $HAVE_DECL_TRUNCATE = 0 || test $REPLACE_TRUNCATE = 1]