Question

I have a daemon process that spawns several threads one of which handles HTTP requests. The handler is intended to return a file located in

resources/html/index.html

I have the following code:

void * read_file_ex(char *file_name, int32_t *data_len) {
   FILE *fp;
   fp = fopen(file_name, "r");
   ... // more code to fetch file contents
   fclose(fp);
}

void * read_file(char *file_name){
   return read_file_ex(file_name, NULL);
}

And in the thread, I call:

read_file("resources/html/index.html");    

The code crashes with a "Segmentation Fault" error when a request is made for that file.

When I use GDB to break at fopen, I notice that a NULL is returned and errno is set to 2 (File not found).

Also, when I change the code to use the absolute path of the file:

/usr/sbin/app/resources/html/index.html

then `fopen()' is able to find the index file and everything works fine.

Another thing to mention is that this error happens when run on Debian Linux but not on Ubuntu 12.04 which makes my question look even dumber.

I forgot to add that I am running the program from the same folder that contains the `resources' folder.

Was it helpful?

Solution

If the current directory of the process is not /usr/sbin/app (and it seems a bit unlikely that the current directory would be /usr/bin/app), then the relative pathname won't work. You should always check the return result from fopen() before attempting to use it. There are endless reasons why an open operation can fail even if you're in the correct directory, let alone when there's a chance that you aren't.

Note that if your process uses functions like daemon(), or is run via a daemonize program, the current directory can be changed to / even if you expected it to be somewhere else.

If you need to check the current directory of the process (a process has a single current directory common to all threads), you can use the getcwd() to get the current working directory.

If you need to change directory (again) after daemonizing your process, you can use chdir() to do so. There's also fchdir() which can be used to change back to a directory if you have an open file descriptor for the directory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top