dockapps/wmifs/wmgeneral/misc.c
Doug Torrance dae24a2f5d wmgeneral: Free pointer.
Fixes "(error) Memory leak: argv" found by cppcheck.
2015-05-20 10:44:40 +01:00

168 lines
3.5 KiB
C

/* dock.c- built-in Dock module for WindowMaker
*
* WindowMaker window manager
*
* Copyright (c) 1997 Alfredo K. Kojima
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "list.h"
#include "misc.h"
/*
*----------------------------------------------------------------------
* parse_command--
* Divides a command line into a argv/argc pair.
*----------------------------------------------------------------------
*/
#define PRC_ALPHA 0
#define PRC_BLANK 1
#define PRC_ESCAPE 2
#define PRC_DQUOTE 3
#define PRC_EOS 4
#define PRC_SQUOTE 5
typedef struct {
short nstate;
short output;
} DFA;
static DFA mtable[9][6] = {
{{3, 1}, {0, 0}, {4, 0}, {1, 0}, {8, 0}, {6, 0} },
{{1, 1}, {1, 1}, {2, 0}, {3, 0}, {5, 0}, {1, 1} },
{{1, 1}, {1, 1}, {1, 1}, {1, 1}, {5, 0}, {1, 1} },
{{3, 1}, {5, 0}, {4, 0}, {1, 0}, {5, 0}, {6, 0} },
{{3, 1}, {3, 1}, {3, 1}, {3, 1}, {5, 0}, {3, 1} },
{{-1, -1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* final state */
{{6, 1}, {6, 1}, {7, 0}, {6, 1}, {5, 0}, {3, 0} },
{{6, 1}, {6, 1}, {6, 1}, {6, 1}, {5, 0}, {6, 1} },
{{-1, -1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0} } /* final state */
};
char*
next_token(char *word, char **next)
{
char *ptr;
char *ret, *t;
int state, ctype;
t = ret = malloc(strlen(word)+1);
if (ret == NULL) {
fprintf(stderr, "Insufficient memory.\n");
exit(EXIT_FAILURE);
}
ptr = word;
state = 0;
*t = 0;
while (1) {
if (*ptr == 0)
ctype = PRC_EOS;
else if (*ptr == '\\')
ctype = PRC_ESCAPE;
else if (*ptr == '"')
ctype = PRC_DQUOTE;
else if (*ptr == '\'')
ctype = PRC_SQUOTE;
else if (*ptr == ' ' || *ptr == '\t')
ctype = PRC_BLANK;
else
ctype = PRC_ALPHA;
if (mtable[state][ctype].output) {
*t = *ptr; t++;
*t = 0;
}
state = mtable[state][ctype].nstate;
ptr++;
if (mtable[state][0].output < 0)
break;
}
if (*ret == 0)
t = NULL;
else
t = strdup(ret);
free(ret);
if (ctype == PRC_EOS)
*next = NULL;
else
*next = ptr;
return t;
}
extern void
parse_command(char *command, char ***argv, int *argc)
{
LinkedList *list = NULL;
char *token, *line;
int count, i;
line = command;
do {
token = next_token(line, &line);
if (token)
list = list_cons(token, list);
} while (token != NULL && line != NULL);
count = list_length(list);
*argv = malloc(sizeof(char *)*count);
i = count;
while (list != NULL) {
(*argv)[--i] = list->head;
list_remove_head(&list);
}
*argc = count;
}
extern pid_t
execCommand(char *command)
{
pid_t pid;
char **argv;
int argc;
parse_command(command, &argv, &argc);
if (argv == NULL)
return 0;
pid = fork();
if (pid == 0) {
char **args;
int i;
args = malloc(sizeof(char *)*(argc+1));
if (!args)
exit(10);
for (i = 0; i < argc; i++)
args[i] = argv[i];
args[argc] = NULL;
execvp(argv[0], args);
exit(10);
}
free(argv);
return pid;
}