diff --git a/include/stdio.h b/include/stdio.h index 2fccc735d84a6789fcf1f3e4405972de80370036..7bf045b98563ec634e08cb445bafdac8a73b2557 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -155,6 +155,7 @@ int putchar_unlocked(int); ssize_t getdelim(char **__restrict, size_t *__restrict, int, FILE *__restrict); ssize_t getline(char **__restrict, size_t *__restrict, FILE *__restrict); int renameat(int, const char *, int, const char *); +int renameat2(int, const char *, int, const char *, unsigned int); char *ctermid(char *); #define L_ctermid 20 #endif diff --git a/libc-test/src/functional/fopencookie_test.c b/libc-test/src/functional/fopencookie_test.c new file mode 100755 index 0000000000000000000000000000000000000000..eba7737425373643a24008e94c8361a37b01d33a --- /dev/null +++ b/libc-test/src/functional/fopencookie_test.c @@ -0,0 +1,150 @@ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include "test.h" +#include +#include +#include +#include +#include + +struct cookie +{ + size_t pos; + size_t len; + size_t size; + char *buf; +}; + +ssize_t mread(void *f, char *buf, size_t len) +{ + struct cookie *c = f; + if (c->pos > c->len) + { + return 0; + } + else if (c->pos + len > c->len) + { + len = c->len - c->pos; + } + + memcpy(buf, c->buf + c->pos, len); + c->pos += len; + return len; +} + +ssize_t mwrite(void *f, const char *buf, size_t len) +{ + struct cookie *c = f; + char *new_buf; + if (c->pos + len > c->size) + { + while (c->pos + len > c->size) + { + c->size *= 2; + } + new_buf = realloc(c->buf, c->size); + if (new_buf == NULL) + { + return -1; + } + else + { + c->size = c->pos + len; + c->buf = new_buf; + } + } + + memcpy(c->buf + c->pos, buf, len); + c->pos += len; + if (c->pos > c->len) + { + c->len = c->pos; + } + return len; +} + +int mseek(void *f, off_t *off, int whence) +{ + struct cookie *c = f; + off_t new_pos; + if (whence == 0) + { + new_pos = *off; + } + else if (whence == 1) + { + new_pos = *off + c->pos; + } + else if (whence == 2) + { + new_pos = *off + c->len; + } + else + { + return -1; + } + if (new_pos < 0) + { + return -1; + } + + c->pos = new_pos; + *off = new_pos; + + return 0; +} + +int mclose(void *f) +{ + struct cookie *c = f; + free(c->buf); + c->buf = NULL; + return 0; +} + +int main(int argc, char *argv[]) +{ + cookie_io_functions_t io_func = {.read = mread, .write = mwrite, .seek = mseek, .close = mclose}; + FILE *file; + struct cookie myc; + size_t nread; + char buf[50]; + myc.buf = malloc(4); + if (myc.buf == NULL) + { + t_error("fopencookie malloc failed\n"); + return 1; + } + myc.pos = 0; + myc.len = 0; + myc.size = 4; + + file = fopencookie(&myc, "w+", io_func); + if (file == NULL) + { + t_error("create fopencookie failed\n"); + return 1; + } + if (fputs("fopencookie", file) == EOF) + { + t_error("fopencookie fputs failed\n"); + return 1; + } + if (fseek(file, 0, SEEK_SET) == -1) + { + t_error("fopencookie fseek failed\n"); + return 1; + } + nread = fread(buf, 1, 2, file); + if (nread == 0) + { + if (ferror(file) != 0) + { + t_error("fopencookie fread failed\n"); + return 1; + } + } + fclose(file); + return 0; +} \ No newline at end of file diff --git a/libc-test/src/functional/renameat2_test.c b/libc-test/src/functional/renameat2_test.c new file mode 100755 index 0000000000000000000000000000000000000000..5dfc6689a164c0ee9334dea549a6de14e22fcd5d --- /dev/null +++ b/libc-test/src/functional/renameat2_test.c @@ -0,0 +1,56 @@ + +#include "test.h" +#include +#include +#include +#include +#include +#include + +int main(void) +{ + int oldfd, newfd; + char oldPath[] = "/data/renameat2.txt"; + char newPath[] = "/data/newrenameat2.txt"; + const char *msg = "test code"; + int len = strlen(msg); + char buf[1024] = {0}; + + if ((oldfd = creat(oldPath, S_IWUSR)) < 0) + { + t_error("%s creat oldfd failed\n", __func__); + } + if ((newfd = creat(newPath, S_IWUSR)) < 0) + { + t_error("%s creat newfd failed\n", __func__); + } + close(oldfd); + close(newfd); + oldfd = open(oldPath, O_RDWR); + int wresult = write(oldfd, msg, len); + if (wresult != len) + { + t_error("%s write get result is %d not want %d\n", __func__, wresult, len); + } + close(oldfd); + if (renameat2(oldfd, oldPath, newfd, newPath, 0) == -1) + { + t_error("%s renameat2 failed\n", __func__); + return 1; + } + newfd = open(newPath, O_RDWR); + int bytes = read(newfd, buf, len); + if (bytes == -1) + { + t_error("%s read file failed\n", __func__); + return 1; + } + if (strcmp(msg, buf)) + { + t_error("%s wrong string written to file\n", __func__); + return 1; + } + close(newfd); + remove(newPath); + return 0; +} diff --git a/libc-test/src/functional/test_src_functional.gni b/libc-test/src/functional/test_src_functional.gni index e038cffb718b6ccbcdebb2008f302a009dac0b6a..b5c1c7aad697122234af26a6f82a9e1320573a15 100644 --- a/libc-test/src/functional/test_src_functional.gni +++ b/libc-test/src/functional/test_src_functional.gni @@ -82,6 +82,8 @@ functional_list = [ "dlclose_reset", "atexit_dlclose", "exit_constructor", + "renameat2_test", + "fopencookie_test", ] if (use_pthread_cancel) { diff --git a/libc.map.txt b/libc.map.txt index 1346be0868a3901646ab2a88e5f6720122f79c8d..642e6c6a93ee2a108a564470d5ad7f1e2d5a00ab 100644 --- a/libc.map.txt +++ b/libc.map.txt @@ -1528,6 +1528,7 @@ remquol; rename; renameat; + renameat2; res_init; res_mkquery; res_query; diff --git a/porting/linux/user/include/stdio.h b/porting/linux/user/include/stdio.h index 5b8620036e29a0c45887eba0f2fc4430a05eec54..7210ac0435bc0a58387c450460498f0f36c6f1aa 100644 --- a/porting/linux/user/include/stdio.h +++ b/porting/linux/user/include/stdio.h @@ -155,6 +155,7 @@ int putchar_unlocked(int); ssize_t getdelim(char **__restrict, size_t *__restrict, int, FILE *__restrict); ssize_t getline(char **__restrict, size_t *__restrict, FILE *__restrict); int renameat(int, const char *, int, const char *); +int renameat2(int, const char *, int, const char *, unsigned int); char *ctermid(char *); #define L_ctermid 20 #endif diff --git a/porting/liteos_a/kernel/include/stdio.h b/porting/liteos_a/kernel/include/stdio.h index 31ac1b52aa663c992e8a4c7472b383c5b0d90312..1c4046c942df74d8b1eae08291837bf7baab70f5 100644 --- a/porting/liteos_a/kernel/include/stdio.h +++ b/porting/liteos_a/kernel/include/stdio.h @@ -154,6 +154,7 @@ int putchar_unlocked(int); ssize_t getdelim(char **__restrict, size_t *__restrict, int, FILE *__restrict); ssize_t getline(char **__restrict, size_t *__restrict, FILE *__restrict); int renameat(int, const char *, int, const char *); +int renameat2(int, const char *, int, const char *, unsigned int); char *ctermid(char *); #define L_ctermid 20 #endif diff --git a/porting/liteos_m/kernel/include/stdio.h b/porting/liteos_m/kernel/include/stdio.h index 3604198c3e503aba5335919cc3f429b7a8350beb..ba48530b174f3aee93c44a1060d65d4bb9f400e9 100644 --- a/porting/liteos_m/kernel/include/stdio.h +++ b/porting/liteos_m/kernel/include/stdio.h @@ -152,6 +152,7 @@ int putchar_unlocked(int); ssize_t getdelim(char **__restrict, size_t *__restrict, int, FILE *__restrict); ssize_t getline(char **__restrict, size_t *__restrict, FILE *__restrict); int renameat(int, const char *, int, const char *); +int renameat2(int, const char *, int, const char *, unsigned int); char *ctermid(char *); #define L_ctermid 20 #endif diff --git a/src/stdio/fopencookie.c b/src/stdio/fopencookie.c index da042fe8adc37c7468aace6a29ae1c0b3796cc81..6233744a0bde797e9247976e78f19f3b2d982dd1 100644 --- a/src/stdio/fopencookie.c +++ b/src/stdio/fopencookie.c @@ -126,6 +126,7 @@ FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t iofuncs) /* Initialize op ptrs. No problem if some are unneeded. */ f->f.read = cookieread; + f->f.readx = cookieread; f->f.write = cookiewrite; f->f.seek = cookieseek; f->f.close = cookieclose; diff --git a/src/unistd/renameat.c b/src/unistd/renameat.c index c3b40a258b2822214ce05a0cf1788d9af6298067..40801387e446d4656ccdf46b2f9fb51c6515b537 100644 --- a/src/unistd/renameat.c +++ b/src/unistd/renameat.c @@ -9,3 +9,8 @@ int renameat(int oldfd, const char *old, int newfd, const char *new) return syscall(SYS_renameat2, oldfd, old, newfd, new, 0); #endif } + +int renameat2(int oldfd, const char *old, int newfd, const char *new, unsigned int flags) +{ + return syscall(SYS_renameat2, oldfd, old, newfd, new, flags); +} \ No newline at end of file