Newer
Older
// Command representation and manipulation
// Sébastien Gendre <seb@k-7.ch>
#include "command.h"
cmd_t *command_from_str(char *str) {
char *str_copy = malloc((strlen(str)+1)*sizeof(char));
// Generate the command
cmd_t *cmd = malloc(sizeof(cmd_t));
// Store next command argument, used in the do…while loop
// Work with a copy of the given str
strcpy(str_copy, str);
// If malloc didn't work
if (cmd == NULL) {
perror("Malloc error for new command");
return (cmd_t *)NULL;
}
// Initialize a simple command (empty, simple, foreground)
cmd->type = JOB;
// Extract the command arguments
do {
if (cmd->argc == 0) {
// Extract the commmand name
next_arg = strtok(str_copy, ARGS_DELIMITERS);
} else {
// Get the next argument
next_arg = strtok(NULL, ARGS_DELIMITERS);
}
// Extend the cmd->argv array with a new char pointer
cmd->argv = realloc(cmd->argv, (cmd->argc+1)*sizeof(char*));
if( cmd->argv == NULL) {
// In case the reallocation didn't work
die_errno("parse_command::realloc");
}
// Store the argument inside cmd->argv
cmd->argv[cmd->argc] = next_arg;
// A new non null element will be added to cmd->argv
// Define the command type
if (builtin_is_command_builtin(cmd->argc, cmd->argv)) {
cmd->type = BUILTIN;
} else {
cmd->type = JOB;
}
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
return cmd;
}
/* Parse a string to get a pipeline of commands */
cmd_t *command_pipeline_from_str(char *str){
char **commands = NULL;
char *next_command = NULL;
int commands_count = 0;
cmd_t *previous_command = NULL;
cmd_t *first_command = NULL;
// Cut str into a list of commands string
do {
if (commands_count == 0) {
// Extract the first command
next_command = strtok(str, COMMAND_PIPE_DELIMITER);
} else {
// Get the next command
next_command = strtok(NULL, COMMAND_PIPE_DELIMITER);
}
// Extend the command list to add a new command
commands = realloc(commands, (commands_count+1)*sizeof(char *));
if( commands == NULL) {
// In case the reallocation didn't work
die_errno("parse_command::realloc");
}
// Store the next command
commands[commands_count] = next_command;
if (next_command != NULL) {
// A now command has been added
commands_count += 1;
}
} while (next_command != NULL);
// For each command string, create a command struct
for (int i = 0; i < commands_count; ++i) {
if (previous_command == NULL) {
first_command = command_from_str(commands[i]);
} else {
previous_command->next = command_from_str(commands[i]);
}
}
return first_command;
// Dispose the commande
// Free all the command arguments str inside argv
/* for (int i = 0; i < cmd->argc; ++i) { */
/* free(cmd->argv[i]); */
/* } */
// Free argv
// Then, finally, free the command
free(cmd);
}
/* Fee a pipeline of command from the given command */
void command_free_pipeline(cmd_t *cmd) {
if (cmd->next != NULL) {
command_free_pipeline(cmd->next);
} else {
command_dispose(cmd);
}
int command_pipeline_exec(cmd_t *cmd) {
switch (cmd->type) {
case BUILTIN: {
return builtin_exec_builtin_command(cmd->argc, cmd->argv);
break;
}
case PIZZA:
printf("I'm no Pizza delivery man, I'm a Ninja Turtle. I eat Pizza\n");
return 0;
break;
case JOB:
default:
return job_exec_command(cmd->argc, cmd->argv);
break;
}