From b4aa9d785844b572c0fd70d2c2973e94aad6e77d Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 27 Jul 2020 12:24:20 +0100 Subject: [PATCH] gfileutils: Fix O_NOFOLLOW handling on BSD systems Various different BSD systems use a different errno from `E_LOOP` (as defined by POSIX and used on Linux) to indicate that a file is a symlink when you try to `open()` it with `O_NOFOLLOW`. Fix the code which detects this. This is a follow-up to #1302. Signed-off-by: Philip Withnall --- glib/gfileutils.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/glib/gfileutils.c b/glib/gfileutils.c index 8d80cd50a..2993eacc3 100644 --- a/glib/gfileutils.c +++ b/glib/gfileutils.c @@ -1444,12 +1444,23 @@ consistent_out: /* ELOOP indicates that @filename is a symlink, since we used * O_NOFOLLOW (alternately it could indicate that @filename contains * looping or too many symlinks). In either case, try again on the - * %G_FILE_SET_CONTENTS_CONSISTENT code path. */ + * %G_FILE_SET_CONTENTS_CONSISTENT code path. + * + * FreeBSD uses EMLINK instead of ELOOP + * (https://www.freebsd.org/cgi/man.cgi?query=open&sektion=2#STANDARDS), + * and NetBSD uses EFTYPE + * (https://netbsd.gw.com/cgi-bin/man-cgi?open+2+NetBSD-current). */ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + if (saved_errno == EMLINK) +#elif defined(__NetBSD__) + if (saved_errno == EFTYPE) +#else if (saved_errno == ELOOP) +#endif return g_file_set_contents_full (filename, contents, length, flags | G_FILE_SET_CONTENTS_CONSISTENT, mode, error); -#endif +#endif /* O_NOFOLLOW */ set_file_error (error, filename, _("Failed to open file ā€œ%sā€: %s"),