1*99a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2*99a2dd95SBruce Richardson * Copyright(c) 2020 Dmitry Kozlyuk
3*99a2dd95SBruce Richardson */
4*99a2dd95SBruce Richardson
5*99a2dd95SBruce Richardson #include <fcntl.h>
6*99a2dd95SBruce Richardson #include <io.h>
7*99a2dd95SBruce Richardson #include <share.h>
8*99a2dd95SBruce Richardson #include <sys/stat.h>
9*99a2dd95SBruce Richardson
10*99a2dd95SBruce Richardson #include "eal_private.h"
11*99a2dd95SBruce Richardson #include "eal_windows.h"
12*99a2dd95SBruce Richardson
13*99a2dd95SBruce Richardson int
eal_file_open(const char * path,int flags)14*99a2dd95SBruce Richardson eal_file_open(const char *path, int flags)
15*99a2dd95SBruce Richardson {
16*99a2dd95SBruce Richardson static const int MODE_MASK = EAL_OPEN_READONLY | EAL_OPEN_READWRITE;
17*99a2dd95SBruce Richardson
18*99a2dd95SBruce Richardson int fd, ret, sys_flags;
19*99a2dd95SBruce Richardson
20*99a2dd95SBruce Richardson switch (flags & MODE_MASK) {
21*99a2dd95SBruce Richardson case EAL_OPEN_READONLY:
22*99a2dd95SBruce Richardson sys_flags = _O_RDONLY;
23*99a2dd95SBruce Richardson break;
24*99a2dd95SBruce Richardson case EAL_OPEN_READWRITE:
25*99a2dd95SBruce Richardson sys_flags = _O_RDWR;
26*99a2dd95SBruce Richardson break;
27*99a2dd95SBruce Richardson default:
28*99a2dd95SBruce Richardson rte_errno = ENOTSUP;
29*99a2dd95SBruce Richardson return -1;
30*99a2dd95SBruce Richardson }
31*99a2dd95SBruce Richardson
32*99a2dd95SBruce Richardson if (flags & EAL_OPEN_CREATE)
33*99a2dd95SBruce Richardson sys_flags |= _O_CREAT;
34*99a2dd95SBruce Richardson
35*99a2dd95SBruce Richardson ret = _sopen_s(&fd, path, sys_flags, _SH_DENYNO, _S_IWRITE);
36*99a2dd95SBruce Richardson if (ret < 0) {
37*99a2dd95SBruce Richardson rte_errno = errno;
38*99a2dd95SBruce Richardson return -1;
39*99a2dd95SBruce Richardson }
40*99a2dd95SBruce Richardson
41*99a2dd95SBruce Richardson return fd;
42*99a2dd95SBruce Richardson }
43*99a2dd95SBruce Richardson
44*99a2dd95SBruce Richardson int
eal_file_truncate(int fd,ssize_t size)45*99a2dd95SBruce Richardson eal_file_truncate(int fd, ssize_t size)
46*99a2dd95SBruce Richardson {
47*99a2dd95SBruce Richardson HANDLE handle;
48*99a2dd95SBruce Richardson DWORD ret;
49*99a2dd95SBruce Richardson LONG low = (LONG)((size_t)size);
50*99a2dd95SBruce Richardson LONG high = (LONG)((size_t)size >> 32);
51*99a2dd95SBruce Richardson
52*99a2dd95SBruce Richardson handle = (HANDLE)_get_osfhandle(fd);
53*99a2dd95SBruce Richardson if (handle == INVALID_HANDLE_VALUE) {
54*99a2dd95SBruce Richardson rte_errno = EBADF;
55*99a2dd95SBruce Richardson return -1;
56*99a2dd95SBruce Richardson }
57*99a2dd95SBruce Richardson
58*99a2dd95SBruce Richardson ret = SetFilePointer(handle, low, &high, FILE_BEGIN);
59*99a2dd95SBruce Richardson if (ret == INVALID_SET_FILE_POINTER) {
60*99a2dd95SBruce Richardson RTE_LOG_WIN32_ERR("SetFilePointer()");
61*99a2dd95SBruce Richardson rte_errno = EINVAL;
62*99a2dd95SBruce Richardson return -1;
63*99a2dd95SBruce Richardson }
64*99a2dd95SBruce Richardson
65*99a2dd95SBruce Richardson return 0;
66*99a2dd95SBruce Richardson }
67*99a2dd95SBruce Richardson
68*99a2dd95SBruce Richardson static int
lock_file(HANDLE handle,enum eal_flock_op op,enum eal_flock_mode mode)69*99a2dd95SBruce Richardson lock_file(HANDLE handle, enum eal_flock_op op, enum eal_flock_mode mode)
70*99a2dd95SBruce Richardson {
71*99a2dd95SBruce Richardson DWORD sys_flags = 0;
72*99a2dd95SBruce Richardson OVERLAPPED overlapped;
73*99a2dd95SBruce Richardson
74*99a2dd95SBruce Richardson if (op == EAL_FLOCK_EXCLUSIVE)
75*99a2dd95SBruce Richardson sys_flags |= LOCKFILE_EXCLUSIVE_LOCK;
76*99a2dd95SBruce Richardson if (mode == EAL_FLOCK_RETURN)
77*99a2dd95SBruce Richardson sys_flags |= LOCKFILE_FAIL_IMMEDIATELY;
78*99a2dd95SBruce Richardson
79*99a2dd95SBruce Richardson memset(&overlapped, 0, sizeof(overlapped));
80*99a2dd95SBruce Richardson if (!LockFileEx(handle, sys_flags, 0, 0, 0, &overlapped)) {
81*99a2dd95SBruce Richardson if ((sys_flags & LOCKFILE_FAIL_IMMEDIATELY) &&
82*99a2dd95SBruce Richardson (GetLastError() == ERROR_IO_PENDING)) {
83*99a2dd95SBruce Richardson rte_errno = EWOULDBLOCK;
84*99a2dd95SBruce Richardson } else {
85*99a2dd95SBruce Richardson RTE_LOG_WIN32_ERR("LockFileEx()");
86*99a2dd95SBruce Richardson rte_errno = EINVAL;
87*99a2dd95SBruce Richardson }
88*99a2dd95SBruce Richardson return -1;
89*99a2dd95SBruce Richardson }
90*99a2dd95SBruce Richardson
91*99a2dd95SBruce Richardson return 0;
92*99a2dd95SBruce Richardson }
93*99a2dd95SBruce Richardson
94*99a2dd95SBruce Richardson static int
unlock_file(HANDLE handle)95*99a2dd95SBruce Richardson unlock_file(HANDLE handle)
96*99a2dd95SBruce Richardson {
97*99a2dd95SBruce Richardson if (!UnlockFileEx(handle, 0, 0, 0, NULL)) {
98*99a2dd95SBruce Richardson RTE_LOG_WIN32_ERR("UnlockFileEx()");
99*99a2dd95SBruce Richardson rte_errno = EINVAL;
100*99a2dd95SBruce Richardson return -1;
101*99a2dd95SBruce Richardson }
102*99a2dd95SBruce Richardson return 0;
103*99a2dd95SBruce Richardson }
104*99a2dd95SBruce Richardson
105*99a2dd95SBruce Richardson int
eal_file_lock(int fd,enum eal_flock_op op,enum eal_flock_mode mode)106*99a2dd95SBruce Richardson eal_file_lock(int fd, enum eal_flock_op op, enum eal_flock_mode mode)
107*99a2dd95SBruce Richardson {
108*99a2dd95SBruce Richardson HANDLE handle = (HANDLE)_get_osfhandle(fd);
109*99a2dd95SBruce Richardson
110*99a2dd95SBruce Richardson if (handle == INVALID_HANDLE_VALUE) {
111*99a2dd95SBruce Richardson rte_errno = EBADF;
112*99a2dd95SBruce Richardson return -1;
113*99a2dd95SBruce Richardson }
114*99a2dd95SBruce Richardson
115*99a2dd95SBruce Richardson switch (op) {
116*99a2dd95SBruce Richardson case EAL_FLOCK_EXCLUSIVE:
117*99a2dd95SBruce Richardson case EAL_FLOCK_SHARED:
118*99a2dd95SBruce Richardson return lock_file(handle, op, mode);
119*99a2dd95SBruce Richardson case EAL_FLOCK_UNLOCK:
120*99a2dd95SBruce Richardson return unlock_file(handle);
121*99a2dd95SBruce Richardson default:
122*99a2dd95SBruce Richardson rte_errno = EINVAL;
123*99a2dd95SBruce Richardson return -1;
124*99a2dd95SBruce Richardson }
125*99a2dd95SBruce Richardson }
126