ZmnSCPxj
7 years ago
committed by
Rusty Russell
5 changed files with 78 additions and 0 deletions
@ -0,0 +1,47 @@ |
|||||
|
#include "socket_close.h" |
||||
|
#include <ccan/noerr/noerr.h> |
||||
|
#include <errno.h> |
||||
|
#include <sys/socket.h> |
||||
|
#include <unistd.h> |
||||
|
|
||||
|
/*
|
||||
|
Simplified (minus all the error checks): |
||||
|
|
||||
|
shutdown(fd, SHUT_WR); |
||||
|
for (;;) { |
||||
|
char unused[64] |
||||
|
sys_res = read(fd, unused, 64); |
||||
|
if (sys_res == 0) |
||||
|
break; |
||||
|
} |
||||
|
close(fd); |
||||
|
*/ |
||||
|
|
||||
|
bool socket_close(int fd) |
||||
|
{ |
||||
|
char unused[64]; |
||||
|
int sys_res; |
||||
|
|
||||
|
sys_res = shutdown(fd, SHUT_WR); |
||||
|
if (sys_res < 0) { |
||||
|
close_noerr(fd); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
for (;;) { |
||||
|
do { |
||||
|
sys_res = read(fd, unused, sizeof(unused)); |
||||
|
} while (sys_res < 0 && errno == EINTR); |
||||
|
if (sys_res < 0) { |
||||
|
close_noerr(fd); |
||||
|
return false; |
||||
|
} |
||||
|
if (sys_res == 0) |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
if (close(fd) < 0) |
||||
|
return false; |
||||
|
else |
||||
|
return true; |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
/* common/socket_close - Properly close a socket,
|
||||
|
* ensuring that any data we write just before |
||||
|
* the close has been transmitted to the other |
||||
|
* side, and ignoring any data the other side |
||||
|
* has sent at the time the close was started. |
||||
|
* |
||||
|
* Reference: |
||||
|
* |
||||
|
* http://ia800504.us.archive.org/3/items/TheUltimateSo_lingerPageOrWhyIsMyTcpNotReliable/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable.html
|
||||
|
*/ |
||||
|
#ifndef LIGHTNING_COMMON_SOCKET_CLOSE_H |
||||
|
#define LIGHTNING_COMMON_SOCKET_CLOSE_H |
||||
|
#include "config.h" |
||||
|
#include <stdbool.h> |
||||
|
|
||||
|
/* Return false if something failed, true if
|
||||
|
* nothing failed. |
||||
|
* If something failed, error is stored in |
||||
|
* `errno. |
||||
|
*/ |
||||
|
bool socket_close(int fd); |
||||
|
|
||||
|
#endif /* LIGHTNING_COMMON_SOCKET_CLOSE_H */ |
Loading…
Reference in new issue