bytecodealliance / wasm-micro-runtime

WebAssembly Micro Runtime (WAMR)
Apache License 2.0
4.66k stars 577 forks source link

O_TRUNC, O_CREAT access mode do not print . #3565

Open Userzxcvbvnm opened 1 week ago

Userzxcvbvnm commented 1 week ago

Subject of the issue

In this situation, wamr fail to print O_TRUNC and O_CREAT. I'm not sure whether this is a bug.

Test case

The test case is:


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

int get_fd(const char *filename, int flags) {
    int fd = open(filename, flags);

    if (fd == -1) {
        printf("Get file descriptor of file %s failed!\n", filename);
        return -1;
    } else {
        printf("Get file descriptor of file %s succeed!\n", filename);
        return fd;
    }
}

void closebyfd(int fd) {
    if (close(fd) == -1) {
        printf("Close the file %d by descriptor failed!\n", fd);
    }
}

void fd_fdstat_set_flags_00006_ZJtyU(int fd) {
    printf("Enter function fd_fdstat_set_flags_00006_ZJtyU\n");

    int flags = fcntl(fd, F_GETFL);
    flags = flags | O_CREAT;

    if (fcntl(fd, F_SETFL, flags) == -1) {
        printf("Setting flags failed!\n");
    } else {
        printf("Setting flags succeed!\n");
    }
}

void print_flags(int fd){
    int flags1 = fcntl(fd, F_GETFL);
    int access_mode1 = flags1 & O_ACCMODE;
    if (access_mode1 == O_RDONLY) {
        printf("Access mode: Read Only\n");
    }
    if (access_mode1 == O_WRONLY) {
        printf("Access mode: Write Only\n");
    }
    if (access_mode1 == O_RDWR) {
        printf("Access mode: Read/Write\n");
    }
    if (flags1 & O_TRUNC) {
        printf("Access mode: O_TRUNC\n");
    }
    if (flags1 & O_APPEND) {
        printf("Access mode: O_APPEND\n");
    }
    if (flags1 & O_CREAT) {
        printf("Access mode: O_CREAT\n");
    }
    if (flags1 & O_EXCL) {
        printf("Access mode: O_EXCL\n");
    }
    if (flags1 & O_NONBLOCK) {
        printf("Access mode: Non-blocking\n");
    }
    if (flags1 & O_SYNC) {
        printf("Access mode: Synchronous Write\n");
    }
    if (flags1 & O_DSYNC) {
        printf("Access mode: Data Synchronization Write\n");
    }
}

int main() {

    int fd = get_fd("subfile_3", O_WRONLY | O_TRUNC);

    if (fd == -1) {
        return 1;
    }

    print_flags(fd);
    fd_fdstat_set_flags_00006_ZJtyU(fd);
    printf("After setting flags\n");
    print_flags(fd);

    closebyfd(fd);

    return 0;
}

Your environment

Ubuntu 20.04 x86_64 WAMR 1.3.2 and WAMR 1.2.3

Steps to reproduce

(1)compile to wasm:./wasi-sdk-21.0/bin/clang --target=wasm32-unkown-wasi --sysroot=./wasi-sdk-21.0/share/wasi-sysroot test.c -o test.wasm

(2)Running wasm: (Before run the Wasm file, file subfile_3 exists, and file size is 26.) iwasm --dir=. test.wasm

Expected behavior

prints:

Get file descriptor of file subfile_3 succeed!
Access mode: Write Only
Access mode: O_TRUNC
Enter function fd_fdstat_set_flags_00006_ZJtyU
Setting flags succeed!
After setting flags
Access mode: Write Only
Access mode: O_TRUNC
Access mode: O_CREAT

Actual behavior

WAMR prints:

Get file descriptor of file subfile_3 succeed!
Access mode: Write Only
Enter function fd_fdstat_set_flags_00006_ZJtyU
Setting flags succeed!
After setting flags
Access mode: Write Only
TianlongLiang commented 1 week ago

The fcntl function can only affect the file status flags, but O_TRUNC or O_CREAT is also an opening flag. O_CREAT is used when a file is initially opened to create the file if it does not already exist and O_TRUNC truncates the file to zero length, the file size should be zero when checked right after opening the file. They are not part of the file status flags that can be modified or retrieved using fcntl.

If you try a modifiable flag like O_APPEND, it will be set successfully:

Get file descriptor of file subfile_3 succeed!
Access mode: Write Only
Enter function fd_fdstat_set_flags_00006_ZJtyU
Setting flags succeed!
After setting flags
Access mode: Write Only
Access mode: O_APPEND