ReactOS 0.4.15-dev-7934-g1dc8d80
SClose.c File Reference
#include "syshdrs.h"
Include dependency graph for SClose.c:

Go to the source code of this file.

Functions

int SClose (int sfd, int tlen)
 

Function Documentation

◆ SClose()

int SClose ( int  sfd,
int  tlen 
)

Definition at line 9 of file SClose.c.

10{
11#ifndef NO_SIGNALS
12 vsio_sigproc_t sigalrm, sigpipe;
13
14 if (sfd < 0) {
15 errno = EBADF;
16 return (-1);
17 }
18
19 if (tlen < 1) {
20 /* Don't time it, shut it down now. */
21 if (SetSocketLinger(sfd, 0, 0) == 0) {
22 /* Linger disabled, so close()
23 * should not block.
24 */
25 return (closesocket(sfd));
26 } else {
27 /* This will result in a fd leak,
28 * but it's either that or hang forever.
29 */
30 return (shutdown(sfd, 2));
31 }
32 }
33
34 if (SSetjmp(gNetTimeoutJmp) != 0) {
35 alarm(0);
36 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
37 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
38 if (SetSocketLinger(sfd, 0, 0) == 0) {
39 /* Linger disabled, so close()
40 * should not block.
41 */
42 return closesocket(sfd);
43 } else {
44 /* This will result in a fd leak,
45 * but it's either that or hang forever.
46 */
47 (void) shutdown(sfd, 2);
48 }
49 return (-1);
50 }
51
52 sigalrm = (vsio_sigproc_t) SSignal(SIGALRM, SIOHandler);
54
55 alarm((unsigned int) tlen);
56 for (;;) {
57 if (closesocket(sfd) == 0) {
58 errno = 0;
59 break;
60 }
61 if (errno != EINTR)
62 break;
63 }
64 alarm(0);
65 (void) SSignal(SIGALRM, (sio_sigproc_t) sigalrm);
66
67 if ((errno != 0) && (errno != EBADF)) {
68 if (SetSocketLinger(sfd, 0, 0) == 0) {
69 /* Linger disabled, so close()
70 * should not block.
71 */
72 (void) closesocket(sfd);
73 } else {
74 /* This will result in a fd leak,
75 * but it's either that or hang forever.
76 */
77 (void) shutdown(sfd, 2);
78 }
79 }
80 (void) SSignal(SIGPIPE, (sio_sigproc_t) sigpipe);
81
82 return ((errno == 0) ? 0 : (-1));
83#else
84 struct timeval tv;
85 int result;
86 time_t done, now;
87 fd_set ss;
88
89 if (sfd < 0) {
90 errno = EBADF;
91 return (-1);
92 }
93
94 if (tlen < 1) {
95 /* Don't time it, shut it down now. */
96 if (SetSocketLinger(sfd, 0, 0) == 0) {
97 /* Linger disabled, so close()
98 * should not block.
99 */
100 return (closesocket(sfd));
101 } else {
102 /* This will result in a fd leak,
103 * but it's either that or hang forever.
104 */
105 return (shutdown(sfd, 2));
106 }
107 }
108
109 /* Wait until the socket is ready for writing (usually easy). */
110 time(&now);
111 done = now + tlen;
112
113 forever {
114 tlen = done - now;
115 if (tlen <= 0) {
116 /* timeout */
117 if (SetSocketLinger(sfd, 0, 0) == 0) {
118 /* Linger disabled, so close()
119 * should not block.
120 */
121 (void) closesocket(sfd);
122 } else {
123 /* This will result in a fd leak,
124 * but it's either that or hang forever.
125 */
126 (void) shutdown(sfd, 2);
127 }
129 return (kTimeoutErr);
130 }
131
132 errno = 0;
133 FD_ZERO(&ss);
134 FD_SET(sfd, &ss);
135 tv.tv_sec = tlen;
136 tv.tv_usec = 0;
138 if (result == 1) {
139 /* ready */
140 break;
141 } else if (result == 0) {
142 /* timeout */
143 if (SetSocketLinger(sfd, 0, 0) == 0) {
144 /* Linger disabled, so close()
145 * should not block.
146 */
147 (void) closesocket(sfd);
148 } else {
149 /* This will result in a fd leak,
150 * but it's either that or hang forever.
151 */
152 (void) shutdown(sfd, 2);
153 }
155 return (kTimeoutErr);
156 } else if (errno != EINTR) {
157 /* Error, done. This end may have been shutdown. */
158 break;
159 }
160 time(&now);
161 }
162
163 /* Wait until the socket is ready for reading. */
164 forever {
165 tlen = done - now;
166 if (tlen <= 0) {
167 /* timeout */
168 if (SetSocketLinger(sfd, 0, 0) == 0) {
169 /* Linger disabled, so close()
170 * should not block.
171 */
172 (void) closesocket(sfd);
173 } else {
174 /* This will result in a fd leak,
175 * but it's either that or hang forever.
176 */
177 (void) shutdown(sfd, 2);
178 }
180 return (kTimeoutErr);
181 }
182
183 errno = 0;
184 FD_ZERO(&ss);
185 FD_SET(sfd, &ss);
186 tv.tv_sec = tlen;
187 tv.tv_usec = 0;
189 if (result == 1) {
190 /* ready */
191 break;
192 } else if (result == 0) {
193 /* timeout */
194 if (SetSocketLinger(sfd, 0, 0) == 0) {
195 /* Linger disabled, so close()
196 * should not block.
197 */
198 (void) closesocket(sfd);
199 } else {
200 /* This will result in a fd leak,
201 * but it's either that or hang forever.
202 */
203 (void) shutdown(sfd, 2);
204 }
206 return (kTimeoutErr);
207 } else if (errno != EINTR) {
208 /* Error, done. This end may have been shutdown. */
209 break;
210 }
211 time(&now);
212 }
213
214 /* If we get here, close() won't block. */
215 return closesocket(sfd);
216#endif
217} /* SClose */
#define EINTR
Definition: acclib.h:80
#define EBADF
Definition: acclib.h:82
#define SIGPIPE
Definition: signal.h:35
#define SIG_IGN
Definition: signal.h:48
#define NULL
Definition: types.h:112
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
#define ETIMEDOUT
Definition: errno.h:121
__kernel_time_t time_t
Definition: linux.h:252
time_t now
Definition: finger.c:65
GLuint64EXT * result
Definition: glext.h:11304
#define ss
Definition: i386-dis.c:441
#define SELECT_TYPE_ARG234
Definition: wincfg.h:4
#define SELECT_TYPE_ARG5
Definition: wincfg.h:7
__u16 time
Definition: mkdosfs.c:8
void SIOHandler(int)
#define SSetjmp(a)
Definition: sio.h:39
volatile sio_sigproc_t vsio_sigproc_t
Definition: sio.h:124
void(*)(int) SSignal(int signum, void(*handler)(int))
Definition: sio.h:237
int SetSocketLinger(const int, const int, const int)
#define kTimeoutErr
Definition: sio.h:58
void(* sio_sigproc_t)(int)
Definition: sio.h:123
#define forever
Definition: ncftp.h:73
#define closesocket
Definition: ncftp.h:477
#define errno
Definition: errno.h:18
INT WSAAPI shutdown(IN SOCKET s, IN INT how)
Definition: sockctrl.c:506
Definition: winsock.h:66
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89

Referenced by CloseControlConnection(), CloseDataConnection(), OpenControlConnection(), and ServeOneClient().