Skip to content
Snippets Groups Projects
Commit 68411d3e authored by Sébastien Gendre's avatar Sébastien Gendre
Browse files

Start to implement the pipeline mechanism with a chained list of cmd_t

parent 5ab94051
No related branches found
No related tags found
No related merge requests found
......@@ -3,10 +3,22 @@
#include "command.h"
int command_from_str(char *str, cmd_t *cmd) {
cmd_t *command_from_str(char *str) {
// Stor next command argument, used in the do…while loop
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
char* next_arg;
// 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;
......@@ -19,10 +31,10 @@ int command_from_str(char *str, cmd_t *cmd) {
if (cmd->argc == 0) {
// Extract the commmand name
next_arg = strtok(str, DELIMITERS);
next_arg = strtok(str_copy, ARGS_DELIMITERS);
} else {
// Get the next argument
next_arg = strtok(NULL, DELIMITERS);
next_arg = strtok(NULL, ARGS_DELIMITERS);
}
// Extend the cmd->argv array with a new char pointer
......@@ -47,22 +59,83 @@ int command_from_str(char *str, cmd_t *cmd) {
} else {
cmd->type = JOB;
}
return 0;
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
void command_dispose(cmd_t *cmd) {
// Free all the command arguments str inside argv
for (int i = 0; i < cmd->argc; ++i) {
free(cmd->argv[i]);
}
// Then, finally, free argv
/* for (int i = 0; i < cmd->argc; ++i) { */
/* free(cmd->argv[i]); */
/* } */
// Free argv
free(cmd->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);
}
}
// Execute the commande
int command_exec(cmd_t *cmd) {
int command_pipeline_exec(cmd_t *cmd) {
switch (cmd->type) {
case BUILTIN: {
return builtin_exec_builtin_command(cmd->argc, cmd->argv);
......
......@@ -13,7 +13,8 @@
#include "jobs.h"
// Chars used to separate atoms of a command
#define DELIMITERS " \t"
#define ARGS_DELIMITERS " \t"
#define COMMAND_PIPE_DELIMITER "|"
// Command types
enum command_type {BUILTIN, JOB, PIZZA};
......@@ -21,22 +22,33 @@ enum command_type {BUILTIN, JOB, PIZZA};
// A full user command
typedef struct cmd cmd_t;
struct cmd {
enum command_type type; // Command type
enum command_type type; // Command type
char** argv; // The command arguments
int argc; // Number of command arguments
bool foreground; // Should the command be run in foreground or background (might not be relevant for your TP depending on TP version)
cmd_t *next; // Pointer to the next command, in case of pipe
};
/* Parse a user input to get a command
/* Parse a string to get one command
*
* Parameters
* - user_input: A string containing the full command. IT WILL BE MODIFIED BY THE FUNCTION.
* - str: A string containing the full command. IT WILL BE MODIFIED BY THE FUNCTION.
* - cmd: Command updated from user input string (i.e. command input). MUST BE DISPOSED SEE FUNCTION dispose_command
*
* Return:
* -1 in case of error otherwise 0.
* A pointer to the new command, NULL in case of error
*/
int command_from_str(char *str, cmd_t *cmd);
cmd_t *command_from_str(char *str);
/* Parse a string to get a pipeline of commands
*
* Parameters
* - user_input: A string containing the full command. IT WILL BE MODIFIED BY THE FUNCTION.
*
* Return:
* The pointer to the first command, NULL in case of error
*/
cmd_t *command_pipeline_from_str(char *str);
/* Dispose of the command, which free some allocated memory
......@@ -47,6 +59,13 @@ int command_from_str(char *str, cmd_t *cmd);
*/
void command_dispose(cmd_t *cmd);
/* Fee a pipeline of command from the given command
*
* Parameters:
* - cmd: The command start command of the pipeline to free
*/
void command_free_pipeline(cmd_t *cmd);
/* Execute a given command as job or as builtin
*
* Parameters:
......@@ -55,7 +74,7 @@ void command_dispose(cmd_t *cmd);
* Return:
* - The command return code, 0 is success
*/
int command_exec(cmd_t *cmd);
int command_pipeline_exec(cmd_t *cmd);
#endif /* COMMAND_H */
......@@ -10,15 +10,16 @@
int main(int argc, char *argv[])
{
char * user_input;
cmd_t command;
char *user_input;
cmd_t *command_p;
user_input = calloc(LIMIT_USER_INPUT_MAX_LENGTH, sizeof(char));
while(1){
interface_ask_user_input(user_input);
command_from_str(user_input, &command);
command_exec(&command);
command_p = command_pipeline_from_str(user_input);
command_pipeline_exec(command_p);
command_free_pipeline(command_p);
}
return 0;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment