aboutsummaryrefslogtreecommitdiffstats
path: root/iptables/xshared.c
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2017-03-24 06:30:48 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-03-24 06:30:48 +0000
commitff45753ae3c3108c6c93ec132f7cf62190f9c628 (patch)
tree4400fe0ba9baae676633293796954b4061726d5d /iptables/xshared.c
parenta4283108b91a9afcb2596a4cd98201805634cffa (diff)
parentc784fc47e639ff04b6d0ac207fe8d11227bd358b (diff)
downloadplatform_external_iptables-ff45753ae3c3108c6c93ec132f7cf62190f9c628.tar.gz
platform_external_iptables-ff45753ae3c3108c6c93ec132f7cf62190f9c628.tar.bz2
platform_external_iptables-ff45753ae3c3108c6c93ec132f7cf62190f9c628.zip
Merge changes from topic 'iptables-1.6.1'
am: c784fc47e6 Change-Id: I9c26682631ff24de4215e553045036b94bfb611e
Diffstat (limited to 'iptables/xshared.c')
-rw-r--r--iptables/xshared.c111
1 files changed, 87 insertions, 24 deletions
diff --git a/iptables/xshared.c b/iptables/xshared.c
index c144b485..3fbe3b1a 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -1,4 +1,6 @@
+#include <config.h>
#include <getopt.h>
+#include <errno.h>
#include <libgen.h>
#include <netdb.h>
#include <stdbool.h>
@@ -6,15 +8,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/file.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <sys/time.h>
#include <unistd.h>
+#include <fcntl.h>
#include <xtables.h>
+#include <math.h>
#include "xshared.h"
-#define XT_SOCKET_NAME "xtables"
-#define XT_SOCKET_LEN 8
-
/*
* Print out any special helps. A user might like to be able to add a --help
* to the commandline, and see expected results. So we call help for all
@@ -243,37 +246,97 @@ void xs_init_match(struct xtables_match *match)
match->init(match->m);
}
-int xtables_lock(bool wait)
+int xtables_lock(int wait, struct timeval *wait_interval)
{
- int i = 0, ret, xt_socket;
- struct sockaddr_un xt_addr;
-
- memset(&xt_addr, 0, sizeof(xt_addr));
- xt_addr.sun_family = AF_UNIX;
- strcpy(xt_addr.sun_path+1, XT_SOCKET_NAME);
- xt_socket = socket(AF_UNIX, SOCK_STREAM, 0);
- /* If we can't even create a socket, fall back to prior (lockless) behavior */
- if (xt_socket < 0)
+ struct timeval time_left, wait_time;
+ int fd, i = 0;
+
+ time_left.tv_sec = wait;
+ time_left.tv_usec = 0;
+
+ fd = open(XT_LOCK_NAME, O_CREAT, 0600);
+ if (fd < 0)
return XT_LOCK_UNSUPPORTED;
+ if (wait == -1) {
+ if (flock(fd, LOCK_EX) == 0)
+ return fd;
+
+ fprintf(stderr, "Can't lock %s: %s\n", XT_LOCK_NAME,
+ strerror(errno));
+ return XT_LOCK_BUSY;
+ }
+
while (1) {
- ret = bind(xt_socket, (struct sockaddr*)&xt_addr,
- offsetof(struct sockaddr_un, sun_path)+XT_SOCKET_LEN);
- if (ret == 0)
- return xt_socket;
- else if (wait == false)
+ if (flock(fd, LOCK_EX | LOCK_NB) == 0)
+ return fd;
+ else if (timercmp(&time_left, wait_interval, <))
return XT_LOCK_BUSY;
- if (++i % 2 == 0)
+
+ if (++i % 10 == 0) {
fprintf(stderr, "Another app is currently holding the xtables lock; "
- "waiting for it to exit...\n");
- sleep(1);
+ "still %lds %ldus time ahead to have a chance to grab the lock...\n",
+ time_left.tv_sec, time_left.tv_usec);
+ }
+
+ wait_time = *wait_interval;
+ select(0, NULL, NULL, NULL, &wait_time);
+ timersub(&time_left, wait_interval, &time_left);
}
}
-void xtables_unlock(int lock) {
- if (lock < 0) {
+void xtables_unlock(int lock)
+{
+ if (lock >= 0)
+ close(lock);
+}
+
+int parse_wait_time(int argc, char *argv[])
+{
+ int wait = -1;
+
+ if (optarg) {
+ if (sscanf(optarg, "%i", &wait) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "wait seconds not numeric");
+ } else if (xs_has_arg(argc, argv))
+ if (sscanf(argv[optind++], "%i", &wait) != 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "wait seconds not numeric");
+
+ return wait;
+}
+
+void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval)
+{
+ const char *arg;
+ unsigned int usec;
+ int ret;
+
+ if (optarg)
+ arg = optarg;
+ else if (xs_has_arg(argc, argv))
+ arg = argv[optind++];
+ else
+ return;
+
+ ret = sscanf(arg, "%u", &usec);
+ if (ret == 1) {
+ if (usec > 999999)
+ xtables_error(PARAMETER_PROBLEM,
+ "too long usec wait %u > 999999 usec",
+ usec);
+
+ wait_interval->tv_sec = 0;
+ wait_interval->tv_usec = usec;
return;
}
+ xtables_error(PARAMETER_PROBLEM, "wait interval not numeric");
+}
- close(lock);
+inline bool xs_has_arg(int argc, char *argv[])
+{
+ return optind < argc &&
+ argv[optind][0] != '-' &&
+ argv[optind][0] != '!';
}