#fopen() cannot read files from different directories

49 messages · Page 1 of 1 (latest)

glossy bough
#

Hello, quick question.

Why wouldn't the file open? The directory I am accessing is correct when I tried ls /path/to/*.bin , but it does not recognise the path as it seems.

uint8_t ram[0x10000];

int 
load_file(m65xx_core_t* const m, const char* file_to_load, uint16_t addr)
{
printf("Trying to open file: '%s'\n", file_to_load);
  FILE *f = fopen(file_to_load, "rb");

  if(f == NULL) 
  {
    fprintf(stderr, "**" RED " Error " RESET "** " "file couldn't be opened");
    return 1;
  }

  fseek(f, 0, SEEK_END);
  size_t file_size = ftell(f);
  rewind(f);

  if(file_size + addr > 0x10000) 
  {
    fprintf(stderr, "\n**" RED "Error" RESET "** " "file size to large\n"); 
    fclose(f); 
    return 1;
  }

  size_t file_read = fread(&ram[addr], sizeof(uint8_t), file_size, f);

  if(file_read != file_size) 
  {
    fprintf(stderr, "**" RED " Error " RESET "** " "file \"%s\" couldn't be read into memory" , file_to_load); 
    fclose(f); 
    return 1;
  }

  fclose(f);
  return 0;
}

static int execute_allsuiteasm(m65xx_core_t* const m, const char* file_to_load) {
    memset(ram, 0, 0x10000);

    // Check if the file was loaded successfully
    if (load_file(m, file_to_load, 0x4000) != 0) {
        fprintf(stderr, "**" RED " Error " RESET "** failed to load file. Aborting execution.\n");
        return 1;  // Exit if file loading fails.
    }

    m65xx_power(m);

    printf("\n** file loaded: " BOLD "%s" RESET " **\n", file_to_load);

    while (1) {
        m65xx_run(m);
        if (m->pc == 0x45C0) {
            if (rb(m, 0x0210) == 0xFF) {
                printf(GREEN "✓" RESET " - test passed!\n");
            } else {
                printf(RED "✘" RESET " - test failed!\n");
            }
            break;
        }
    }

    return 0;
}

main(): execute_allsuiteasm(&m, "../tests/AllSuiteA.bin");
sacred socketBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

glossy bough
#

The error message:

 ________    ________    ______       ________
|\   ____\  |\   ____\  /___   \     |\   __  \
\ \  \      \ \ \ ___/  \___ \  \    \ \  \|\  \
 \ \  \_____ \ \ \_____     \ \  \    \ \  \|\  \
  \ \    _  \ \ \_______\    \ \  \    \ \  \|\  \
   \ \  \|\  \ \/______\ \    \ \  \    \ \  \|\  \
    \ \_______\ ________\ \  __\_\  \___ \ \_______\
     \|_______| \_\________\ \_\________\ \|_______|
Trying to open file: '../tests/AllSuiteA.bin'
** Error ** file couldn't be opened** Error ** failed to load file. Aborting execution.
❯ ls -l ../tests/AllSuiteA.bin
.rw-r--r--@ 49k cupko 13 Jul 14:42 ../tests/AllSuiteA.bin
~/Documents/dev/c/emulation/m65xx/src main* ❯
#
ls -l
drwxr-xr-x@   - cupko  6 Nov 18:15 include
.rw-r--r--@ 670 cupko  6 Nov 18:30 Makefile
drwxr-xr-x@   - cupko  6 Nov 18:49 src
drwxr-xr-x@   - cupko  5 Nov 23:10 tests
~/Documents/dev/c/emulation/m65xx main* ❯
mossy hull
#

permission issues maybe?

#

also what is the working dir

#

where is the binary executed from

glossy bough
#

The directories are both readable and writeable

mossy hull
#

so if the binary is in m65xx, you should open tests/AllSuiteA.bin

sharp narwhal
#

also using perror is good, as it would tell you the problem ;p

#

like "file not found"

glossy bough
mossy hull
#

thats not how it works

sharp narwhal
#

it matters where the binary is executed

glossy bough
mossy hull
#

yes

sharp narwhal
#

the path is interpreted during runtime

#

it doesn't even matter where the binary is

glossy bough
#

I did not know that

sharp narwhal
#

it matters what is your working directory

#

as you can give full path to your binary and run it from somewhere else

#

and then it will still fail

#

because the path will be relative to cwd

#

it will work if you run it from src though :P

sharp narwhal
glossy bough
#

But

sharp narwhal
#

perror prints your messages and message for errno

#

to stderr

glossy bough
#

My executable file is in the root directory though and I did ../tests/AllSuiteASM for the file path

#

Shouldn’t it still work tho

#

Since I change the directory to .. first

sharp narwhal
#

I wonder what do you mean by "root directory"

#

root directory would me normally literally /

#

which wouldn't be a usual place to store your files

mossy hull
#

prob refers to workspace dir

glossy bough
#
❯ make
[compiling] src/debugger.c
[compiling] src/m65xx.c
[compiling] src/main.c
src/main.c: In function ‘load_file’:
src/main.c:21:31: warning: unused parameter ‘m’ [-Wunused-parameter]
   21 | load_file(m65xx_core_t* const m, const char* file_to_load, uint16_t addr)
      |           ~~~~~~~~~~~~~~~~~~~~^
[linking] src/debugger.o src/m65xx.o src/main.o
[produced] m65xx
❯ ls
include  m65xx  Makefile  src  tests
❯ ls -l
drwxr-xr-x@   - cupko  6 Nov 18:15 include
.rwxr-xr-x@ 78k cupko  6 Nov 19:04 m65xx
.rw-r--r--@ 670 cupko  6 Nov 18:30 Makefile
drwxr-xr-x@   - cupko  6 Nov 19:04 src
drwxr-xr-x@   - cupko  5 Nov 23:10 tests
~/Documents/dev/c/emulation/m65xx main* ❯

m65xx is the executable

sharp narwhal
#

so .. goes to ~/Documents/dev/c

glossy bough
sharp narwhal
#

and then looks for tests there

#

again, .. are relative to a directory you are in when launching the executable, you, not the executable per se

#

that convention is convenient for your user passing you a path, e.g. imagine you were writing program showme that would display a file, you have showme in c:\myprogs\showme, you are in a directory c:\foo\bar and you want to display file c:\foo\file.txt

#

then being in c:\foo\bar you would run c:\myprogs\showme ../file.txt (or if c:\myprogs was in PATH, then it would be just showme)

glossy bough
#

oh

#

I understand now

#

thank you

sacred socketBOT
#

@glossy bough Has your question been resolved? If so, type !solved :)

glossy bough
#

!solved