summaryrefslogtreecommitdiffstats
path: root/libiptc
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-04-02 14:01:53 +0200
committerPatrick McHardy <kaber@trash.net>2008-04-02 14:01:53 +0200
commit2f93205b375ee9f5a383f8041749a9b989012dd0 (patch)
tree8e11798d6ce952eb81e3b7e58def210d6fffff48 /libiptc
parentdbe6c3b74ee847707181f1fe28b2975b4a8ab425 (diff)
Retry ruleset dump when kernel returns EAGAIN.
Bugzilla #104
Diffstat (limited to 'libiptc')
-rw-r--r--libiptc/libiptc.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
index b7bf785c..277ca0f2 100644
--- a/libiptc/libiptc.c
+++ b/libiptc/libiptc.c
@@ -1219,21 +1219,21 @@ TC_INIT(const char *tablename)
errno = EINVAL;
return NULL;
}
if (sockfd_use == 0) {
sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW);
if (sockfd < 0)
return NULL;
}
sockfd_use++;
-
+retry:
s = sizeof(info);
strcpy(info.name, tablename);
if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0) {
if (--sockfd_use == 0) {
close(sockfd);
sockfd = -1;
}
return NULL;
}
@@ -1272,20 +1272,23 @@ TC_INIT(const char *tablename)
}
#endif
if (parse_table(h) < 0)
goto error;
CHECK(h);
return h;
error:
TC_FREE(&h);
+ /* A different process changed the ruleset size, retry */
+ if (errno == EAGAIN)
+ goto retry;
return NULL;
}
void
TC_FREE(TC_HANDLE_T *h)
{
struct chain_head *c, *tmp;
iptc_fn = TC_FREE;
if (--sockfd_use == 0) {