Squid Web Cache master
Loading...
Searching...
No Matches
unistd.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9#include "squid.h"
10
11#if _SQUID_WINDOWS_ || _SQUID_MINGW_
12
13#include "compat/socket.h"
14#include "compat/unistd.h"
15#include "compat/wserrno.h"
16
17// 2025 MinGW and pre-2022 MSVC do not define these
18#ifndef _S_IREAD
19#define _S_IREAD 0x0100
20#endif
21
22#ifndef _S_IWRITE
23#define _S_IWRITE 0x0080
24#endif
25
27static bool
28isSocket(intptr_t handle)
29{
30 if (!isValidSocketHandle(handle)) {
31 // isValidSocketHandle does not touch errno
32 return false;
33 }
34
35 int value = 0;
36 int valueSize = sizeof(value);
37 const auto savedErrno = errno;
38 // use Windows API directly
39 const auto result = (getsockopt(handle, SOL_SOCKET, SO_TYPE, reinterpret_cast<char *>(&value), &valueSize) == 0);
40 errno = savedErrno;
41 return result;
42}
43
44int
45xclose(int fd)
46{
47 const auto sock = _get_osfhandle(fd);
48 if (sock == intptr_t(INVALID_HANDLE_VALUE)) {
49 // errno is already set by _get_osfhandle()
50 return -1;
51 }
52
53 if (isSocket(sock)) {
54 const auto result = closesocket(sock);
55 if (result == SOCKET_ERROR)
56 SetErrnoFromWsaError();
57 return result;
58 } else {
59 const auto result = _close(fd);
60 if (result)
61 SetErrnoFromWsaError();
62 return result;
63 }
64}
65
66int
67xgethostname(char *name, size_t nameLength)
68{
69 assert(nameLength <= INT_MAX);
70 const auto result = gethostname(name, static_cast<int>(nameLength));
71 if (result == SOCKET_ERROR)
72 SetErrnoFromWsaError();
73 return result;
74}
75
76int
77xopen(const char *filename, int oflag, int pmode)
78{
79 return _open(filename, oflag, pmode & (_S_IREAD | _S_IWRITE));
80}
81
82int
83xread(int fd, void * buf, size_t bufSize)
84{
85 const auto sock = _get_osfhandle(fd);
86 if (sock == intptr_t(INVALID_HANDLE_VALUE)) {
87 // errno is already set by _get_osfhandle()
88 return -1;
89 }
90
91 assert(bufSize <= UINT_MAX);
92 if (isSocket(sock))
93 return xrecv(sock, buf, bufSize, 0);
94 else
95 return _read(fd, buf, static_cast<unsigned int>(bufSize));
96}
97
98int
99xwrite(int fd, const void * buf, size_t bufSize)
100{
101 const auto sock = _get_osfhandle(fd);
102 if (sock == intptr_t(INVALID_HANDLE_VALUE)) {
103 // errno is already set by _get_osfhandle()
104 return -1;
105 }
106
107 assert(bufSize <= UINT_MAX);
108 if (isSocket(sock))
109 return xsend(sock, buf, bufSize, 0);
110 else
111 return _write(fd, buf, static_cast<unsigned int>(bufSize));
112}
113
114#endif /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */
#define assert(EX)
Definition assert.h:17
ssize_t xrecv(int socketFd, void *buf, size_t bufLength, int flags)
POSIX recv(2) equivalent.
Definition socket.h:98
ssize_t xsend(int socketFd, const void *buf, size_t bufLength, int flags)
POSIX send(2) equivalent.
Definition socket.h:110
#define INT_MAX
Definition types.h:70
int xread(int fd, void *buf, size_t bufSize)
POSIX read(2) equivalent.
Definition unistd.h:61
int xwrite(int fd, const void *buf, size_t bufSize)
POSIX write(2) equivalent.
Definition unistd.h:67
int xclose(int fd)
POSIX close(2) equivalent.
Definition unistd.h:43
int xgethostname(char *name, size_t nameLength)
POSIX gethostname(2) equivalent.
Definition unistd.h:49
int xopen(const char *filename, int oflag, int pmode=0)
POSIX open(2) equivalent.
Definition unistd.h:55