1 /* 2 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <errno.h> 8 #include <unistd.h> 9 10 #include <syscalls.h> 11 #include <syscall_utils.h> 12 13 14 ssize_t 15 readlink(const char *path, char *buffer, size_t bufferSize) 16 { 17 return readlinkat(AT_FDCWD, path, buffer, bufferSize); 18 } 19 20 21 ssize_t 22 readlinkat(int fd, const char *path, char *buffer, size_t bufferSize) 23 { 24 size_t linkLen = bufferSize; 25 status_t status = _kern_read_link(fd, path, buffer, &linkLen); 26 if (status < B_OK) { 27 errno = status; 28 return -1; 29 } 30 31 // If the buffer is big enough, null-terminate the string. That's not 32 // required by the standard, but helps non-conforming apps. 33 if (linkLen < bufferSize) 34 buffer[linkLen] = '\0'; 35 36 return linkLen; 37 } 38 39 40 int 41 symlink(const char *toPath, const char *symlinkPath) 42 { 43 int status = _kern_create_symlink(-1, symlinkPath, toPath, 0); 44 45 RETURN_AND_SET_ERRNO(status); 46 } 47 48 49 int 50 symlinkat(const char *toPath, int fd, const char *symlinkPath) 51 { 52 RETURN_AND_SET_ERRNO(_kern_create_symlink(fd, symlinkPath, toPath, 0)); 53 } 54 55 56 int 57 unlink(const char *path) 58 { 59 int status = _kern_unlink(-1, path); 60 61 RETURN_AND_SET_ERRNO(status); 62 } 63 64 65 int 66 unlinkat(int fd, const char *path, int flag) 67 { 68 if ((flag & AT_REMOVEDIR) != 0) 69 RETURN_AND_SET_ERRNO(_kern_remove_dir(fd, path)); 70 else 71 RETURN_AND_SET_ERRNO(_kern_unlink(fd, path)); 72 } 73 74 75 int 76 link(const char *toPath, const char *linkPath) 77 { 78 RETURN_AND_SET_ERRNO(_kern_create_link(-1, linkPath, -1, toPath, true)); 79 } 80 81 82 int 83 linkat(int toFD, const char *toPath, int linkFD, const char *linkPath, int flag) 84 { 85 RETURN_AND_SET_ERRNO(_kern_create_link(linkFD, linkPath, toFD, toPath, 86 (flag & AT_SYMLINK_FOLLOW) != 0)); 87 } 88 89