Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <assert.h>
8#include <errno.h>
9#include <fcntl.h>
10#include <stdio.h>
11#include <string.h>
12#include <sys/stat.h>
13#include <syscall.h>
14#include <unistd.h>
15
16extern "C" {
17
18// https://pubs.opengroup.org/onlinepubs/9699919799/functions/umask.html
19mode_t umask(mode_t mask)
20{
21 return syscall(SC_umask, mask);
22}
23
24// https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html
25int mkdir(char const* pathname, mode_t mode)
26{
27 return mkdirat(AT_FDCWD, pathname, mode);
28}
29
30// https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdirat.html
31int mkdirat(int dirfd, char const* pathname, mode_t mode)
32{
33 if (!pathname) {
34 errno = EFAULT;
35 return -1;
36 }
37 int rc = syscall(SC_mkdir, dirfd, pathname, strlen(pathname), mode);
38 __RETURN_WITH_ERRNO(rc, rc, -1);
39}
40
41// https://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html
42int chmod(char const* pathname, mode_t mode)
43{
44 return fchmodat(AT_FDCWD, pathname, mode, 0);
45}
46
47// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmodat.html
48int fchmodat(int dirfd, char const* pathname, mode_t mode, int flags)
49{
50 if (!pathname) {
51 errno = EFAULT;
52 return -1;
53 }
54
55 if (flags & ~AT_SYMLINK_NOFOLLOW) {
56 errno = EINVAL;
57 return -1;
58 }
59
60 Syscall::SC_chmod_params params {
61 dirfd,
62 { pathname, strlen(pathname) },
63 mode,
64 !(flags & AT_SYMLINK_NOFOLLOW)
65 };
66 int rc = syscall(SC_chmod, ¶ms);
67 __RETURN_WITH_ERRNO(rc, rc, -1);
68}
69
70// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchmod.html
71int fchmod(int fd, mode_t mode)
72{
73 int rc = syscall(SC_fchmod, fd, mode);
74 __RETURN_WITH_ERRNO(rc, rc, -1);
75}
76
77// https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkfifo.html
78int mkfifo(char const* pathname, mode_t mode)
79{
80 return mknod(pathname, mode | S_IFIFO, 0);
81}
82
83static int do_stat(int dirfd, char const* path, struct stat* statbuf, bool follow_symlinks)
84{
85 if (!path) {
86 errno = EFAULT;
87 return -1;
88 }
89 Syscall::SC_stat_params params { { path, strlen(path) }, statbuf, dirfd, follow_symlinks };
90 int rc = syscall(SC_stat, ¶ms);
91 __RETURN_WITH_ERRNO(rc, rc, -1);
92}
93
94// https://pubs.opengroup.org/onlinepubs/9699919799/functions/lstat.html
95int lstat(char const* path, struct stat* statbuf)
96{
97 return do_stat(AT_FDCWD, path, statbuf, false);
98}
99
100// https://pubs.opengroup.org/onlinepubs/9699919799/functions/stat.html
101int stat(char const* path, struct stat* statbuf)
102{
103 return do_stat(AT_FDCWD, path, statbuf, true);
104}
105
106// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstat.html
107int fstat(int fd, struct stat* statbuf)
108{
109 int rc = syscall(SC_fstat, fd, statbuf);
110 __RETURN_WITH_ERRNO(rc, rc, -1);
111}
112
113// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fstatat.html
114int fstatat(int fd, char const* path, struct stat* statbuf, int flags)
115{
116 return do_stat(fd, path, statbuf, !(flags & AT_SYMLINK_NOFOLLOW));
117}
118
119// https://pubs.opengroup.org/onlinepubs/9699919799/functions/futimens.html
120int futimens(int fd, struct timespec const times[2])
121{
122 return utimensat(fd, "", times, 0);
123}
124}