/* * %CopyrightBegin% * * Copyright Ericsson AB 1999-2009. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * %CopyrightEnd% */ /* * Purpose: Safe memory allocation and other utilities. * */ #include #include #include #include "esock_utils.h" static char *strtok_quote(char *s1, const char *s2); void *esock_malloc(size_t size) { void *p; p = malloc(size); if (!p) { fprintf(stderr, "esock_malloc: cannot alloc %d bytes\n", size); exit(EXIT_FAILURE); } return p; } void *esock_realloc(void *p, size_t size) { void *np; np = realloc(p, size); if (!np) { fprintf(stderr, "esock_realloc: cannot realloc %d bytes\n", size); exit(EXIT_FAILURE); } return np; } void esock_free(void *p) { free(p); } /* Builds an argv array from cmd. Spaces and tabs within double quotes * are not considered delimiters. Double quotes are removed. * * The return value is argc, and the pointer to char ** is set. argc * is non-negative, argv[0], ..., argv[argc - 1] are pointers to * strings, and argv[argc] == NULL. All argv[0], ..., argv[argc - 1] * must be freed by the user, and also the argv pointer itself. * * Example: cmd = abc"/program files/"olle nisse, results in * argv[0] = abc/program files/olle, argv[1] = nisse, argc = 2. * */ int esock_build_argv(char *cmd, char ***argvp) { int argvsize = 10, argc = 0; char *args, *tokp, *argp; char **argv; argv = esock_malloc(argvsize * sizeof(char *)); args = esock_malloc(strlen(cmd) + 1); strcpy(args, cmd); tokp = strtok_quote(args, " \t"); while (tokp != NULL) { if (argc + 1 >= argvsize) { argvsize += 10; argv = esock_realloc(argv, argvsize * sizeof(char *)); } argp = esock_malloc(strlen(tokp) + 1); strcpy(argp, tokp); argv[argc++] = argp; tokp = strtok_quote(NULL, " \t"); } esock_free(args); argv[argc] = NULL; *argvp = argv; return argc; } /* strtok_quote * Works as strtok, but characters within pairs of double quotes are not * considered as delimiters. Quotes are removed. */ static char *strtok_quote(char *s1, const char *s2) { static char *last; char *s, *t, *u; s = (s1) ? s1 : last; if (!s) return last = NULL; while (*s != '"' && *s != '\0' && strchr(s2, *s)) s++; t = s; while (1) { if (*t == '"') { t++; while (*t != '"' && *t != '\0') t++; if (*t == '\0') { last = NULL; goto end; } t++; } while(*t != '"' && *t != '\0' && !strchr(s2, *t)) t++; if (*t == '\0') { last = NULL; goto end; } else if (*t != '"') { *t = '\0'; last = t + 1; goto end; } } end: /* Remove quotes */ u = t = s; while (*u) { if (*u == '"') u++; else *t++ = *u++; } *t = '\0'; return s; }