mortbopet / Ripes

A graphical processor simulator and assembly editor for the RISC-V ISA
https://ripes.me/
MIT License
2.45k stars 272 forks source link

write system call fails #196

Open matsievskiysv opened 2 years ago

matsievskiysv commented 2 years ago

Hello! I'm having trobble using write system call. The following program is supposed to open file, write a string to it and close file. open system call creates file with 644 permissions but write always fails. Call arguments appear to be in order. What could be the problem?

.data
greeting:
        .asciz "hello world"
greeting_length:
        .word 11
file_address:
        .asciz "/tmp/hello_world.txt"
file_error:
        .asciz "cannot open file"
write_error:
        .asciz "cannot write to file"
success:
        .asciz "Success! Wrote greeting to "

.text
        la a0 file_address
        call open_file
        add s0 a0 zero
        la a1 greeting
        lw a2 greeting_length
        call write_file
        add a0 s0 zero
        call close_file
        la a0 success
        call print_string
        la a0 file_address
        call print_string
        jal end

open_file:
        ## a0 - file string address
        addi a7 zero 1024
        addi a1 zero 0x1 # O_WRONLY
        ori a1 a1 0x200 # O_CREAT
        ecall
        addi a1 zero -1
        beq a0 a1 open_file_error
        ret

close_file:
        ## a0 - file descriptor
        addi a7 zero 57
        ecall
        ret

write_file:
        ## a0 - file descriptor
        ## a1 - string address
        ## a2 - string length
        addi a7 zero 64
        ecall
        addi a1 zero -1
        beq a0 a1 write_file_error
        ret

open_file_error:
        la a0 file_error
        call print_string
        jal end

write_file_error:
        la a0 write_error
        call print_string
        jal end

print_string:
        ## a0 - string address
        addi a7 zero 4
        ecall
        ret

end:
        nop
mortbopet commented 2 years ago

Hi @matsievskiysv - sorry for the long delay, been having a lot of stuff IRL taking priority. I hope to get back to you in one of the following days!

HotMercury commented 7 months ago

Hi @matsievskiysv

According to the code in systemio.h at line 80,

 static constexpr int O_RDONLY = 0x00000000;
 static constexpr int O_WRONLY = 0x00000001;
 static constexpr int O_RDWR = 0x00000002;

which defines the value of the flags used by the open syscall.

However, it cannot write data into the file correctly, if we only set O_WRONLY when calling open syscall.

Looking at the conditional statements at lines 408-409, it input fd and 3 as parameter

if (!FileIOData::fdInUse(fd, O_WRONLY | O_RDWR))

and then checks for the existence of the "write" flag using fdInUse at line193

else if ((fileFlags[fd] & flag) == static_cast<unsigned>(flag)) 

it requires the flag to be 0x3 to be true. Therefore, setting it only to O_WRONLY may result in a write failure.

Hi @mortbopet

Ideally, writing to a file should be allowed as long as it satisfies either O_WRONLY or O_RDWR. However, here it is specified that both conditions must be met for a write operation to proceed. I would like to inquire whether the author has any specific reason for this additional requirement.

mortbopet commented 7 months ago

might this be related to https://github.com/mortbopet/Ripes/issues/316 - and subsequently, solved in https://github.com/mortbopet/Ripes/pull/325?