cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

argv_split.c (1721B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Helper function for splitting a string into an argv-like array.
      4 */
      5
      6#include <stdlib.h>
      7#include <linux/kernel.h>
      8#include <linux/ctype.h>
      9#include <linux/string.h>
     10
     11static const char *skip_arg(const char *cp)
     12{
     13	while (*cp && !isspace(*cp))
     14		cp++;
     15
     16	return cp;
     17}
     18
     19static int count_argc(const char *str)
     20{
     21	int count = 0;
     22
     23	while (*str) {
     24		str = skip_spaces(str);
     25		if (*str) {
     26			count++;
     27			str = skip_arg(str);
     28		}
     29	}
     30
     31	return count;
     32}
     33
     34/**
     35 * argv_free - free an argv
     36 * @argv - the argument vector to be freed
     37 *
     38 * Frees an argv and the strings it points to.
     39 */
     40void argv_free(char **argv)
     41{
     42	char **p;
     43	for (p = argv; *p; p++) {
     44		free(*p);
     45		*p = NULL;
     46	}
     47
     48	free(argv);
     49}
     50
     51/**
     52 * argv_split - split a string at whitespace, returning an argv
     53 * @str: the string to be split
     54 * @argcp: returned argument count
     55 *
     56 * Returns an array of pointers to strings which are split out from
     57 * @str.  This is performed by strictly splitting on white-space; no
     58 * quote processing is performed.  Multiple whitespace characters are
     59 * considered to be a single argument separator.  The returned array
     60 * is always NULL-terminated.  Returns NULL on memory allocation
     61 * failure.
     62 */
     63char **argv_split(const char *str, int *argcp)
     64{
     65	int argc = count_argc(str);
     66	char **argv = calloc(argc + 1, sizeof(*argv));
     67	char **argvp;
     68
     69	if (argv == NULL)
     70		goto out;
     71
     72	if (argcp)
     73		*argcp = argc;
     74
     75	argvp = argv;
     76
     77	while (*str) {
     78		str = skip_spaces(str);
     79
     80		if (*str) {
     81			const char *p = str;
     82			char *t;
     83
     84			str = skip_arg(str);
     85
     86			t = strndup(p, str-p);
     87			if (t == NULL)
     88				goto fail;
     89			*argvp++ = t;
     90		}
     91	}
     92	*argvp = NULL;
     93
     94out:
     95	return argv;
     96
     97fail:
     98	argv_free(argv);
     99	return NULL;
    100}