0

EDIT: The problem has been solved.

I'm trying to read a file that is located in proc/PID/environ which is 5 folder higher in the tree of folder than my current program.

I can do it when I write the following file name "../../../../../proc/PID/environ", but I would like the program to be more portable (compatible) with other computers.

The file is not recognized when I use "/proc/PID/environ", which is the absolute path of the file.

Here is the lines of code where it seems to not work:

int main(int argc, char *argv[]) {
        char filename[32];
        char* value;
        int key = 579;
        char line[1000];
        int nDigits = floor(log10(abs(key))) + 1;
        snprintf(filename, nDigits+15, "/proc/%d/environ", key);
            FILE *file = fopen(filename, "r");

The error is simply that the file doesn't exist. Error : errno='No such file or directory'.

filename if printed is really /proc/579/environ so I don't see the problem

Is there a way to read a file in C that is not in the current directory, without using ".." to go back in the tree? /proc/PID/environ being at the root of the tree, I would like to be able to use the absolute path.

JavaDumbell
  • 215
  • 2
  • 11
  • 1
    I assume that instead of `PID` you have an actual pid? When you attempt to open using an absolute path, what is the error you get, what is the value of `errno`? – Some programmer dude Jan 26 '21 at 03:46
  • Show the code that fails with the absolute path — it should work, and there is no (obvious) reason for it to fail if the relative path works and goes to the same location. At the moment, there's no way to help you — you've not shown the code that's causing trouble. In particular, how are you formatting the PID into the pathname? Does using `/self/` instead of `/PID/` make any difference? – Jonathan Leffler Jan 26 '21 at 03:52
  • 1
    What did you provide as `argv[2]`? If it isn't at least 16 characters long, you've got array bounds problems. Debugging: `printf("length(argv[2]) = %zu\n", strlen(argv[2]));` for kick-off. You probably need `argv[2]` to be at least 20 characters for safety with a 5-digit PID (which is normal). I'd probably just use a constant `32` for the size of the file name. – Jonathan Leffler Jan 26 '21 at 04:10
  • 579 only works if that process is running. If you're looking for your own process's environment, use `getpid()` instead. Are you sure process 579 exists? If it doesn't, you'll get the `no such file or directory` error. Note that the process might not exist by the time you open the file, even if you check with something like `if (kill(key, 0) == 0)` that the process exists (and you have rights to signal it) at the time when you do the check. That's a TOCTOU (time of check, time of use) problem. – Jonathan Leffler Jan 26 '21 at 04:11
  • 1
    For your own process use `/proc/self/...` instead. – Some programmer dude Jan 26 '21 at 04:20
  • Correct, the logic didn't made sense here. I made the change in my code and now I'm able to access my file, but I have another problem, now the errno is "permission denied". I will work on that, thanks for your help. I don't know how to upvote comments. – JavaDumbell Jan 26 '21 at 04:21
  • There isn't much of a way to up-vote comments. You might have a little up-arrow to the left that you can use — or you might not since you're new to SO. Don't worry too much this time; know about it for next time. – Jonathan Leffler Jan 26 '21 at 04:29
  • Your 'permission denied' message is a good change — it means that the file name is correct but you aren't allowed to access it. Who owns the process? If it's not you, it is not surprising that you can't read it. You might need to use `ls -l /proc/579/environ` to see what the permissions are, but that might fail if you're not allowed to even look in the `/proc/579` directory. – Jonathan Leffler Jan 26 '21 at 04:30
  • Your usage of `snprintf(filename, nDigits+15, "/proc/%d/environ", key);` is unconventional. A more conventional use would be: `snprintf(filename, sizeof(filename), "/proc/%d/environ", key);`. Theoretically, you should check that the result is smaller than `sizeof(filename)` but if `filename` is big enough (as it is if you use `32` as now shown in the question), it is common to omit the error check. – Jonathan Leffler Jan 26 '21 at 04:33
  • ls -l /proc/579/environ returns -r-------- 1 root root 0 Jan 25 23:32 /proc/579/environ, and I can only read it in the terminal using sudo. I guess you need to give privilege to the user to access the file. – JavaDumbell Jan 26 '21 at 04:36
  • @JonathanLeffler: Or if this only needs to run on Linux, consider using `asprintf` instead. – Nate Eldredge Jan 26 '21 at 05:38
  • 2
    @930404JP — with root having 400 permissions on the file, only root can read the environment for process 579. If you're not root, you have no reason to expect to see the environment of a root-owned process. There might be capabilities and/or ACLs to alter the decision-making, though the permissions don't show signs of that. – Jonathan Leffler Jan 26 '21 at 05:41

0 Answers0