6

i came across a bit of code which says

int fd = open(fn, flags, 0);
if (fd < 0 && errno != EMLINK)
  ...

flags is either O_RDONLY or O_RDONLY|O_NOFOLLOW

IEEE Std 1003.1, 2013 (SUSv4) has just

  • [EMLINK] Too many links. An attempt was made to have the link count of a single file exceed {LINK_MAX}.

  • {LINK_MAX} Maximum number of links to a single file.

how does opening a file increase its link count?

just somebody
  • 18,602
  • 6
  • 51
  • 60
  • 2
    I don't see `EMLINK` listed as one of the possible errors for [`open`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html). It is listed for [`link`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html) though. – Sander De Dycker Jun 06 '14 at 15:22
  • @Sander because you're looking at the linux manpages! – Nicholas Wilson Jun 06 '14 at 15:22
  • @NicholasWilson: No, same for the POSIX specifications themselfs. See *Jean-Baptiste Yunès* answer below. – alk Jun 06 '14 at 15:26
  • @NicholasWilson : click the links in my comment, and you'll find I'm not looking at linux manpages, but at the 2013 edition of POSIX.1-2008, which is the standard mentioned by the op. – Sander De Dycker Jun 06 '14 at 15:33
  • this code originates in FreeBSD, sorry to have withheld this information. – just somebody Jun 06 '14 at 15:36

2 Answers2

5

Good question. When O_NOFOLLOW was added, they chose to reuse an existing error code rather than make up a new one. EMLINK in this case signifies that the file is a symlink and is returned on FreeBSD. Linux and Darwin return ELOOP rather than EMLINK, while NetBSD uses EFTYPE.

My manpages say O_NOFOLLOW is a FreeBSD extension subsequently added to Linux (ie you won't find its behaviour explained in older versions of the SUS, but it is included in the POSIX 2008 with the Linux return code).

Nicholas Wilson
  • 9,435
  • 1
  • 41
  • 80
  • `ELOOP` will be returned when following too many symbolic links or when `O_NOFOLLOW` is specified. – Edward Thomson Jun 06 '14 at 15:22
  • 1
    There is a NetBSD discussion at http://gnats.netbsd.org/43154 about the overloading of this existing code adopted by FreeBSD (although NetBSD were debating about using EFTYPE or ELOOP instead) – mc110 Jun 06 '14 at 15:23
  • 1
    POSIX says ELOOP is the error when you specify a symlink and O_NOFOLLOW is included; Linux may implement EMLINK following BSD, in which case neither Linux nor BSD is POSIX-compliant. However, Mac OS X documents ELOOP as the error when you open a symlink with O_NOFOLLOW. – Jonathan Leffler Jun 06 '14 at 15:23
  • @Edward corrected, just checked on a Linux system :) – Nicholas Wilson Jun 06 '14 at 15:23
  • 2
    @NicholasWilson you may have gotten a downvote because `O_NOFOLLOW` *is* specified for `open(2)`: http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html (it says `errno` is set to `ELOOP` then). – just somebody Jun 06 '14 at 15:27
  • @NicholasWilson Right you are, I didn't realize they had reused `EMLINK` in this way on the FreeBSD. – Edward Thomson Jun 06 '14 at 15:33
2

This is not specified by SUS v4. See http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69