I'm learning syscalls like stat and readlink. I try to stat the root directory in two different ways:
- Just stat the path to root. Simple.
- Then, a roundabout way, fopen "/", make a file descriptor path from the fd I get and readlink it to get "/". Then stat.
What I don't understand is this works the way I expect and the inode numbers are the same, except when I introduce more code AFTERWARDS, namely getcwd, the inodes are strangely not the same and test 2 fails. If you run both versions, with and without the part it says to cut out, the printf of p2 also changes and you can see there is garbage after /
. What am I doing wrong here or what's going on here? How is code after those initial statements causing a change earlier in the code?
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
int main()
{
/* Stat root this way */
struct stat st1;
char *p1 = "/";
if (!stat(p1, &st1))
printf("PASS\n");
else
printf("FAIL - %m\n");
/* Stat root another way */
struct stat st2;
char fdpath[100], p2[100];
FILE *fp = fopen("/", "r");
sprintf(fdpath, "/proc/self/fd/%d", fileno(fp));
readlink(fdpath, p2, sizeof(p2));
if (!stat(p2, &st2))
printf("PASS\n");
else
printf("FAIL - %m\n");
printf("p2 = %s\n", p2);
/* Check inodes are the same */
printf(" st1.st_ino = %ld\n", st1.st_ino);
printf(" st2.st_ino = %ld\n", st2.st_ino);
/* TRY WITHOUT THIS - Adding this makes the inodes different! Take it out and they're the same */
char cwd_buf[100];
char *cwd_ret = getcwd(cwd_buf, sizeof(cwd_buf));
if (cwd_ret == NULL)
printf("getcwd failed - %m\n");
printf("cwd_ret = %s\n", cwd_ret);
return 0;
}