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 <withnall@endlessm.com>
This commit is contained in:
Philip Withnall 2020-07-27 12:24:20 +01:00
parent 87bc87ae69
commit b4aa9d7858

View File

@ -1444,12 +1444,23 @@ consistent_out:
/* ELOOP indicates that @filename is a symlink, since we used /* ELOOP indicates that @filename is a symlink, since we used
* O_NOFOLLOW (alternately it could indicate that @filename contains * O_NOFOLLOW (alternately it could indicate that @filename contains
* looping or too many symlinks). In either case, try again on the * 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) if (saved_errno == ELOOP)
#endif
return g_file_set_contents_full (filename, contents, length, return g_file_set_contents_full (filename, contents, length,
flags | G_FILE_SET_CONTENTS_CONSISTENT, flags | G_FILE_SET_CONTENTS_CONSISTENT,
mode, error); mode, error);
#endif #endif /* O_NOFOLLOW */
set_file_error (error, set_file_error (error,
filename, _("Failed to open file “%s”: %s"), filename, _("Failed to open file “%s”: %s"),