From: Waldemar Kozaczuk <jwkozac...@gmail.com> Committer: Waldemar Kozaczuk <jwkozac...@gmail.com> Branch: master
vfs: implement symlinkat V2: The implementation uses vfs_fun_at2() instead of vfs_fun_at() to further simplify code. We also expose symlinkat though syscall. This patch implements the symlinkat() function and enhances tst-symlink.cc to unit test it. #Refs 1188 Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com> --- diff --git a/exported_symbols/osv_ld-musl.so.1.symbols b/exported_symbols/osv_ld-musl.so.1.symbols --- a/exported_symbols/osv_ld-musl.so.1.symbols +++ b/exported_symbols/osv_ld-musl.so.1.symbols @@ -1081,6 +1081,7 @@ swab swprintf swscanf symlink +symlinkat sync syscall sysconf diff --git a/exported_symbols/osv_libc.so.6.symbols b/exported_symbols/osv_libc.so.6.symbols --- a/exported_symbols/osv_libc.so.6.symbols +++ b/exported_symbols/osv_libc.so.6.symbols @@ -887,6 +887,7 @@ swprintf __swprintf_chk swscanf symlink +symlinkat sync syscall sysconf diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc --- a/fs/vfs/main.cc +++ b/fs/vfs/main.cc @@ -1132,6 +1132,19 @@ int symlink(const char *oldpath, const char *newpath) return 0; } +OSV_LIBC_API +int symlinkat(const char *oldpath, int newdirfd, const char *newpath) +{ + if (!oldpath) { + errno = EINVAL; + return -1; + } + + return vfs_fun_at2(newdirfd, newpath, [oldpath](const char * path) { + return symlink(oldpath, path); + }); +} + TRACEPOINT(trace_vfs_unlink, "\"%s\"", const char*); TRACEPOINT(trace_vfs_unlink_ret, ""); TRACEPOINT(trace_vfs_unlink_err, "%d", int); diff --git a/linux.cc b/linux.cc --- a/linux.cc +++ b/linux.cc @@ -496,6 +496,7 @@ OSV_LIBC_API long syscall(long number, ...) SYSCALL3(lseek, int, off_t, int); SYSCALL2(statfs, const char *, struct statfs *); SYSCALL3(unlinkat, int, const char *, int); + SYSCALL3(symlinkat, const char *, int, const char *); } debug_always("syscall(): unimplemented system call %d\n", number); diff --git a/tests/tst-symlink.cc b/tests/tst-symlink.cc --- a/tests/tst-symlink.cc +++ b/tests/tst-symlink.cc @@ -25,6 +25,9 @@ #define N1 "f1" #define N2 "f2_AAA" +#define N2B "f2_BBB" +#define N2B "f2_BBB" +#define N2C "f2_CCC" #define N3 "f3" #define N4 "f4" #define N5 "f5" @@ -91,6 +94,8 @@ int main(int argc, char **argv) #endif report(chdir(TESTDIR) == 0, "chdir"); + auto test_dir = opendir(TESTDIR); + report(test_dir, "opendir"); /* * test to check @@ -115,6 +120,10 @@ int main(int argc, char **argv) #else report(symlink(N1, N2) == 0, "symlink"); report(search_dir(TESTDIR, N2) == true, "search dir"); + report(symlinkat(N1, dirfd(test_dir), N2B) == 0, "symlinkat"); + report(search_dir(TESTDIR, N2B) == true, "search dir N2B"); + report(symlinkat(N1, AT_FDCWD, N2C) == 0, "symlinkat"); + report(search_dir(TESTDIR, N2C) == true, "search dir N2B"); #endif #if defined(READ_ONLY_FS) @@ -125,6 +134,8 @@ int main(int argc, char **argv) #else report(access(N1, R_OK | W_OK) == 0, "access"); report(access(N2, R_OK | W_OK) == 0, "access"); + report(access(N2B, R_OK | W_OK) == 0, "access"); + report(access(N2C, R_OK | W_OK) == 0, "access"); #endif rc = readlink(N2, path, sizeof(path)); @@ -157,6 +168,8 @@ int main(int argc, char **argv) error = errno; report(rc < 0 && errno == ENOENT, "ENOENT expected"); report(unlink(N2) == 0, "unlink"); + report(unlinkat(dirfd(test_dir),N2B,0) == 0, "unlinkat"); + report(unlinkat(dirfd(test_dir),N2C,0) == 0, "unlinkat"); /* * IO Tests 1: write(file), read(symlink), truncate(symlink) @@ -365,8 +378,6 @@ int main(int argc, char **argv) report(search_dir(D2, N5) == true, "Symlink search"); report(rename(D2, D3) == 0, "rename(d2, d3)"); - auto test_dir = opendir(TESTDIR); - report(test_dir, "opendir"); rc = readlinkat(dirfd(test_dir), D3, path, sizeof(path)); report(rc >= 0, "readlinkat"); path[rc] = 0; @@ -381,7 +392,6 @@ int main(int argc, char **argv) report(rc >= 0, "readlinkat"); path[rc] = 0; report(strcmp(path, D1) == 0, "readlinkat path"); - report(closedir(test_dir) == 0, "closedir(test_dir)"); rc = readlink(D3, path, sizeof(path)); report(rc >= 0, "readlink"); path[rc] = 0; @@ -399,6 +409,8 @@ int main(int argc, char **argv) report(rmdir(D4) == 0, "rmdir"); #endif + report(closedir(test_dir) == 0, "closedir(test_dir)"); + #if defined(READ_ONLY_FS) report(-1 == rmdir(TESTDIR) && errno == ENOTEMPTY, "rmdir"); #else -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/00000000000010e26f05dfffc67e%40google.com.