PostgreSQL Source Code git master
Loading...
Searching...
No Matches
win32stat.c File Reference
#include "c.h"
#include "port/win32ntdll.h"
#include <windows.h>
Include dependency graph for win32stat.c:

Go to the source code of this file.

Functions

static __time64_t filetime_to_time (const FILETIME *ft)
 
static unsigned short fileattr_to_unixmode (int attr)
 
static int fileinfo_to_stat (HANDLE hFile, struct stat *buf)
 
int _pglstat64 (const char *name, struct stat *buf)
 
int _pgstat64 (const char *name, struct stat *buf)
 
int _pgfstat64 (int fileno, struct stat *buf)
 

Function Documentation

◆ _pgfstat64()

int _pgfstat64 ( int  fileno,
struct stat buf 
)

Definition at line 260 of file win32stat.c.

261{
262 HANDLE hFile = (HANDLE) _get_osfhandle(fileno);
264 unsigned short st_mode;
265
266 if (buf == NULL)
267 {
268 errno = EINVAL;
269 return -1;
270 }
271
273 if (errno != 0)
274 return -1;
275
276 switch (fileType)
277 {
278 /* The specified file is a disk file */
279 case FILE_TYPE_DISK:
280 return fileinfo_to_stat(hFile, buf);
281
282 /*
283 * The specified file is a socket, a named pipe, or an anonymous
284 * pipe.
285 */
286 case FILE_TYPE_PIPE:
287 st_mode = _S_IFIFO;
288 break;
289 /* The specified file is a character file */
290 case FILE_TYPE_CHAR:
291 st_mode = _S_IFCHR;
292 break;
293 /* Unused flag and unknown file type */
294 case FILE_TYPE_REMOTE:
296 default:
297 errno = EINVAL;
298 return -1;
299 }
300
301 memset(buf, 0, sizeof(*buf));
302 buf->st_mode = st_mode;
303 buf->st_dev = fileno;
304 buf->st_rdev = fileno;
305 buf->st_nlink = 1;
306 return 0;
307}
static char buf[DEFAULT_XLOG_SEG_SIZE]
static int fb(int x)
#define EINVAL
Definition private.h:69
DWORD pgwin32_get_file_type(HANDLE hFile)
Definition win32common.c:31
static int fileinfo_to_stat(HANDLE hFile, struct stat *buf)
Definition win32stat.c:68

References buf, EINVAL, fb(), fileinfo_to_stat(), and pgwin32_get_file_type().

◆ _pglstat64()

int _pglstat64 ( const char name,
struct stat buf 
)

Definition at line 113 of file win32stat.c.

114{
115 /*
116 * Our open wrapper will report STATUS_DELETE_PENDING as ENOENT. We
117 * request FILE_FLAG_BACKUP_SEMANTICS so that we can open directories too,
118 * for limited purposes. We use the private handle-based version, so we
119 * don't risk running out of fds.
120 */
122 int ret;
123
126 {
127 if (errno == ENOENT)
128 {
129 /*
130 * If it's a junction point pointing to a non-existent path, we'll
131 * have ENOENT here (because pgwin32_open_handle does not use
132 * FILE_FLAG_OPEN_REPARSE_POINT). In that case, we'll try again
133 * with readlink() below, which will distinguish true ENOENT from
134 * pseudo-symlink.
135 */
136 memset(buf, 0, sizeof(*buf));
137 ret = 0;
138 }
139 else
140 return -1;
141 }
142 else
143 ret = fileinfo_to_stat(hFile, buf);
144
145 /*
146 * Junction points appear as directories to fileinfo_to_stat(), so we'll
147 * need to do a bit more work to distinguish them.
148 */
149 if ((ret == 0 && S_ISDIR(buf->st_mode)) || hFile == INVALID_HANDLE_VALUE)
150 {
151 char next[MAXPGPATH];
152 ssize_t size;
153
154 /*
155 * POSIX says we need to put the length of the target path into
156 * st_size. Use readlink() to get it, or learn that this is not a
157 * junction point.
158 */
159 size = readlink(name, next, sizeof(next));
160 if (size < 0)
161 {
162 if (errno == EACCES &&
164 {
165 /* Unlinked underneath us. */
166 errno = ENOENT;
167 ret = -1;
168 }
169 else if (errno == EINVAL)
170 {
171 /* It's not a junction point, nothing to do. */
172 }
173 else
174 {
175 /* Some other failure. */
176 ret = -1;
177 }
178 }
179 else if (size >= sizeof(next))
180 {
182 ret = -1;
183 }
184 else
185 {
186 /* It's a junction point, so report it as a symlink. */
187 buf->st_mode &= ~S_IFDIR;
188 buf->st_mode |= S_IFLNK;
189 buf->st_size = size;
190 ret = 0;
191 }
192 }
193
196 return ret;
197}
static int32 next
Definition blutils.c:225
#define MAXPGPATH
#define ENAMETOOLONG
Definition private.h:76
const char * name
#define S_ISDIR(m)
Definition win32_port.h:332
#define readlink(path, buf, size)
Definition win32_port.h:243
#define S_IFLNK
Definition win32_port.h:350
PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus
Definition win32ntdll.c:20

References buf, EINVAL, ENAMETOOLONG, fb(), fileinfo_to_stat(), MAXPGPATH, name, next, pg_RtlGetLastNtStatus, readlink, S_IFLNK, and S_ISDIR.

Referenced by _pgstat64().

◆ _pgstat64()

int _pgstat64 ( const char name,
struct stat buf 
)

Definition at line 203 of file win32stat.c.

204{
205 int loops = 0;
206 int ret;
207 char curr[MAXPGPATH];
208
209 ret = _pglstat64(name, buf);
210
212
213 /* Do we need to follow a symlink (junction point)? */
214 while (ret == 0 && S_ISLNK(buf->st_mode))
215 {
216 char next[MAXPGPATH];
217 ssize_t size;
218
219 if (++loops > 8)
220 {
221 errno = ELOOP;
222 return -1;
223 }
224
225 /*
226 * _pglstat64() already called readlink() once to be able to fill in
227 * st_size, and now we need to do it again to get the path to follow.
228 * That could be optimized, but stat() on symlinks is probably rare
229 * and this way is simple.
230 */
231 size = readlink(curr, next, sizeof(next));
232 if (size < 0)
233 {
234 if (errno == EACCES &&
236 {
237 /* Unlinked underneath us. */
238 errno = ENOENT;
239 }
240 return -1;
241 }
242 else if (size >= sizeof(next))
243 {
245 return -1;
246 }
247 next[size] = 0;
248
249 ret = _pglstat64(next, buf);
250 strcpy(curr, next);
251 }
252
253 return ret;
254}
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
#define ELOOP
Definition private.h:73
#define S_ISLNK(m)
Definition win32_port.h:351
int _pglstat64(const char *name, struct stat *buf)
Definition win32stat.c:113

References _pglstat64(), buf, ELOOP, ENAMETOOLONG, fb(), MAXPGPATH, name, next, pg_RtlGetLastNtStatus, readlink, S_ISLNK, and strlcpy().

◆ fileattr_to_unixmode()

static unsigned short fileattr_to_unixmode ( int  attr)
static

Definition at line 48 of file win32stat.c.

49{
50 unsigned short uxmode = 0;
51
52 uxmode |= (unsigned short) ((attr & FILE_ATTRIBUTE_DIRECTORY) ?
53 (_S_IFDIR) : (_S_IFREG));
54
55 uxmode |= (unsigned short) ((attr & FILE_ATTRIBUTE_READONLY) ?
57
58 /* there is no need to simulate _S_IEXEC using CMD's PATHEXT extensions */
60
61 return uxmode;
62}

References fb().

Referenced by fileinfo_to_stat().

◆ fileinfo_to_stat()

static int fileinfo_to_stat ( HANDLE  hFile,
struct stat buf 
)
static

Definition at line 68 of file win32stat.c.

69{
71
72 memset(buf, 0, sizeof(*buf));
73
74 /*
75 * GetFileInformationByHandle minimum supported version: Windows XP and
76 * Windows Server 2003, so it exists everywhere we care about.
77 */
79 {
81 return -1;
82 }
83
84 if (fiData.ftLastWriteTime.dwLowDateTime ||
85 fiData.ftLastWriteTime.dwHighDateTime)
86 buf->st_mtime = filetime_to_time(&fiData.ftLastWriteTime);
87
88 if (fiData.ftLastAccessTime.dwLowDateTime ||
89 fiData.ftLastAccessTime.dwHighDateTime)
90 buf->st_atime = filetime_to_time(&fiData.ftLastAccessTime);
91 else
92 buf->st_atime = buf->st_mtime;
93
94 if (fiData.ftCreationTime.dwLowDateTime ||
95 fiData.ftCreationTime.dwHighDateTime)
96 buf->st_ctime = filetime_to_time(&fiData.ftCreationTime);
97 else
98 buf->st_ctime = buf->st_mtime;
99
100 buf->st_mode = fileattr_to_unixmode(fiData.dwFileAttributes);
101 buf->st_nlink = fiData.nNumberOfLinks;
102
103 buf->st_size = ((((uint64) fiData.nFileSizeHigh) << 32) |
104 fiData.nFileSizeLow);
105
106 return 0;
107}
uint64_t uint64
Definition c.h:684
void _dosmaperr(unsigned long)
Definition win32error.c:177
static __time64_t filetime_to_time(const FILETIME *ft)
Definition win32stat.c:25
static unsigned short fileattr_to_unixmode(int attr)
Definition win32stat.c:48

References _dosmaperr(), buf, fb(), fileattr_to_unixmode(), and filetime_to_time().

Referenced by _pgfstat64(), and _pglstat64().

◆ filetime_to_time()

static __time64_t filetime_to_time ( const FILETIME ft)
static

Definition at line 25 of file win32stat.c.

26{
28 static const uint64 EpochShift = UINT64CONST(116444736000000000);
29
30 unified_ft.LowPart = ft->dwLowDateTime;
31 unified_ft.HighPart = ft->dwHighDateTime;
32
33 if (unified_ft.QuadPart < EpochShift)
34 return -1;
35
36 unified_ft.QuadPart -= EpochShift;
37 unified_ft.QuadPart /= 10 * 1000 * 1000;
38
39 return unified_ft.QuadPart;
40}
#define UINT64CONST(x)
Definition c.h:690

References fb(), and UINT64CONST.

Referenced by fileinfo_to_stat().