summaryrefslogtreecommitdiff
path: root/src/libc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libc')
-rw-r--r--src/libc/include/stdio.h2
-rw-r--r--src/libc/stdio/misc.c30
-rw-r--r--src/libc/syscall.c4
3 files changed, 30 insertions, 6 deletions
diff --git a/src/libc/include/stdio.h b/src/libc/include/stdio.h
index 159bdca..d533025 100644
--- a/src/libc/include/stdio.h
+++ b/src/libc/include/stdio.h
@@ -83,7 +83,7 @@ int putchar(int c);
off_t lseek(int fd, off_t off, int whence);
int remove(const char *path);
-int rename(const char *old, const char *new);
+int rename(const char *oldpath, const char *newpath);
#define L_tmpnam (5 + 16 + 1)
char *tmpnam(char *s);
diff --git a/src/libc/stdio/misc.c b/src/libc/stdio/misc.c
index 7e8e746..6cd5b35 100644
--- a/src/libc/stdio/misc.c
+++ b/src/libc/stdio/misc.c
@@ -1,3 +1,6 @@
+#include <camellia.h>
+#include <camellia/flags.h>
+#include <camellia/syscalls.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -30,11 +33,28 @@ int remove(const char *path) {
return unlink(path);
}
-// TODO! VFSOP_MOVE
-int rename(const char *old, const char *new) {
- (void)old; (void)new;
- errno = ENOSYS;
- return -1;
+int rename(const char *oldpath, const char *newpath) {
+ // TODO require a duplex flag in open()
+ hid_t from, to;
+ from = camellia_open(oldpath, OPEN_RW);
+ if (from < 0) {
+ return -1;
+ }
+ to = camellia_open(newpath, OPEN_WRITE | OPEN_CREATE);
+ if (to < 0) {
+ close(from);
+ return -1;
+ }
+
+ long ret = _sys_duplex(from, to, DUPLEX_REMOVE);
+ close(from);
+ close(to);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ } else {
+ return 0;
+ }
}
// TODO tmpnam
diff --git a/src/libc/syscall.c b/src/libc/syscall.c
index f44c775..c6e3762 100644
--- a/src/libc/syscall.c
+++ b/src/libc/syscall.c
@@ -98,6 +98,10 @@ hid_t _sys_getnull(int flags) {
return (hid_t)_syscall(_SYS_GETNULL, (long)flags, 0, 0, 0, 0);
}
+long _sys_duplex(hid_t from, hid_t to, int flags) {
+ return _syscall(_SYS_DUPLEX, (long)from, (long)to, (long)flags, 0, 0);
+}
+
long _sys_execbuf(void __user *buf, size_t len) {
return _syscall(_SYS_EXECBUF, (long)buf, (long)len, 0, 0, 0);
}