diff --git a/libc-test/src/functionalext/supplement/stdio/fread.c b/libc-test/src/functionalext/supplement/stdio/fread.c index 067cb730dc415799038c58357d32dcfddf64b7c6..9e92e42682715b6b2f0de51aa134d31263b98e5d 100644 --- a/libc-test/src/functionalext/supplement/stdio/fread.c +++ b/libc-test/src/functionalext/supplement/stdio/fread.c @@ -13,6 +13,8 @@ * limitations under the License. */ +#include +#include #include #include "functionalext.h" @@ -116,11 +118,48 @@ void fread_0400(void) remove(ptr); } +/** + * @tc.name : fread_0500 + * @tc.desc : Verify that the return value of syscall have been processed correctly + * @tc.level : Level 2 + */ +#define FREAD_0500_BUFSZ (4097) +void fread_0500(void) +{ + pid_t pid = fork(); + if (pid == -1) { + perror("fread_0500 fork:"); + exit(-1); + } + + /* child */ + if (pid == 0) { + /* make sure parent opening the status file */ + sleep(1); + exit(-1); + } + + char buf[FREAD_0500_BUFSZ] = {0}; + sprintf(buf, "/proc/%d/status", pid); + FILE *fStatus = fopen(buf, "rb"); + EXPECT_PTRNE("fread_0500", fStatus, NULL); + + /* wait child exit, and status file of child will disappear */ + int status = 0; + pid_t w = wait(&status); + + /* read >4K data from file, check if return correctly */ + size_t rsize = fread(buf, 1, FREAD_0500_BUFSZ, fStatus); + EXPECT_EQ("fread_0500", rsize, 0); + fclose(fStatus); +} + TEST_FUN G_Fun_Array[] = { fread_0100, fread_0200, fread_0300, fread_0400, + fread_0500, }; int main(int argc, char *argv[]) @@ -131,4 +170,4 @@ int main(int argc, char *argv[]) } return t_status; -} \ No newline at end of file +} diff --git a/porting/linux/user/src/stdio/__stdio_read.c b/porting/linux/user/src/stdio/__stdio_read.c index 2511e34b9cb8f89ea51af95942c5c66faa974551..dd681e0b87eb629146bd863a13837befc24fb56b 100644 --- a/porting/linux/user/src/stdio/__stdio_read.c +++ b/porting/linux/user/src/stdio/__stdio_read.c @@ -3,7 +3,12 @@ size_t __stdio_readx(FILE *f, unsigned char *buf, size_t len) { - return syscall(SYS_read, f->fd, buf, len); + ssize_t cnt = syscall(SYS_read, f->fd, buf, len); + if (cnt <= 0) { + f->flags |= cnt ? F_ERR : F_EOF; + return 0; + } + return cnt; } size_t __stdio_read(FILE *f, unsigned char *buf, size_t len) @@ -21,8 +26,8 @@ size_t __stdio_read(FILE *f, unsigned char *buf, size_t len) return 0; } if (cnt <= iov_buf[0].iov_len) { - return cnt; - } + return cnt; + } cnt -= iov_buf[0].iov_len; f->rpos = f->buf; f->rend = f->buf + cnt; diff --git a/porting/linux/user/src/stdio/fread.c b/porting/linux/user/src/stdio/fread.c index 6819a1ebafbdc96725f2581a450df603e0b842e1..38b685c1a0a696e571f9d05fd2ef7b512a08cecf 100644 --- a/porting/linux/user/src/stdio/fread.c +++ b/porting/linux/user/src/stdio/fread.c @@ -69,8 +69,7 @@ size_t fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f) /* Read the remainder directly */ for (; l; l-=k, dest+=k) { k = f->readx(f, dest, l); - if (k <= 0) { - f->flags |= (k == 0 ? F_EOF : F_ERR); + if (!k) { break; } }