* lib/issymlink.h: New file, extracted from lib/sys_stat.in.h.
* lib/issymlink.c: Include issymlink.h instead of <sys/stat.h>.
* lib/issymlinkat.c: Likewise.
* modules/issymlink (Files): Add lib/issymlink.h.
(Depends-on): Add extern-inline.
(configure.ac): Use gl_MODULE_INDICATOR.
(Include): Set to "issymlink.h".
* modules/issymlinkat (Files): Add lib/issymlink.h.
(Depends-on): Add extern-inline.
(configure.ac): Use gl_MODULE_INDICATOR.
(Include): Set to "issymlink.h".
* lib/sys_stat.in.h: Don't include <errno.h>, <unistd.h>.
(_GL_ISSYMLINK_INLINE, _GL_ISSYMLINKAT_INLINE): Remove macros.
(issymlink, issymlinkat): Remove functions.
* m4/sys_stat_h.m4 (gl_SYS_STAT_H_REQUIRE_DEFAULTS): Don't initialize
GNULIB_ISSYMLINK, GNULIB_ISSYMLINKAT.
* modules/sys_stat-h (Depends-on): Remove extern-inline.
(Makefile.am): Don't substitute GNULIB_ISSYMLINK, GNULIB_ISSYMLINKAT.
* lib/chown.c: Include issymlink.h.
* lib/lchown.c: Likewise.
* lib/lchmod.c: Likewise.
* lib/fchmodat.c: Likewise.
* lib/rename.c: Likewise.
* lib/renameatu.c: Likewise.
* lib/unlink.c: Likewise.
* lib/unlinkat.c: Likewise.
* lib/utimens.c: Likewise.
+2025-08-18 Bruno Haible <bruno@clisp.org>
+
+ sys_stat: Fix namespace pollution on native Windows.
+ * lib/issymlink.h: New file, extracted from lib/sys_stat.in.h.
+ * lib/issymlink.c: Include issymlink.h instead of <sys/stat.h>.
+ * lib/issymlinkat.c: Likewise.
+ * modules/issymlink (Files): Add lib/issymlink.h.
+ (Depends-on): Add extern-inline.
+ (configure.ac): Use gl_MODULE_INDICATOR.
+ (Include): Set to "issymlink.h".
+ * modules/issymlinkat (Files): Add lib/issymlink.h.
+ (Depends-on): Add extern-inline.
+ (configure.ac): Use gl_MODULE_INDICATOR.
+ (Include): Set to "issymlink.h".
+ * lib/sys_stat.in.h: Don't include <errno.h>, <unistd.h>.
+ (_GL_ISSYMLINK_INLINE, _GL_ISSYMLINKAT_INLINE): Remove macros.
+ (issymlink, issymlinkat): Remove functions.
+ * m4/sys_stat_h.m4 (gl_SYS_STAT_H_REQUIRE_DEFAULTS): Don't initialize
+ GNULIB_ISSYMLINK, GNULIB_ISSYMLINKAT.
+ * modules/sys_stat-h (Depends-on): Remove extern-inline.
+ (Makefile.am): Don't substitute GNULIB_ISSYMLINK, GNULIB_ISSYMLINKAT.
+ * lib/chown.c: Include issymlink.h.
+ * lib/lchown.c: Likewise.
+ * lib/lchmod.c: Likewise.
+ * lib/fchmodat.c: Likewise.
+ * lib/rename.c: Likewise.
+ * lib/renameatu.c: Likewise.
+ * lib/unlink.c: Likewise.
+ * lib/unlinkat.c: Likewise.
+ * lib/utimens.c: Likewise.
+
2025-08-15 Bruno Haible <bruno@clisp.org>
Reduce risk of compilation errors within include files.
#include <string.h>
#include <sys/stat.h>
+#include "issymlink.h"
+
#if !HAVE_CHOWN
/* Simple stub that always fails with ENOSYS, for mingw. */
#include <intprops.h>
+#include "issymlink.h"
+
/* Invoke chmod or lchmod on FILE, using mode MODE, in the directory
open on descriptor FD. If possible, do it without changing the
working directory. Otherwise, resort to using save_cwd/fchdir,
#include <config.h>
#define _GL_ISSYMLINK_INLINE _GL_EXTERN_INLINE
-#include <sys/stat.h>
+#include "issymlink.h"
--- /dev/null
+/* Test whether a file is a symbolic link.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ This file 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _ISSYMLINK_H
+#define _ISSYMLINK_H
+
+/* This file uses _GL_ARG_NONNULL, _GL_INLINE. */
+#if !_GL_CONFIG_H_INCLUDED
+ #error "Please include config.h first."
+#endif
+
+#include <errno.h>
+#include <unistd.h> /* for readlink, readlinkat */
+
+
+_GL_INLINE_HEADER_BEGIN
+
+#ifndef _GL_ISSYMLINK_INLINE
+# define _GL_ISSYMLINK_INLINE _GL_INLINE
+#endif
+#ifndef _GL_ISSYMLINKAT_INLINE
+# define _GL_ISSYMLINKAT_INLINE _GL_INLINE
+#endif
+
+#if GNULIB_ISSYMLINK
+/* Tests whether FILENAME represents a symbolic link.
+ This function is more reliable than lstat() / fstatat() followed by S_ISLNK,
+ because it avoids possible EOVERFLOW errors.
+ Returns
+ 1 if FILENAME is a symbolic link,
+ 0 if FILENAME exists and is not a symbolic link,
+ -1 with errno set if determination failed, in particular
+ -1 with errno = ENOENT or ENOTDIR if FILENAME does not exist. */
+# ifdef __cplusplus
+extern "C" {
+# endif
+_GL_ISSYMLINK_INLINE int issymlink (const char *filename)
+ _GL_ARG_NONNULL ((1));
+_GL_ISSYMLINK_INLINE int
+issymlink (const char *filename)
+{
+ char linkbuf[1];
+ if (readlink (filename, linkbuf, sizeof (linkbuf)) >= 0)
+ return 1;
+ if (errno == EINVAL)
+ return 0;
+ else
+ return -1;
+}
+# ifdef __cplusplus
+}
+# endif
+#endif
+
+#if GNULIB_ISSYMLINKAT
+/* Tests whether FILENAME represents a symbolic link.
+ This function is more reliable than lstat() / fstatat() followed by S_ISLNK,
+ because it avoids possible EOVERFLOW errors.
+ If FILENAME is a relative file name, it is interpreted as relative to the
+ directory referred to by FD (where FD = AT_FDCWD denotes the current
+ directory).
+ Returns
+ 1 if FILENAME is a symbolic link,
+ 0 if FILENAME exists and is not a symbolic link,
+ -1 with errno set if determination failed, in particular
+ -1 with errno = ENOENT or ENOTDIR if FILENAME does not exist. */
+# ifdef __cplusplus
+extern "C" {
+# endif
+_GL_ISSYMLINKAT_INLINE int issymlinkat (int fd, const char *filename)
+ _GL_ARG_NONNULL ((2));
+_GL_ISSYMLINKAT_INLINE int
+issymlinkat (int fd, const char *filename)
+{
+ char linkbuf[1];
+ if (readlinkat (fd, filename, linkbuf, sizeof (linkbuf)) >= 0)
+ return 1;
+ if (errno == EINVAL)
+ return 0;
+ else
+ return -1;
+}
+# ifdef __cplusplus
+}
+# endif
+#endif
+
+_GL_INLINE_HEADER_END
+
+#endif /* _ISSYMLINK_H */
#include <config.h>
#define _GL_ISSYMLINKAT_INLINE _GL_EXTERN_INLINE
-#include <sys/stat.h>
+#include "issymlink.h"
#include <unistd.h>
#include <intprops.h>
+#include "issymlink.h"
/* Work like chmod, except when FILE is a symbolic link.
In that case, on systems where permissions on symbolic links are unsupported
#include <config.h>
+/* Specification. */
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
+#include "issymlink.h"
+
#if !HAVE_LCHOWN
/* If the system chown does not follow symlinks, we don't want it
#include <config.h>
+/* Specification. */
#include <stdio.h>
#undef rename
# include <unistd.h>
# include "dirname.h"
+# include "issymlink.h"
# include "same-inode.h"
/* Rename the file SRC to DST, fixing any trailing slash bugs. */
#include <config.h>
+/* Specification. */
#include "renameatu.h"
#include <errno.h>
# include <sys/syscall.h>
#endif
+#include "issymlink.h"
+
static int
errno_fail (int e)
{
#define _@GUARD_PREFIX@_SYS_STAT_H
/* This file uses _GL_ATTRIBUTE_NODISCARD, _GL_ATTRIBUTE_NOTHROW,
- _GL_INLINE, GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */
+ GNULIB_POSIXCHECK, HAVE_RAW_DECL_*. */
#if !_GL_CONFIG_H_INCLUDED
#error "Please include config.h first."
#endif
/* The definition of _GL_WARN_ON_USE is copied here. */
-_GL_INLINE_HEADER_BEGIN
-
-#ifndef _GL_ISSYMLINK_INLINE
-# define _GL_ISSYMLINK_INLINE _GL_INLINE
-#endif
-#ifndef _GL_ISSYMLINKAT_INLINE
-# define _GL_ISSYMLINKAT_INLINE _GL_INLINE
-#endif
-
-
/* Before doing "#define mknod rpl_mknod" below, we need to include all
headers that may declare mknod(). OS/2 kLIBC declares mknod() in
<unistd.h>, not in <sys/stat.h>. */
#endif
-#if @GNULIB_ISSYMLINK@ || @GNULIB_ISSYMLINKAT@
-/* For the inline definitions of issymlink, issymlinkat below. */
-# include <errno.h>
-# include <unistd.h> /* for readlink, readlinkat */
-#endif
-
-
#if @GNULIB_CHMOD@
# if @REPLACE_CHMOD@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
#endif
-#if @GNULIB_ISSYMLINK@
-/* Tests whether FILENAME represents a symbolic link.
- This function is more reliable than lstat() / fstatat() followed by S_ISLNK,
- because it avoids possible EOVERFLOW errors.
- Returns
- 1 if FILENAME is a symbolic link,
- 0 if FILENAME exists and is not a symbolic link,
- -1 with errno set if determination failed, in particular
- -1 with errno = ENOENT or ENOTDIR if FILENAME does not exist. */
-# ifdef __cplusplus
-extern "C" {
-# endif
-_GL_ISSYMLINK_INLINE int issymlink (const char *filename)
- _GL_ARG_NONNULL ((1));
-_GL_ISSYMLINK_INLINE int
-issymlink (const char *filename)
-{
- char linkbuf[1];
- if (readlink (filename, linkbuf, sizeof (linkbuf)) >= 0)
- return 1;
- if (errno == EINVAL)
- return 0;
- else
- return -1;
-}
-# ifdef __cplusplus
-}
-# endif
-#endif
-
-
-#if @GNULIB_ISSYMLINKAT@
-/* Tests whether FILENAME represents a symbolic link.
- This function is more reliable than lstat() / fstatat() followed by S_ISLNK,
- because it avoids possible EOVERFLOW errors.
- If FILENAME is a relative file name, it is interpreted as relative to the
- directory referred to by FD (where FD = AT_FDCWD denotes the current
- directory).
- Returns
- 1 if FILENAME is a symbolic link,
- 0 if FILENAME exists and is not a symbolic link,
- -1 with errno set if determination failed, in particular
- -1 with errno = ENOENT or ENOTDIR if FILENAME does not exist. */
-# ifdef __cplusplus
-extern "C" {
-# endif
-_GL_ISSYMLINKAT_INLINE int issymlinkat (int fd, const char *filename)
- _GL_ARG_NONNULL ((2));
-_GL_ISSYMLINKAT_INLINE int
-issymlinkat (int fd, const char *filename)
-{
- char linkbuf[1];
- if (readlinkat (fd, filename, linkbuf, sizeof (linkbuf)) >= 0)
- return 1;
- if (errno == EINVAL)
- return 0;
- else
- return -1;
-}
-# ifdef __cplusplus
-}
-# endif
-#endif
-
-
#if @GNULIB_LCHMOD@
/* Change the mode of FILENAME to MODE, without dereferencing it if FILENAME
denotes a symbolic link. */
#endif
-_GL_INLINE_HEADER_END
-
#endif /* _@GUARD_PREFIX@_SYS_STAT_H */
#endif /* _@GUARD_PREFIX@_SYS_STAT_H */
#endif
#include <config.h>
+/* Specification. */
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include "filename.h"
+#include "issymlink.h"
#undef unlink
#if defined _WIN32 && !defined __CYGWIN__
#include <config.h>
+/* Specification. */
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include "filename.h"
+#include "issymlink.h"
#include "openat.h"
#if HAVE_UNLINKAT
#include <config.h>
+/* Specification. */
#define _GL_UTIMENS_INLINE _GL_EXTERN_INLINE
#include "utimens.h"
#include <unistd.h>
#include <utime.h>
+#include "issymlink.h"
#include "stat-time.h"
#include "timespec.h"
# sys_stat_h.m4
-# serial 43 -*- Autoconf -*-
+# serial 44 -*- Autoconf -*-
dnl Copyright (C) 2006-2025 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FSTATAT])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_FUTIMENS])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETUMASK])
- gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISSYMLINK])
- gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ISSYMLINKAT])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LCHMOD])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_LSTAT])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MKDIR])
Test whether a file is a symbolic link.
Files:
+lib/issymlink.h
lib/issymlink.c
Depends-on:
+extern-inline
sys_stat-h
fcntl-h
readlink
configure.ac:
-gl_SYS_STAT_MODULE_INDICATOR([issymlink])
+gl_MODULE_INDICATOR([issymlink])
Makefile.am:
lib_SOURCES += issymlink.c
Include:
-<sys/stat.h>
+"issymlink.h"
License:
LGPLv2+
Test whether a file is a symbolic link.
Files:
+lib/issymlink.h
lib/issymlinkat.c
Depends-on:
+extern-inline
sys_stat-h
fcntl-h
readlinkat
configure.ac:
-gl_SYS_STAT_MODULE_INDICATOR([issymlinkat])
+gl_MODULE_INDICATOR([issymlinkat])
Makefile.am:
lib_SOURCES += issymlinkat.c
Include:
-<sys/stat.h>
+"issymlink.h"
License:
GPL
snippet/arg-nonnull
snippet/c++defs
snippet/warn-on-use
-extern-inline
sys_types-h
time-h
-e 's/@''GNULIB_FSTATAT''@/$(GNULIB_FSTATAT)/g' \
-e 's/@''GNULIB_FUTIMENS''@/$(GNULIB_FUTIMENS)/g' \
-e 's/@''GNULIB_GETUMASK''@/$(GNULIB_GETUMASK)/g' \
- -e 's/@''GNULIB_ISSYMLINK''@/$(GNULIB_ISSYMLINK)/g' \
- -e 's/@''GNULIB_ISSYMLINKAT''@/$(GNULIB_ISSYMLINKAT)/g' \
-e 's/@''GNULIB_LCHMOD''@/$(GNULIB_LCHMOD)/g' \
-e 's/@''GNULIB_LSTAT''@/$(GNULIB_LSTAT)/g' \
-e 's/@''GNULIB_MKDIR''@/$(GNULIB_MKDIR)/g' \