0

I have an application which runs in desktop (compiled with gcc 10 for x86_64 arch) and in emscripten (compiled with emscripten and run through nodejs). This code produces some files I need to save.

In the case of x86_64 its pretty simple, I just use std::ofstream, but in the case of emscripten, I am not sure how to proceed. I have read the wiki and it says the filesystem that emscripten provides is virtual and lives in memory, but they also say there are some ways to save files into the host filesystem (https://emscripten.org/docs/api_reference/Filesystem-API.html).

However, I haven't been able to save a file from emscripten directly to the host filesystem

I would appreciate an example on how to save a file using emscripten.

As an example of what I am trying to achieve,

main.cpp:

#include <fstream>

int main()
{
    std::ofstream os("log.txt", std::ios::trunc);
    os << "a";
}

compiled with

em++ main.cpp

and executed as

node a.out.wasm

The issue is that this doesn't saves the log.txt. How could I tell emscripten to write that file to my host filesystem?

jjcasmar
  • 1,387
  • 1
  • 18
  • 30
  • 2
    Isn't the observed behavior by-design, since if a web-assembly program could write to your host filesystem, then simply viewing the "wrong" web page could allow a malicious program to overwrite your files with garbage? – Jeremy Friesner Jun 27 '23 at 22:43
  • It is. Im asking how to bypass it, given that I'm writing the code (use case is to dump a file for debugging). Also, I'm running nodejs, not in a browser – jjcasmar Jun 27 '23 at 23:10
  • MeshLib does it somehow. [Here's the code](https://github.com/MeshInspector/MeshLib/blob/master/source/MRViewer/MRFileDialog.cpp), and [here](https://demo.meshinspector.com/) you can see it in action. But the nonfree license, so you can't just copypaste their solution. – HolyBlackCat Jun 29 '23 at 07:03
  • See https://github.com/emscripten-core/emscripten/blob/main/test/fs/test_nodefs_rw.c – zakki Jul 02 '23 at 23:58

1 Answers1

-1

Edit: @jjcasmar is correct, this option needs the file to be present at compile time, so my answer is wrong

You can use the --preload-file argument when compiling the code, to give the code access to the file:

em++ main.cpp --preload-file ./log.txt

You can see my other answer from this question.

TachyonicBytes
  • 700
  • 1
  • 8
  • So, how do you suggest I preload a file that doesn't exist and I want to create during the execution of the application? – jjcasmar Jun 28 '23 at 11:48
  • If I recall correctly, the file doesn't have to exist yet, in order for preload to work. I may be wrong, so to be safe, you can preload the entire directory. The syntax is the same, albeit a bit confusing because it's named `--preload-file`: `em++ main.cpp --preload-file ./` – TachyonicBytes Jun 28 '23 at 12:17
  • I thought that preloading a file basically means copying that file into the virtual filesystem the emscripten creates, and if I modify it, its going to modify the virtual copy, not the original file, no? At least, I understand that from the docs – jjcasmar Jun 28 '23 at 12:27
  • Yes, it seems that you are correct, I apologize. I will update my answer to reflect that. `NODEFS` seems like the most promising candidate for your problem, I will try to toy around with that when I get time, so I can correct the answer. – TachyonicBytes Jun 29 '23 at 06:51