1/*
2 * Copyright 2002-2009, Axel D��rfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 *
5 * Copyright 2001, Manuel J. Petit. All rights reserved.
6 * Distributed under the terms of the NewOS License.
7 */
8
9
10#include <errno.h>
11#include <fcntl.h>
12#include <pthread.h>
13#include <stdarg.h>
14#include <unistd.h>
15
16#include <errno_private.h>
17#include <syscalls.h>
18#include <syscall_utils.h>
19#include <umask.h>
20
21
22int
23creat(const char *path, mode_t mode)
24{
25	RETURN_AND_SET_ERRNO_TEST_CANCEL(
26		_kern_open(-1, path, O_CREAT | O_TRUNC | O_WRONLY, mode & ~__gUmask));
27		// adapt the permissions as required by POSIX
28}
29
30
31int
32open(const char *path, int openMode, ...)
33{
34	int perms = 0;
35	if (openMode & O_CREAT) {
36		va_list args;
37		va_start(args, openMode);
38		perms = va_arg(args, int) & ~__gUmask;
39			// adapt the permissions as required by POSIX
40		va_end(args);
41	}
42
43	RETURN_AND_SET_ERRNO_TEST_CANCEL(_kern_open(-1, path, openMode, perms));
44}
45
46
47int
48openat(int fd, const char *path, int openMode, ...)
49{
50	int perms = 0;
51	if (openMode & O_CREAT) {
52		va_list args;
53		va_start(args, openMode);
54		perms = va_arg(args, int) & ~__gUmask;
55			// adapt the permissions as required by POSIX
56		va_end(args);
57	}
58
59	RETURN_AND_SET_ERRNO_TEST_CANCEL(_kern_open(fd, path, openMode, perms));
60}
61
62
63int
64fcntl(int fd, int op, ...)
65{
66	va_list args;
67	va_start(args, op);
68	size_t argument = va_arg(args, size_t);
69	va_end(args);
70
71	status_t error = _kern_fcntl(fd, op, argument);
72
73	if (op == F_SETLKW)
74		pthread_testcancel();
75
76	RETURN_AND_SET_ERRNO(error);
77}
78
79
80int
81posix_fadvise(int fd, off_t offset, off_t len, int advice)
82{
83	if (len < 0 || offset < 0 || advice < POSIX_FADV_NORMAL
84		|| advice > POSIX_FADV_NOREUSE) {
85		return EINVAL;
86	}
87
88	struct stat stat;
89	if (fstat(fd, &stat) < 0)
90		return EBADF;
91	if (S_ISFIFO(stat.st_mode))
92		return ESPIPE;
93
94	// Haiku does not use this information.
95	return 0;
96}
97
98
99int
100posix_fallocate(int fd, off_t offset, off_t len)
101{
102	if (len == 0 || offset < 0)
103		return EINVAL;
104
105	int error = _kern_preallocate(fd, offset, len);
106	if (error == B_UNSUPPORTED) {
107		// While the official specification for this function does not
108		// prescribe which error code to use when the underlying file system
109		// does not support preallocation, we will convert B_UNSUPPORTED to
110		// EOPNOTSUPP for better compatibility with existing applications.
111		return EOPNOTSUPP;
112	}
113	return error;
114}
115