diff options
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/common-utils.c | 202 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 10 | ||||
| -rw-r--r-- | libglusterfs/src/run.c | 35 | 
3 files changed, 215 insertions, 32 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 6ea4fd14374..635d092bc7d 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -35,6 +35,9 @@  #include <sys/sysctl.h>  #endif  #include <libgen.h> +#ifndef GF_LINUX_HOST_OS +#include <sys/resource.h> +#endif  #include "compat-errno.h"  #include "logging.h" @@ -2129,6 +2132,145 @@ get_nth_word (const char *str, int n)          return word;  } +/** + * token_iter_init -- initialize tokenization + * + * @str: string to be tokenized + * @sep: token separator character + * @tit: pointer to iteration state + * + * @return: token string + * + * The returned token string and tit are + * not to be used directly, but through + * next_token(). + */ +char * +token_iter_init (char *str, char sep, token_iter_t *tit) +{ +        tit->end = str + strlen (str); +        tit->sep = sep; + +        return str; +} + +/** + * next_token -- fetch next token in tokenization + * inited by token_iter_init(). + * + * @tokenp: pointer to token + * @tit:    pointer to iteration state + * + * @return: true if iteration ends, else false + * + * The token pointed by @tokenp can be used + * after a call to next_token(). When next_token() + * returns true the iteration is to be stopped + * and the string with which the tokenization + * was inited (see token_iter_init() is restored, + * apart from dropped tokens (see drop_token()). + */ +gf_boolean_t +next_token (char **tokenp, token_iter_t *tit) +{ +        char        *cursor  = NULL; +        gf_boolean_t is_last = _gf_false; + +        for (cursor = *tokenp; *cursor; cursor++); +        if (cursor < tit->end) { +                /* +                 * We detect that in between current token and end a zero +                 * marker has already been inserted. This means that the +                 * token has already been returned. We restore the +                 * separator and move ahead. +                 */ +                *cursor = tit->sep; +                *tokenp = cursor + 1; +        } + +        for (cursor = *tokenp; *cursor && *cursor != tit->sep; cursor++); +        /* If the cursor ended up on a zero byte, then it's the last token. */ +        is_last = !*cursor; +        /* Zero-terminate the token. */ +        *cursor = 0; + +        return is_last; +} + +/* + * drop_token -- drop a token during iterated calls of next_token(). + * + * Sample program that uses these functions to tokenize + * a comma-separated first argument while dropping the + * rest of the arguments if they occur as token: + * + * #include <stdio.h> + * #include <stdlib.h> + * #include <string.h> + * #include "common-utils.h" + * + * int + * main (int argc, char **argv) + * { + *         char *buf; + *         char *token; + *         token_iter_t tit; + *         int i; + *         gf_boolean_t iter_end; + * + *         if (argc <= 1) + *                 abort(); + * + *         buf = strdup (argv[1]); + *         if (!buf) + *                 abort(); + * + *         for (token = token_iter_init (buf, ',', &tit) ;;) { + *                 iter_end = next_token (&token, &tit); + *                 printf("found token: '%s'\n", token); + *                 for (i = 2; i < argc; i++) { + *                         if (strcmp (argv[i], token) == 0) { + *                                 printf ("%s\n", "dropping token!"); + *                                 drop_token (token, &tit); + *                                 break; + *                          } + *                 } + *                 if (iter_end) + *                         break; + *         } + * + *         printf ("finally: '%s'\n", buf); + * + *         return 0; + * } + */ +void +drop_token (char *token, token_iter_t *tit) +{ +        char *cursor = NULL; + +        for (cursor = token; *cursor; cursor++); +        if (cursor < tit->end) { +                /* +                 * We detect a zero inserted by next_token(). +                 * Step the cursor and copy what comes after +                 * to token. +                 */ +                for (cursor++; cursor < tit->end; *token++ = *cursor++); +        } + +        /* +         * Zero out the remainder of the buffer. +         * It would be enough to insert just a single zero, +         * but we continue 'till the end to have cleaner +         * memory content. +         */ +        for (cursor = token; cursor < tit->end; *cursor++ = 0); + +        /* Adjust the end to point to the new terminating zero. */ +        tit->end = token; +} +  /* Syntax formed according to RFC 1912 (RFC 1123 & 952 are more restrictive)  *     <hname> ::= <gen-name>*["."<gen-name>]                                     *     <gen-name> ::= <let-or-digit> <[*[<let-or-digit-or-hyphen>]<let-or-digit>] */ @@ -4657,3 +4799,63 @@ gf_fop_string (glusterfs_fop_t fop)                  return gf_fop_list[fop];          return "INVALID";  } + +int +close_fds_except (int *fdv, size_t count) +{ +        int          i            = 0; +        size_t       j            = 0; +        gf_boolean_t should_close = _gf_true; +#ifdef GF_LINUX_HOST_OS +        DIR           *d          = NULL; +        struct dirent *de         = NULL; +        struct dirent  scratch[2] = {{0,},}; +        char          *e          = NULL; + +        d = sys_opendir ("/proc/self/fd"); +        if (!d) +                return -1; + +        for (;;) { +                should_close = _gf_true; + +                errno = 0; +                de = sys_readdir (d, scratch); +                if (!de || errno != 0) +                        break; +                i = strtoul (de->d_name, &e, 10); +                if (*e != '\0' || i == dirfd (d)) +                        continue; + +                for (j = 0; j < count; j++) { +                        if (i == fdv[j]) { +                                should_close = _gf_false; +                                break; +                        } +               } +               if (should_close) +                        sys_close (i); +        } +        sys_closedir (d); +#else /* !GF_LINUX_HOST_OS */ +        struct rlimit rl; +        int ret = -1; + +        ret = getrlimit (RLIMIT_NOFILE, &rl); +        if (ret) +                return ret; + +        for (i = 0; i < rl.rlim_cur; i++) { +                should_close = _gf_true; +                for (j = 0; j < count; j++) { +                        if (i == fdv[j]) { +                                should_close = _gf_false; +                                break; +                        } +                } +                if (should_close) +                        sys_close (i); +        } +#endif /* !GF_LINUX_HOST_OS */ +        return 0; +} diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 6243732b522..6bd24179592 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -774,6 +774,14 @@ void skip_word (char **str);  /* returns a new string with nth word of given string. n>=1 */  char *get_nth_word (const char *str, int n); +typedef struct token_iter { +        char *end; +        char sep; +} token_iter_t; +char *token_iter_init (char *str, char sep, token_iter_t *tit); +gf_boolean_t next_token (char **tokenp, token_iter_t *tit); +void drop_token (char *token, token_iter_t *tit); +  gf_boolean_t mask_match (const uint32_t a, const uint32_t b, const uint32_t m);  gf_boolean_t gf_is_ip_in_net (const char *network, const char *ip_str);  char valid_host_name (char *address, int length); @@ -903,4 +911,6 @@ gf_fop_string (glusterfs_fop_t fop);  char *  get_ip_from_addrinfo (struct addrinfo *addr, char **ip); +int +close_fds_except (int *fdv, size_t count);  #endif /* _COMMON_UTILS_H */ diff --git a/libglusterfs/src/run.c b/libglusterfs/src/run.c index ff587f7e4de..a7d98af502f 100644 --- a/libglusterfs/src/run.c +++ b/libglusterfs/src/run.c @@ -23,7 +23,6 @@  #include <assert.h>  #include <signal.h>  #include <sys/wait.h> -#include <sys/resource.h>  #include "syscall.h"  #ifdef RUN_STANDALONE @@ -274,37 +273,9 @@ runner_start (runner_t *runner)                  }                  if (ret != -1 ) { -#ifdef GF_LINUX_HOST_OS -                        DIR *d = NULL; -                        struct dirent *de = NULL; -                        struct dirent  scratch[2] = {{0,},}; -                        char *e = NULL; - -                        d = sys_opendir ("/proc/self/fd"); -                        if (d) { -                                for (;;) { -                                        errno = 0; -                                        de = sys_readdir (d, scratch); -                                        if (!de || errno != 0) -                                                break; -                                        i = strtoul (de->d_name, &e, 10); -                                        if (*e == '\0' && i > 2 && -                                            i != dirfd (d) && i != xpi[1]) -                                                sys_close (i); -                                } -                                sys_closedir (d); -                        } else -                                ret = -1; -#else /* !GF_LINUX_HOST_OS */ -                        struct rlimit rl; -                        ret = getrlimit (RLIMIT_NOFILE, &rl); -                        GF_ASSERT (ret == 0); - -                        for (i = 3; i < rl.rlim_cur; i++) { -                                if (i != xpi[1]) -                                        sys_close (i); -                        } -#endif /* !GF_LINUX_HOST_OS */ +                        int fdv[4] = {0, 1, 2, xpi[1]}; + +                        ret = close_fds_except(fdv, sizeof (fdv) / sizeof (*fdv));                  }                  if (ret != -1) {  | 
