5

I am working on an embedded system with no filesystem and I need to execute programs that take input data from files specified via command like arguments or directly from stdin.

I know it is possible to bake-in the file data with the binary using the method from this answer: C/C++ with GCC: Statically add resource files to executable/library but currently I would need to rewrite all the programs to access the data in a new way.

Is it possible to bake-in a text file, for example, and access it using a fake file pointer to stdin when running the program?

clauniel
  • 53
  • 5

2 Answers2

4

If your system is an OS-less bare-metal system, then your C library will have "retargetting" stubs or hooks that you need to implement to hook the library into the platform. This will typically include low-level I/O functions such as open(), read(), write(), seek() etc. You can implement these as you wish to implement the basic stdin, stdout, stderr streams (in POSIX and most other implementations they will have fixed file descriptors 0, 1 and 2 respectively, and do not need to be explicitly opened), file I/O and in this case for managing an arbitrary memory block.

open() for example will be passed a file or device name (the string may be interpreted any way you wish), and will return a file descriptor. You might perhaps recognise "cfgdata:" as a device name to access your "memory file", and you would return a unique descriptor that is then passed into read(). You use the descriptor to reference data for managing the stream; probably little more that an index that is incremented by the number if characters read. The same index may be set directly by the seek() implementation.

Once you have implemented these functions, the higher level stdio functions or even C++ iostreams will work normally for the devices or filesystems you have supported in your low level implementation.

Clifford
  • 88,407
  • 13
  • 85
  • 165
2

As commented, you could use the POSIX fmemopen function. You'll need a libc providing it, e.g. musl-libc or possibly glibc. BTW for benchmarking purposes you might install some tiny Linux-like OS on your hardware, e.g. uclinux

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Installing an OS is not an option, I will try fmemopen. Thanks. – clauniel Feb 27 '15 at 17:57
  • uCLinux *is* Linux and is *not* tiny. – Clifford Feb 27 '15 at 19:18
  • 1
    @BasileStarynkevitch : Indeed but uCLinux's main trick is running Linux without an MMU (arguably defeating much of the benefit of Linux!) rather than running in small space (not much change from 4Mb of RAM for example). Implementing the I/O stubs for an embedded C library to support file/stream I/O is trivial and requires a few hundred bytes only. It's a sledge-hammer for a nut in this case perhaps. – Clifford Feb 27 '15 at 19:40