1/* 2 * Copyright 2002-2013, 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 <errno_private.h> 11#include <syscalls.h> 12#include <syscall_utils.h> 13 14 15ssize_t 16readlink(const char *path, char *buffer, size_t bufferSize) 17{ 18 return readlinkat(AT_FDCWD, path, buffer, bufferSize); 19} 20 21 22ssize_t 23readlinkat(int fd, const char *path, char *buffer, size_t bufferSize) 24{ 25 size_t linkLen = bufferSize; 26 status_t status = _kern_read_link(fd, path, buffer, &linkLen); 27 if (status < B_OK) { 28 __set_errno(status); 29 return -1; 30 } 31 32 // If the buffer is big enough, null-terminate the string. That's not 33 // required by the standard, but helps non-conforming apps. 34 if (linkLen < bufferSize) 35 buffer[linkLen] = '\0'; 36 37 // _kern_read_link() returns the length of the link, but readlinkat() is 38 // supposed to return the number of bytes placed into buffer. If the 39 // buffer is larger than the link contents, then linkLen is the number 40 // of bytes written to the buffer. Otherwise, bufferSize bytes will have 41 // been written. 42 return min_c(linkLen, bufferSize); 43} 44 45 46int 47symlink(const char *toPath, const char *symlinkPath) 48{ 49 int status = _kern_create_symlink(-1, symlinkPath, toPath, 0); 50 51 RETURN_AND_SET_ERRNO(status); 52} 53 54 55int 56symlinkat(const char *toPath, int fd, const char *symlinkPath) 57{ 58 RETURN_AND_SET_ERRNO(_kern_create_symlink(fd, symlinkPath, toPath, 0)); 59} 60 61 62int 63unlink(const char *path) 64{ 65 int status = _kern_unlink(-1, path); 66 67 RETURN_AND_SET_ERRNO(status); 68} 69 70 71int 72unlinkat(int fd, const char *path, int flag) 73{ 74 if ((flag & AT_REMOVEDIR) != 0) 75 RETURN_AND_SET_ERRNO(_kern_remove_dir(fd, path)); 76 else 77 RETURN_AND_SET_ERRNO(_kern_unlink(fd, path)); 78} 79 80 81int 82link(const char *toPath, const char *linkPath) 83{ 84 int status = _kern_create_link(-1, linkPath, -1, toPath, true); 85 // Haiku -> POSIX error mapping 86 if (status == B_UNSUPPORTED) 87 status = EPERM; 88 89 RETURN_AND_SET_ERRNO(status); 90} 91 92 93int 94linkat(int toFD, const char *toPath, int linkFD, const char *linkPath, int flag) 95{ 96 RETURN_AND_SET_ERRNO(_kern_create_link(linkFD, linkPath, toFD, toPath, 97 (flag & AT_SYMLINK_FOLLOW) != 0)); 98} 99 100