jvilk / BrowserFS

BrowserFS is an in-browser filesystem that emulates the Node JS filesystem API and supports storing and retrieving files from various backends.
Other
3.07k stars 218 forks source link

open(fname, O_RDONLY) fails with EINVALID #119

Closed jbaicoianu closed 8 years ago

jbaicoianu commented 9 years ago

I originally filed this bug against emscripten since it started happening after switching to a newer version of the compiler, but @kripken points out that it works when embedding the file directly, so it must be something to do with the interface between BrowserFS and Emscripten.

I'm trying to compile MAME with the latest version of Emscripten (incoming branch), and I'm getting EINVALID whenever I try to call open() on an existing file. Compiling with -s SYSCALL_DEBUG=1 shows this error:

syscall! 5,SYS_open
    (raw: "672")
    (str: "/mnt/myfile.zip")
    (raw: "32768")
    (raw: "0")
error: syscall failed with 22 (Invalid argument)
syscall return: -22

I've isolated this into a bare-bones test case and see the same error there:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
  char *fname = "/mnt/myfile.zip";
  printf("Opening file: %s\n", fname);
  int fd = open(fname, O_RDONLY);
  if (fd > 0) {
    printf("cool it worked, close it (fd=%d)\n", fd);
    close(fd);
  } else {
    printf("ERROR (fd=%d)\n", fd);
  }
  return 0;
}

Compile with: emcc opentest.c -o opentest.bc && emcc -O3 opentest.bc -s SYSCALL_DEBUG=1 -o opentest.js

I can read the file in the browser just fine via the FS object:

> FS.readFile('/mnt/myfile.zip')
< Uint8Array[3261863]

The file definitely exists on the FS according to the asm.js code as well, because the error code is different if I try to access a nonexistent file (as expected):

syscall! 5,SYS_open
    (raw: "672")
    (str: "/mnt/nofile.zip")
    (raw: "32768")
    (raw: "0")
error: syscall failed with 2 (No such file or directory)
syscall return: -2
jbaicoianu commented 9 years ago

Emscripten issue is here: kripken/emscripten#3678

jbaicoianu commented 9 years ago

I put together a simple harness for running this test. There are two versions:

working, no BFS - http://baicoianu.com/~bai/emscripten-open-test/opentest.html broken, with BFS - http://baicoianu.com/~bai/emscripten-open-test/opentest-bfs.html

Check the console to see the syscall debug messages.

jvilk commented 9 years ago

Thanks! I'll take a look at this tonight.

jvilk commented 9 years ago

OK. Emscripten is calling open on a stream with flags set to 32768.

The failure is happening because this line is supposed to return a string indicating the open mode (e.g. r), but 32768 is invalid; it contains a high-level bit which I believe indicates the stream's type. Thus, it doesn't return a string. flagsToPermissionString should zero the top bits.

Fixing...

jvilk commented 9 years ago

@jbaicoianu does this release work? https://github.com/jvilk/BrowserFS/releases/tag/v0.4.2

Let me know, and I'll promote it to an official release.

Thanks for reporting!

jbaicoianu commented 9 years ago

Yup, this fixes it, thanks for the quick turnaround!

jvilk commented 8 years ago

I pushed out v0.4.4 to NPM and Bower (0.4.2 was a pre-release, and I pushed out an erroneous version of 0.4.3), which contains the fix from the 0.4.2 pre-release. Officially closing (finally!).