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