0

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.

Community
  • 1
  • 1
StoneThrow
  • 5,314
  • 4
  • 44
  • 86

2 Answers2

3

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.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
1

proc/22272/exe is a relative path name. It resolves to the file exe, in the directory 22272, in the directory proc, in your current directory. Unless your current directory is /, that's unlikely to exist.

You want an absolute path name, starting with /, in this case /proc/22272/exe.

Change this:

snprintf(szTmp, 100, "proc/%d/exe", getpid());

to this:

snprintf(szTmp, 100, "/proc/%d/exe", getpid());

But before you fix your program, you might try this:

( cd / ; ~/a.out )

(assuming a.out is in your home directory).

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • Thank you also. I hate to choose between two correct and generous answers from the very same minute (SO only gives minute resolution(?)). But I'll upvote both your answers. – StoneThrow Jan 14 '17 at 02:51