GNOME Bugzilla – Bug 775593
GIO cannot write symlinks on FreeBSD and NetBSD
Last modified: 2017-06-10 12:59:45 UTC
This problem was reported on FreeBSD Bugzilla: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=212572 This can be easily tested by using 'gio save' command: $ gio save testfile < /etc/shells $ ln -s testfile testlink $ gio save testlink < /etc/shells gio: file:///path/to/testlink: Error opening file '/path/to/testlink': Too many links This problem happens in file gio/glocalfileoutputstream.c, function handle_overwrite_open. When O_NOFOLLOW is available, GIO checks whether errno is set to ELOOP to determine whether the target file is a symlink. However, some operating systems implement O_NOFOLLOW before POSIX. They use other error numbers and they have their own reasons for not following the standard. FreeBSD developers say they are not going to change this behavior: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214633 FreeBSD and DragonflyBSD use EMLINK: https://www.freebsd.org/cgi/man.cgi?query=open&sektion=2 https://leaf.dragonflybsd.org/cgi/web-man/?command=open§ion=2 NetBSD uses EFTYPE: http://netbsd.gw.com/cgi-bin/man-cgi?open+2
Created attachment 341338 [details] [review] glocalfileoutputstream: Fix symlink writing on FreeBSD and NetBSD FreeBSD, DragonflyBSD and NetBSD support O_NOFOLLOW, but they use error numbers that are different from what POSIX standard specifies. They are not going to change the behavior, and existing programs on these systems already take advantage of this difference. To support them, we have to add a check in GIO to use different error numbers on these systems.
Ping ... This bug was first reported in FreeBSD Bugzilla by a user (https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=212572), and I reported it here because it is an upstream issue. Can we get the patch reviewed?
*** Bug 777352 has been marked as a duplicate of this bug. ***
Review of attachment 341338 [details] [review]: I wonder if it would be a better long-term solution to move the EMLINK and EFTYPE handling into g_open() itself, since it is GLib’s compatibility wrapper for open(). It already abstracts the Windows file API to make it more POSIX-like; it would make sense to abstract this BSD-ism and make it POSIX-compliant (POSIX mandates the ELOOP error code). The downside of doing that is that any code like what’s currently in this patch will break, since it will be checking for the native error code on BSD platforms, rather than the POSIX error code. How much of a problem do you think that would be?
(In reply to Philip Withnall from comment #4) > Review of attachment 341338 [details] [review] [review]: > > I wonder if it would be a better long-term solution to move the EMLINK and > EFTYPE handling into g_open() itself, since it is GLib’s compatibility > wrapper for open(). It already abstracts the Windows file API to make it > more POSIX-like; it would make sense to abstract this BSD-ism and make it > POSIX-compliant (POSIX mandates the ELOOP error code). In glib/gstdio.h, when G_OS_UNIX defined, g_open is defined to be the same as open, so wrapper provided by GLib is never used.
(In reply to Ting-Wei Lan from comment #5) > (In reply to Philip Withnall from comment #4) > > Review of attachment 341338 [details] [review] [review] [review]: > > > > I wonder if it would be a better long-term solution to move the EMLINK and > > EFTYPE handling into g_open() itself, since it is GLib’s compatibility > > wrapper for open(). It already abstracts the Windows file API to make it > > more POSIX-like; it would make sense to abstract this BSD-ism and make it > > POSIX-compliant (POSIX mandates the ELOOP error code). > > In glib/gstdio.h, when G_OS_UNIX defined, g_open is defined to be the same > as open, so wrapper provided by GLib is never used. Uff, it’s probably going to cause more problems than it solves to change that. (At the least, none of the changes in GLib would take effect until programs were recompiled using the modified headers.) Let’s go with the patch.
Review of attachment 341338 [details] [review]: ++
Attachment 341338 [details] pushed as 45d4b59 - glocalfileoutputstream: Fix symlink writing on FreeBSD and NetBSD