error EPERM on attempt to read symlink

Why is it that I can open a symbolic link, but can't read it? I am aware that I can get the contents of a symlink file using the readlink function, but still, it seems like this ought to work. Here's example code:

#include <iostream>

#include <unistd.h>
#include <fcntl.h>

int main(int argc, const char * argv[])
{
	// Make sure there is not already a file where we will create the link
	unlink( "/tmp/ReadSymLink-test" );
	
	// Create a symlink
	int result = symlink( "../usr", "/tmp/ReadSymLink-test");
	int err;
	if (result == 0)
	{
		std::cout << "created file /tmp/ReadSymLink-test\n";
	}
	else
	{
		err = errno;
		std::cerr << "symlink failed with error " << err << "\n";
		return 1;
	}
	
	// Open it for reading
	int fd = open( "/tmp/ReadSymLink-test", O_RDONLY | O_SYMLINK );
	if (fd < 0)
	{
		err = errno;
		std::cerr << "open failed with error " << err << "\n";
		return 2;
	}
	std::cout << "open succeeded\n";
	
	// and read it
	char buffer[200];
	ssize_t bytesRead = read( fd, buffer, sizeof(buffer) );
	if (bytesRead < 0)
	{
		err = errno;
		std::cerr << "read failed with error " << err << "\n";
		return 2;
	}
	else
	{
		buffer[ bytesRead ] = '\0';
		std::cout << "read of symlink result: " << buffer << "\n";
	}
	
	return 0;
}

The result, running under Sonoma 14.2 (beta) is

created file /tmp/ReadSymLink-test
open succeeded
read failed with error 1

Replies

Why questions are hard. In this case I suspect the answer is “Because BSD has always behaved this way.” However, finding a definitive answer would require more research than I have time for right now.

The standard way to read a symlink is with readlink. If you’re starting with a file descriptor, you can use freadlink.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Why questions are hard. In this case I suspect the answer is “Because BSD has always behaved this way.”

As far as I can determine, the flag O_SYMLINK only exists on macOS, so its behavior isn’t really a BSD question.

However, finding a definitive answer would require more research than I have time for right now.

That’s reasonable.

I suspect that this will go nowhere, but I filed FB13440366.