message (1)
message (1)
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "cmd.h"
#include "utils.h"
#define READ 0
#define WRITE 1
/**
* Internal change-directory command.
*/
static bool shell_cd(word_t *dir)
{
/* TODO: Execute cd. */
if (dir == NULL)
{
chdir(NULL);
return false;
}
chdir(dir->string);
return true;
}
/**
* Internal exit/quit command.
*/
static int shell_exit(void)
{
/* TODO: Execute exit/quit. */
/**
* Parse a simple command (internal, environment variable assignment,
* external command).
*/
static int handle_variable_assignment(simple_command_t *s)
{
char *eq = strchr(s->verb->string, '=');
char *value = eq + 1;
size_t name_len = eq - s->verb->string;
char *name = malloc(name_len * sizeof(char) + 1);
memcpy(name, s->verb->string, name_len);
name[name_len] = '\0';
int ret = setenv(name, value, 1);
free(name);
return ret;
}
const char **word_to_strings(word_t *params)
{
word_t *p = params;
size_t i = 0;
while (p != NULL)
{
i++;
p = p->next_word;
}
const char **params_arr = malloc(i * sizeof(const char *));
p = params;
size_t j = 0;
while (p != NULL)
{
params_arr[j] = p->string;
j++;
p = p->next_word;
}
return params_arr;
// TODO LATER FIX THE MEMORY LEAK HERE
}
static int parse_simple(simple_command_t *s, int level, command_t *father)
{
/* TODO: Sanity checks. */
if (s == NULL)
return -1;
/* TODO: If builtin command, execute the command. */
if (s->verb != NULL && s->verb->string != NULL)
{
if (strcmp(s->verb->string, "cd") == 0)
return shell_cd(s->params);
else if (!strcmp(s->verb->string, "exit") || !strcmp(s->verb->string,
"leave"))
shell_exit();
}
/**
* Process two commands in parallel, by creating two children.
*/
static bool run_in_parallel(command_t *cmd1, command_t *cmd2, int level,
command_t *father)
{
/* TODO: Execute cmd1 and cmd2 simultaneously. */
/**
* Run commands by creating an anonymous pipe (cmd1 | cmd2).
*/
static bool run_on_pipe(command_t *cmd1, command_t *cmd2, int level,
command_t *father)
{
/* TODO: Redirect the output of cmd1 to the input of cmd2. */
/**
* Parse and execute a command.
*/
int parse_command(command_t *c, int level, command_t *father)
{
/* TODO: sanity checks */
if (c->op == OP_NONE)
{
/* TODO: Execute a simple command. */
switch (c->op)
{
case OP_SEQUENTIAL:
/* TODO: Execute the commands one after the other. */
break;
case OP_PARALLEL:
/* TODO: Execute the commands simultaneously. */
break;
case OP_CONDITIONAL_NZERO:
/* TODO: Execute the second command only if the first one
* returns non zero.
*/
break;
case OP_CONDITIONAL_ZERO:
/* TODO: Execute the second command only if the first one
* returns zero.
*/
break;
case OP_PIPE:
/* TODO: Redirect the output of the first command to the
* input of the second.
*/
break;
default:
return SHELL_EXIT;
}