xref: /haiku/src/system/libroot/posix/unistd/link.c (revision 481f986b59e7782458dcc5fe98ad59a57480e5db)
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