0

I wanted a function to return the absolute path given a relative path to an existing file. Searching online I came across realpath here: https://stackoverflow.com/a/229038/19637794 And followed the example here: Example of realpath function in C

So I wrote:

#include <limits.h>
#include <stdlib.h>
char path[PATH_MAX];

void test(void){
char *ppath = realpath("../../test/src/file", path );
if (ppath != NULL)
{
    *do stuff, read the file*
}
else
{
    return -1;
}
free(ppath);
}

int main ()
{
    test();
}

Where my working directories are as follow

dir
|---CMakeLists.txt
|---build/
|   |---test/
|       |
|       |---executable
|
|---test/
|   |---CMakeLists.txt
|   |---src/
|       |
|       |---test.c
|       |---file

I launched the executable from build directory with ./test/executable but I kept getting -1, checked with gdb and verified that ppath was 0x0.

I read My realpath return null for files But didn't seem to fit my problem

Then I read about #include <errno.h>, so added this two line and it said "No such file or directory"

else
{
    char* errStr = strerror(errno);
    printf("%s" ,errStr);
}

After that I added printf("%s", path); that returned: dir/test, which is the directory above the one I wanted, still ppath is NULL. I tried to add a file in the directory above, but doesn't seem to work either, nor with its original path nor with the new one.

I also read it might happen having realpath returning NULL if the path exceed the maximum allowed in phase of declaration, so I also tried to remove path and feeding NULL, like it was done at https://www.demo2s.com/c/c-char-real-realpath-p-null.html as follow:

char *ppath = realpath("../../test/src/file", NULL );

Which didn't work either.

What am I doing wrong?

Edit: few modify based on comment Edit2: added parenthesis between test and ;

  • How are you running your program? – Will Eccles Jul 29 '22 at 16:26
  • Unless the second argument passed to realpath() (char *restrict resolved_path) is NULL, you should not be calling free() on the returned pointer, since it will not have been dynamically allocated. – Gregor Hartl Watters Jul 29 '22 at 16:32
  • You can also simplify `if (ppath != NULL) ...` to `if (ppath) ...` – Gregor Hartl Watters Jul 29 '22 at 16:33
  • The code appears to be missing a `main` function. "I kept getting errors" ... what errors? For what code? – thrig Jul 30 '22 at 04:05
  • @WillEccles from the build directory I run ./test/executable – cielocamminatore Jul 30 '22 at 09:47
  • 1
    @GregorWattersHärtl Right, I'll try without the free. Yes, absolutely, but I prefer not to simplify the expression inside the if, to make it 100% clear what was the risk in the operation. – cielocamminatore Jul 30 '22 at 09:49
  • @thrig I'm trying to automate tests for a function to read files (function that compile correctly, and if I gave it the absolute path "by hand" work as desired). In order to do that I have a function where I call realpath as posted, if the pointer isn't NULL it should read the file calling the function under test, else I return -1. In main I call the function so what I expected was the function under test to read the file, insted I keep receiving -1, because the pointer is NULL; which is the errors I was referring to. I'll edit the question to make it more clear – cielocamminatore Jul 30 '22 at 09:51
  • `test;` does not do anything. To call the function, you need `test();`. Edit the question to provide an actual working [mre]. – Eric Postpischil Jul 30 '22 at 12:48
  • @cielocamminatore perfectly understandable, clear code is often better than slightly condensed code – Gregor Hartl Watters Jul 30 '22 at 14:35

1 Answers1

1

As your comment says "from the build directory I run ./test/executable", the present working directory is "dir/build". Starting from this directory, realpath() is right telling you that there is no "dir/build/../../test/src/file".

the busybee
  • 10,755
  • 3
  • 13
  • 30