diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2017-03-24 06:30:48 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-03-24 06:30:48 +0000 |
commit | ff45753ae3c3108c6c93ec132f7cf62190f9c628 (patch) | |
tree | 4400fe0ba9baae676633293796954b4061726d5d /iptables/xshared.c | |
parent | a4283108b91a9afcb2596a4cd98201805634cffa (diff) | |
parent | c784fc47e639ff04b6d0ac207fe8d11227bd358b (diff) | |
download | platform_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.c | 111 |
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] != '!'; } |