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 
27 static bool
28 isSocket(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 
44 int
45 xclose(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 
66 int
67 xgethostname(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 
76 int
77 xopen(const char *filename, int oflag, int pmode)
78 {
79  return _open(filename, oflag, pmode & (_S_IREAD | _S_IWRITE));
80 }
81 
82 int
83 xread(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 
98 int
99 xwrite(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_ */
int xwrite(int fd, const void *buf, size_t bufSize)
POSIX write(2) equivalent.
Definition: unistd.h:67
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
#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
int xread(int fd, void *buf, size_t bufSize)
POSIX read(2) equivalent.
Definition: unistd.h:61
int xopen(const char *filename, int oflag, int pmode=0)
POSIX open(2) equivalent.
Definition: unistd.h:55
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

 

Introduction

Documentation

Support

Miscellaneous