Reputation: 163
This is supposed to be a program that reads multiple files within a directory and gets the frequency of a given word across those files, I know that part is incomplete for now.
fopen()
is returning null to files that exist and have permission 777
.
here is permissions from the terminal:
ra@ra-VirtualBox:~/Desktop/lab2/folder$ ls -l
total 12
-rwxrwxrwx 1 ra ra 21 mar 14 23:20 file1.txt
-rwxrwxrwx 1 ra ra 21 mar 14 23:20 file2.txt
-rwxrwxrwx 1 ra ra 21 mar 14 23:20 file3.txt
and here is the output obtained after using errno as suggested by this answer
with buf
printed
READING FILE: /home/ra/Desktop/lab2/file3.txt
fopen: No such file or directory
READING FILE: /home/ra/Desktop/lab2/file1.txt
fopen: No such file or directory
READING FILE: /home/ra/Desktop/lab2/file2.txt
fopen: No such file or directory
Edit: from output I noticed that realpath()
somehow erased an entire subdirectory before going to the file. /folder/ is not there and /home/ra/Desktop/lab2/file*.txt
does not exist!
And the code as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <pthread.h>
#include <limits.h> //For PATH_MAX
typedef struct {
FILE * fptr;
char * word;
}
inputFile;
void * readFrequenciesFromFile(void * path) {
static int count = 0;
}
int main(int argc, char * argv) {
int i;
char buf[PATH_MAX + 1];
char * wordToSearch = "test";
DIR * dir;
FILE * entry_file;
struct dirent * in_file;
// notice that the full directory is used here
// but buf somehow does magic and tells me the files
// are in /lab2/ directory
dir = opendir("/home/ra/Desktop/lab2/folder");
if (dir == NULL) {
printf("Error! Unable to read directory");
exit(1);
}
while ((in_file = readdir(dir)) != NULL) {
if (!strcmp(in_file -> d_name, "."))
continue;
if (!strcmp(in_file -> d_name, ".."))
continue;
realpath(in_file -> d_name, buf);
entry_file = fopen(buf, "r");
// printf("READING FILE: %s\n", buf);
if (!entry_file) perror("fopen");
if (entry_file != NULL) {
pthread_t tid;
inputFile * args = malloc(sizeof * args);
args -> fptr = malloc(sizeof entry_file);
args -> word = wordToSearch;
if (pthread_create( & tid, NULL, readFrequenciesFromFile, args) == 0) {
printf("Creating thread for file [%s] with ID %ld\n", in_file -> d_name, tid);
} else {
free(args);
}
fclose(entry_file);
}
}
closedir(dir);
return 0;
}
I will mention that I'm using Ubuntu 18.04 on VirtualBox Version 6.1.10 r138449 (Qt5.6.2)
Where do I begin to solve this problem? Is this even plausible or have I missed something?
Upvotes: 0
Views: 662
Reputation: 181932
You would have a better idea of what is going wrong if you consistently checked the return values of your function calls to recognize when they fail. In this case, you might have been clued in if you had checked the return value of the realpath()
calls.
I will suppose that your home directory is /home/ra
as your code suggests. Observe that the files you want to open are in /home/ra/Desktop/lab2/folder
. You are successfully opening that directory and reading its entries, and those entries give the base names of the files within -- that is, the names without any path components.
Whether you try to resolve those file names by opening the files or by computing their realpath()
s, you are doing so relative to the working directory. But the way you are launching the program, its working directory is /home/ra/Desktop/lab2
, not /home/ra/Desktop/lab2/folder
, so indeed the files the program is asking for don't exist.
Among your options are
Upvotes: 2
Reputation: 15018
I see ra@ra-VirtualBox:~/Desktop/lab2/folder$
has folder
but READING FILE: /home/ra/Desktop/lab2/file3.txt
does not. The problem is that the default directory is ~/Desktop/lab2/
, and that is what realpath()
uses; perhaps adding chdir()
will help:
chdir("/home/ra/Desktop/lab2/folder");
dir = opendir("/home/ra/Desktop/lab2/folder");
Upvotes: 1