0

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?

Rami Raghfan
  • 151
  • 12

2 Answers2

2

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

  • run the program from the folder containing the files
  • form correct paths to the files with which to open them -- either correct absolute paths or correct paths relative to the actual working directory.
John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • I was under the assumption that using ```/home/ra``` is the absolute path.. because using tilde in the path does not work, the program outputs ```Error! Unable to read directory``` – Rami Raghfan Mar 15 '21 at 00:51
  • @RamiRaghfan note: `~` is expanded by your SHELL, not C++, so there is no tilde-expansion. Generally, you will need to keep an array of `PATH_MAX` length to form the absolute path using either a couple of `strcpy()` and `strcat()` or using one `sprintf()` – David C. Rankin Mar 15 '21 at 01:20
  • @RamiRaghfan, `/home/ra` is *an* absolute path, but it is not a path to the location of the files you want to open. – John Bollinger Mar 15 '21 at 04:42
1

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");
Ken Y-N
  • 14,644
  • 21
  • 71
  • 114