mortbopet/Ripes

Open ecall does not support read only mode

lukasrad02 opened this issue · 1 comments

It is not possible to open a file in read only mode by passing 0 as flags parameter. The file will have the state QIODevice::NotOpen instead.

This seems to be related to a bug in the implementation of the ecall. Parsing the flags does not work for a 0 flag, as flags & O_RDONLY always evaluates to false since O_RDONLY equals 0:

const auto qtOpenFlags = // Translate from stdlib file flags to Qt flags
(flags & O_RDONLY ? QIODevice::ReadOnly : QIODevice::NotOpen) |
(flags & O_WRONLY ? QIODevice::WriteOnly : QIODevice::NotOpen) |
(flags & O_RDWR ? QIODevice::ReadWrite : QIODevice::NotOpen) |
(flags & O_TRUNC ? QIODevice::Truncate : QIODevice::Append) |
(flags & O_EXCL ? QIODevice::NewOnly : QIODevice::NotOpen);

The only way to open a file for reading is using the read-write mode and then seeking back to position 0 in the file.

Not working code using O_RDONLY

.data

filename: .string "/tmp/test.txt"

.text

la a0 filename # a0: Pointer to filename
li a1 0 # Readonly flag
li a7 1024 # "Open" ecall
ecall # Returns: File descriptor

li a1 0x2000 # a1: buffer
li a2 100 # a2: max. buffer size
li a7 63 # "Read" ecall
ecall

li a0 0x2000
li a7 4 # "Print String" ecall
ecall

Workaround using O_RDWR and seek

.data

filename: .string "/tmp/test.txt"

.text

la a0 filename # a0: Pointer to filename
li a1 2 # Read-Write flag
li a7 1024 # "Open" ecall
ecall # Returns: File descriptor
mv s0 a0 # Save fd, since it will be overwritten by return values

nop # file descriptor stays in a0
li a1 0 # Offset 0
li a2 0 # From the beginning
li a7 62 # "Seek" ecall
ecall

mv a0 s0 # Get back file descriptor
li a1 0x2000 # a1: buffer
li a2 100 # a2: max. buffer size
li a7 63 # "Read" ecall
ecall

li a0 0x2000
li a7 4 # "Print String" ecall
ecall
raccog commented

@lukasrad02 Thank you for reporting this bug!

I submitted a pull request here that fixes it: #325.