Search code examples
c++linuxreadlink

readlink sets errno to ENOENT


I'm an inexperienced Linux programmer and am trying to learn to use readlink() based on this question and answer.

My call to readlink() returns -1 and sets errno to 2 (ENOENT).

The code:

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <iostream>
#include <algorithm>
#include <cstdio>

int main(int argc, char* argv[])
{
  char szTmp[100];
  snprintf(szTmp, 100, "proc/%d/exe", getpid());
  std::cout << "szTmp is " << szTmp << std::endl;
  char executingFolder[500];
  errno = 0;
  int bytes = std::min(readlink(szTmp, executingFolder, 500), (ssize_t)499);

  if (bytes > 0)
  {
    executingFolder[bytes] = '\0';
  }

  std::cout << "bytes is " << bytes << std::endl;
  std::cout << "errno is " << errno;
  if (ENOENT == errno)
  {
    std::cout << " ENOENT";
  }
  std::cout << std::endl;
  std::cout << "Executing folder is \"" << executingFolder << "\"" << std::endl;

  return 0;
}

The output:

(An example from one iteration since pid changes)

szTmp is proc/22272/exe
bytes is -1
errno is 2 ENOENT
Executing folder is ""

Things I have tried:

  • After compilation: sudo ./a.out (thinking that directory access was restricted because of lack of permission). Result: unchanged behavior from ./a.out
  • SIGINT the program during execution, and verified that /proc/<pid>/exe exists. Result: it consistently exists for each run of the program.
  • Verified that the value of the target link is well within 499 chars.

Can someone please help identify the problem? Having read the readlink man page and online descriptions, and the noted StackOverflow article, I am still unclear what is wrong.

Thank you.


Solution

  • proc/1234/exe is a relative path.

    I think you want /proc/%d/exe, which is an absolute path, and correctly refers to the /proc directory.


    Secondly, because readlink() will truncate the result in case the buffer is too small, you should consider the case where the return value is == bufsiz to be an error, as truncation may have happened. You can't know.


    Also, "Executing folder" is not what /proc/<pid>/exe gives you. /proc/<pid>/exe is a symlink to the currently running executable (file), not a directory.