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:

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.