2021-12-04 12:23:56 +01:00
|
|
|
#include "config.h"
|
2018-05-05 06:57:58 +02:00
|
|
|
#include <ccan/noerr/noerr.h>
|
2021-12-04 12:23:56 +01:00
|
|
|
#include <common/socket_close.h>
|
2018-05-05 06:57:58 +02:00
|
|
|
#include <errno.h>
|
2021-12-28 00:25:09 +01:00
|
|
|
#include <signal.h>
|
|
|
|
#include <string.h>
|
2018-05-05 06:57:58 +02:00
|
|
|
#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);
|
|
|
|
*/
|
|
|
|
|
2021-12-28 00:25:09 +01:00
|
|
|
/* makes read() return EINTR */
|
|
|
|
static void break_read(int signum)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-05-05 06:57:58 +02:00
|
|
|
bool socket_close(int fd)
|
|
|
|
{
|
|
|
|
char unused[64];
|
2021-12-28 00:25:09 +01:00
|
|
|
struct sigaction act, old_act;
|
2018-05-05 06:57:58 +02:00
|
|
|
int sys_res;
|
|
|
|
|
|
|
|
sys_res = shutdown(fd, SHUT_WR);
|
|
|
|
if (sys_res < 0) {
|
|
|
|
close_noerr(fd);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-12-28 00:25:09 +01:00
|
|
|
/* Let's not get too enthusiastic about waiting. */
|
|
|
|
memset(&act, 0, sizeof(act));
|
|
|
|
act.sa_handler = break_read;
|
|
|
|
sigaction(SIGALRM, &act, &old_act);
|
2018-05-05 06:57:58 +02:00
|
|
|
|
2021-12-28 00:25:09 +01:00
|
|
|
alarm(5);
|
|
|
|
|
|
|
|
while ((sys_res = read(fd, unused, sizeof(unused))) > 0);
|
|
|
|
|
|
|
|
alarm(0);
|
|
|
|
sigaction(SIGALRM, &old_act, NULL);
|
|
|
|
|
|
|
|
if (sys_res < 0) {
|
|
|
|
close_noerr(fd);
|
2018-05-05 06:57:58 +02:00
|
|
|
return false;
|
2021-12-28 00:25:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return close(fd) == 0;
|
2018-05-05 06:57:58 +02:00
|
|
|
}
|