mirror of
https://https.git.savannah.gnu.org/git/gnulib.git
synced 2026-09-01 02:34:55 +00:00
chmod: New module.
* lib/sys_stat.in.h (chmod): Declare when GNULIB_CHMOD is 1. * lib/chmod.c: New file, based on lib/lchmod.c. * m4/chmod.m4: New file, based on m4/fchmodat.m4. * m4/sys_stat_h.m4 (gl_SYS_STAT_H): Test whether chmod is declared. (gl_SYS_STAT_H_REQUIRE_DEFAULTS): Initialize GNULIB_CHMOD. (gl_SYS_STAT_H_DEFAULTS): Initialize REPLACE_CHMOD. * modules/sys_stat (Makefile.am): Substitute GNULIB_CHMOD, REPLACE_CHMOD. * modules/chmod: New file, based on modules/lchmod. * doc/posix-functions/chmod.texi: Mention the new module and the problems on IRIX and Windows.
This commit is contained in:
@@ -1,3 +1,18 @@
|
||||
2022-06-22 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
chmod: New module.
|
||||
* lib/sys_stat.in.h (chmod): Declare when GNULIB_CHMOD is 1.
|
||||
* lib/chmod.c: New file, based on lib/lchmod.c.
|
||||
* m4/chmod.m4: New file, based on m4/fchmodat.m4.
|
||||
* m4/sys_stat_h.m4 (gl_SYS_STAT_H): Test whether chmod is declared.
|
||||
(gl_SYS_STAT_H_REQUIRE_DEFAULTS): Initialize GNULIB_CHMOD.
|
||||
(gl_SYS_STAT_H_DEFAULTS): Initialize REPLACE_CHMOD.
|
||||
* modules/sys_stat (Makefile.am): Substitute GNULIB_CHMOD,
|
||||
REPLACE_CHMOD.
|
||||
* modules/chmod: New file, based on modules/lchmod.
|
||||
* doc/posix-functions/chmod.texi: Mention the new module and the
|
||||
problems on IRIX and Windows.
|
||||
|
||||
2022-06-21 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
lchmod: Simplify.
|
||||
|
||||
@@ -4,16 +4,21 @@
|
||||
|
||||
POSIX specification:@* @url{https://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html}
|
||||
|
||||
Gnulib module: ---
|
||||
Gnulib module: chmod
|
||||
|
||||
Portability problems fixed by Gnulib:
|
||||
@itemize
|
||||
@end itemize
|
||||
|
||||
Portability problems not fixed by Gnulib:
|
||||
@itemize
|
||||
@item
|
||||
This function does not fail when the file name argument ends in a slash
|
||||
and (without the slash) names a non-directory, on some platforms:
|
||||
AIX 7.2.
|
||||
AIX 7.2, IRIX 6.5.
|
||||
@item
|
||||
This function fails with a wrong error code (EINVAL instead of ENOTDIR)
|
||||
when the file name argument ends in a slash and (without the slash) names
|
||||
a non-directory, on some platforms:
|
||||
mingw, MSVC.
|
||||
@end itemize
|
||||
|
||||
Portability problems not fixed by Gnulib:
|
||||
@itemize
|
||||
@end itemize
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/* Implement chmod on platforms where it does not work correctly.
|
||||
|
||||
Copyright 2022 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 of the License, 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 <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
rpl_chmod (const char *filename, mode_t mode)
|
||||
#undef chmod
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
# define chmod _chmod
|
||||
#endif
|
||||
{
|
||||
size_t len = strlen (filename);
|
||||
if (len > 0 && filename[len - 1] == '/')
|
||||
{
|
||||
struct stat st;
|
||||
if (lstat (filename, &st) < 0)
|
||||
return -1;
|
||||
if (!S_ISDIR (st.st_mode))
|
||||
{
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return chmod (filename, mode);
|
||||
}
|
||||
+27
-1
@@ -391,7 +391,33 @@ struct stat
|
||||
#endif
|
||||
|
||||
|
||||
#if @GNULIB_MDA_CHMOD@
|
||||
#if @GNULIB_CHMOD@
|
||||
# if @REPLACE_CHMOD@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef chmod
|
||||
# define chmod rpl_chmod
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (chmod, int, (const char *filename, mode_t mode)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
_GL_CXXALIAS_RPL (chmod, int, (const char *filename, mode_t mode));
|
||||
# elif defined _WIN32 && !defined __CYGWIN__
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef chmod
|
||||
# define chmod _chmod
|
||||
# endif
|
||||
/* Need to cast, because in mingw the last argument is 'int mode'. */
|
||||
_GL_CXXALIAS_MDA_CAST (chmod, int, (const char *filename, mode_t mode));
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (chmod, int, (const char *filename, mode_t mode));
|
||||
# endif
|
||||
_GL_CXXALIASWARN (chmod);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
# undef chmod
|
||||
# if HAVE_RAW_DECL_CHMOD
|
||||
_GL_WARN_ON_USE (chmod, "chmod has portability problems - "
|
||||
"use gnulib module chmod for portability");
|
||||
# endif
|
||||
#elif @GNULIB_MDA_CHMOD@
|
||||
/* On native Windows, map 'chmod' to '_chmod', so that -loldnames is not
|
||||
required. In C++ with GNULIB_NAMESPACE, avoid differences between
|
||||
platforms by defining GNULIB_NAMESPACE::chmod always. */
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
# chmod.m4 serial 1
|
||||
dnl Copyright (C) 2004-2022 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.
|
||||
|
||||
dnl From Bruno Haible.
|
||||
|
||||
AC_DEFUN([gl_FUNC_CHMOD],
|
||||
[
|
||||
AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
|
||||
AC_CACHE_CHECK([whether chmod works],
|
||||
[gl_cv_func_chmod_works],
|
||||
[AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[
|
||||
AC_INCLUDES_DEFAULT[
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifndef S_IRUSR
|
||||
#define S_IRUSR 0400
|
||||
#endif
|
||||
#ifndef S_IWUSR
|
||||
#define S_IWUSR 0200
|
||||
#endif
|
||||
#ifndef S_IRWXU
|
||||
#define S_IRWXU 0700
|
||||
#endif
|
||||
#ifndef S_IRWXG
|
||||
#define S_IRWXG 0070
|
||||
#endif
|
||||
#ifndef S_IRWXO
|
||||
#define S_IRWXO 0007
|
||||
#endif
|
||||
]GL_MDA_DEFINES],
|
||||
[[
|
||||
int permissive = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
int desired = S_IRUSR | S_IWUSR;
|
||||
int result = 0;
|
||||
#define file "conftest.chmod"
|
||||
if (open (file, O_CREAT | O_WRONLY | O_TRUNC, permissive) < 0)
|
||||
return 1;
|
||||
/* Test whether chmod rejects a trailing slash on a non-directory,
|
||||
with error ENOTDIR.
|
||||
This test fails on AIX 7.2, IRIX 6.5 (no error) and
|
||||
native Windows (error EINVAL). */
|
||||
errno = 0;
|
||||
if (chmod (file "/", desired) == 0)
|
||||
result |= 2;
|
||||
else if (errno != ENOTDIR)
|
||||
result |= 4;
|
||||
return result;
|
||||
]])],
|
||||
[gl_cv_func_chmod_works=yes],
|
||||
[gl_cv_func_chmod_works=no],
|
||||
[case "$host_os" in
|
||||
# Guess no on AIX, IRIX, native Windows.
|
||||
aix* | irix* | mingw*)
|
||||
gl_cv_func_chmod_works="guessing no" ;;
|
||||
# Guess yes on glibc, musl libc, macOS, FreeBSD, NetBSD, OpenBSD, Solaris, Haiku, Cygwin.
|
||||
*-gnu* | gnu* | *-musl* | darwin* | freebsd* | midnightbsd* | netbsd* | openbsd* | solaris* | haiku* | cygwin*)
|
||||
gl_cv_func_chmod_works="guessing yes" ;;
|
||||
# If we don't know, obey --enable-cross-guesses.
|
||||
*)
|
||||
gl_cv_func_chmod_works="$gl_cross_guess_normal" ;;
|
||||
esac
|
||||
])
|
||||
rm -f conftest.chmod
|
||||
])
|
||||
case "$gl_cv_func_chmod_works" in
|
||||
*yes) ;;
|
||||
*) REPLACE_CHMOD=1 ;;
|
||||
esac
|
||||
])
|
||||
|
||||
# Prerequisites of lib/chmod.c.
|
||||
AC_DEFUN([gl_PREREQ_CHMOD],
|
||||
[
|
||||
:
|
||||
])
|
||||
+4
-2
@@ -1,4 +1,4 @@
|
||||
# sys_stat_h.m4 serial 41 -*- Autoconf -*-
|
||||
# sys_stat_h.m4 serial 42 -*- Autoconf -*-
|
||||
dnl Copyright (C) 2006-2022 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,7 +46,7 @@ AC_DEFUN_ONCE([gl_SYS_STAT_H],
|
||||
dnl Check for declarations of anything we want to poison if the
|
||||
dnl corresponding gnulib module is not in use.
|
||||
gl_WARN_ON_USE_PREPARE([[#include <sys/stat.h>
|
||||
]], [fchmodat fstat fstatat futimens getumask lchmod lstat
|
||||
]], [chmod fchmodat fstat fstatat futimens getumask lchmod lstat
|
||||
mkdirat mkfifo mkfifoat mknod mknodat stat utimensat])
|
||||
|
||||
AC_REQUIRE([AC_C_RESTRICT])
|
||||
@@ -72,6 +72,7 @@ AC_DEFUN([gl_SYS_STAT_H_REQUIRE_DEFAULTS],
|
||||
[
|
||||
m4_defun(GL_MODULE_INDICATOR_PREFIX[_SYS_STAT_H_MODULE_INDICATOR_DEFAULTS], [
|
||||
gl_UNISTD_H_REQUIRE_DEFAULTS dnl for REPLACE_FCHDIR
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_CHMOD])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FCHMODAT])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTAT])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTATAT])
|
||||
@@ -112,6 +113,7 @@ AC_DEFUN([gl_SYS_STAT_H_DEFAULTS],
|
||||
HAVE_MKNOD=1; AC_SUBST([HAVE_MKNOD])
|
||||
HAVE_MKNODAT=1; AC_SUBST([HAVE_MKNODAT])
|
||||
HAVE_UTIMENSAT=1; AC_SUBST([HAVE_UTIMENSAT])
|
||||
REPLACE_CHMOD=0; AC_SUBST([REPLACE_CHMOD])
|
||||
REPLACE_FCHMODAT=0; AC_SUBST([REPLACE_FCHMODAT])
|
||||
REPLACE_FSTAT=0; AC_SUBST([REPLACE_FSTAT])
|
||||
REPLACE_FSTATAT=0; AC_SUBST([REPLACE_FSTATAT])
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
Description:
|
||||
chmod() function: change the permissions of a file
|
||||
|
||||
Files:
|
||||
lib/chmod.c
|
||||
m4/chmod.m4
|
||||
|
||||
Depends-on:
|
||||
sys_stat
|
||||
lstat [test $REPLACE_CHMOD = 1]
|
||||
|
||||
configure.ac:
|
||||
gl_FUNC_CHMOD
|
||||
gl_CONDITIONAL([GL_COND_OBJ_CHMOD], [test $REPLACE_CHMOD = 1])
|
||||
AM_COND_IF([GL_COND_OBJ_CHMOD], [
|
||||
gl_PREREQ_CHMOD
|
||||
])
|
||||
gl_SYS_STAT_MODULE_INDICATOR([chmod])
|
||||
|
||||
Makefile.am:
|
||||
if GL_COND_OBJ_CHMOD
|
||||
lib_SOURCES += chmod.c
|
||||
endif
|
||||
|
||||
Include:
|
||||
<sys/stat.h>
|
||||
|
||||
License:
|
||||
GPL
|
||||
|
||||
Maintainer:
|
||||
Paul Eggert, Bruno Haible
|
||||
@@ -36,6 +36,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
|
||||
-e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \
|
||||
-e 's|@''WINDOWS_64_BIT_ST_SIZE''@|$(WINDOWS_64_BIT_ST_SIZE)|g' \
|
||||
-e 's|@''WINDOWS_STAT_TIMESPEC''@|$(WINDOWS_STAT_TIMESPEC)|g' \
|
||||
-e 's/@''GNULIB_CHMOD''@/$(GNULIB_CHMOD)/g' \
|
||||
-e 's/@''GNULIB_FCHMODAT''@/$(GNULIB_FCHMODAT)/g' \
|
||||
-e 's/@''GNULIB_FSTAT''@/$(GNULIB_FSTAT)/g' \
|
||||
-e 's/@''GNULIB_FSTATAT''@/$(GNULIB_FSTATAT)/g' \
|
||||
@@ -67,6 +68,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
|
||||
-e 's|@''HAVE_MKNOD''@|$(HAVE_MKNOD)|g' \
|
||||
-e 's|@''HAVE_MKNODAT''@|$(HAVE_MKNODAT)|g' \
|
||||
-e 's|@''HAVE_UTIMENSAT''@|$(HAVE_UTIMENSAT)|g' \
|
||||
-e 's|@''REPLACE_CHMOD''@|$(REPLACE_CHMOD)|g' \
|
||||
-e 's|@''REPLACE_FCHMODAT''@|$(REPLACE_FCHMODAT)|g' \
|
||||
-e 's|@''REPLACE_FSTAT''@|$(REPLACE_FSTAT)|g' \
|
||||
-e 's|@''REPLACE_FSTATAT''@|$(REPLACE_FSTATAT)|g' \
|
||||
|
||||
Reference in New Issue
Block a user