1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
/*
* Copyright (c) 2002-2007 BalaBit IT Ltd, Budapest, Hungary
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Note that this permission is granted for only version 2 of the GPL.
*
* As an additional exemption you are allowed to compile & link against the
* OpenSSL libraries as published by the OpenSSL project. See the file
* COPYING for details.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "fdread.h"
#include "messages.h"
#include "alarms.h"
#include <errno.h>
static size_t
fd_do_read(FDRead *self, void *buf, size_t buflen, GSockAddr **sa)
{
gint rc;
if ((self->flags & FR_RECV) == 0)
{
*sa = NULL;
do
{
if (self->timeout)
alarm_set(self->timeout);
rc = read(self->fd, buf, buflen);
if (self->timeout > 0 && rc == -1 && errno == EINTR && alarm_has_fired())
{
msg_notice("Nonblocking read has blocked, returning with an error",
evt_tag_int("fd", self->fd),
evt_tag_int("timeout", self->timeout),
NULL);
alarm_cancel();
break;
}
if (self->timeout)
alarm_cancel();
}
while (rc == -1 && errno == EINTR);
}
else
{
union
{
#if HAVE_STRUCT_SOCKADDR_STORAGE
struct sockaddr_storage __sas;
#endif
struct sockaddr __sa;
} sas;
socklen_t salen = sizeof(sas);
do
{
rc = recvfrom(self->fd, buf, buflen, 0,
(struct sockaddr *) &sas, &salen);
}
while (rc == -1 && errno == EINTR);
if (rc != -1 && salen)
(*sa) = g_sockaddr_new((struct sockaddr *) &sas, salen);
}
return rc;
}
FDRead *
fd_read_new(gint fd, guint flags)
{
FDRead *self = g_new0(FDRead, 1);
self->fd = fd;
self->cond = G_IO_IN;
self->read = fd_do_read;
self->flags = flags;
return self;
}
void
fd_read_free(FDRead *self)
{
if ((self->flags & FR_DONTCLOSE) == 0)
{
msg_verbose("Closing log reader fd",
evt_tag_int(EVT_TAG_FD, self->fd),
NULL);
close(self->fd);
}
g_free(self);
}
|