ReactOS  0.4.13-dev-247-g0f29b3f
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);
53  sigpipe = (vsio_sigproc_t) SSignal(SIGPIPE, SIG_IGN);
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  }
128  errno = ETIMEDOUT;
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  }
154  errno = ETIMEDOUT;
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  }
179  errno = ETIMEDOUT;
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  }
205  errno = ETIMEDOUT;
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 */
Definition: winsock.h:66
#define SELECT_TYPE_ARG234
Definition: wincfg.h:4
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
volatile sio_sigproc_t vsio_sigproc_t
Definition: sio.h:124
#define EINTR
Definition: acclib.h:80
int errno
__u16 time
Definition: mkdosfs.c:366
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
Definition: arc.h:36
#define closesocket
Definition: main.c:39
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
time_t now
Definition: finger.c:65
smooth NULL
Definition: ftsmooth.c:416
#define kTimeoutErr
Definition: sio.h:58
int SetSocketLinger(const int, const int, const int)
INT WSAAPI shutdown(IN SOCKET s, IN INT how)
Definition: sockctrl.c:506
#define SIGPIPE
Definition: signal.h:35
#define SSetjmp(a)
Definition: sio.h:39
#define SELECT_TYPE_ARG5
Definition: wincfg.h:7
#define forever
Definition: ncftp.h:73
__kernel_time_t time_t
Definition: linux.h:252
void(*)(int) SSignal(int signum, void(*handler)(int))
Definition: sio.h:237
#define ETIMEDOUT
Definition: errno.h:121
#define ss
Definition: i386-dis.c:432
#define SIG_IGN
Definition: signal.h:48
GLuint64EXT * result
Definition: glext.h:11304
void(* sio_sigproc_t)(int)
Definition: sio.h:123
void SIOHandler(int)

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