0% found this document useful (0 votes)
5 views

message (1)

uoipu

Uploaded by

Vlad 29
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

message (1)

uoipu

Uploaded by

Vlad 29
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

// SPDX-License-Identifier: BSD-3-Clause

#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. */

return 0; /* TODO: Replace with actual exit code. */


}

/**
* 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();
}

/* TODO: If variable assignment, execute the assignment and return


* the exit status.
*/
if (strchr(s->verb->string, '='))
return handle_variable_assignment(s);

pid_t pid = fork();


if (pid == 0)
{
if (s->in)
{
int in_fd = open(s->in->string, O_RDONLY);
dup2(in_fd, STDIN_FILENO);
close(in_fd);
}
if (s->out)
{
int out_fd = open(s->out->string, O_WRONLY | O_CREAT | O_TRUNC,
0644);
dup2(out_fd, STDOUT_FILENO);
close(out_fd);
}
if (s->err)
{
int err_fd = open(s->err->string, O_WRONLY | O_CREAT | O_TRUNC,
0644);
dup2(err_fd, STDERR_FILENO);
close(err_fd);
}
const char **params_arr = word_to_strings(s->params);
execvp(s->verb->string, (char *const *)params_arr);
}
/* TODO: If external command:
* 1. Fork new process
* 2c. Perform redirections in child
* 3c. Load executable in child
* 2. Wait for child
* 3. Return exit status
*/

return 0; /* TODO: Replace with actual exit status. */


}

/**
* 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. */

return true; /* TODO: Replace with actual exit status. */


}

/**
* 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. */

return true; /* TODO: Replace with actual exit status. */


}

/**
* 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. */

return 0; /* TODO: Replace with actual exit code of 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;
}

return 0; /* TODO: Replace with actual exit code of command. */


}

You might also like