-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcmd_exec.c
139 lines (123 loc) · 2.89 KB
/
cmd_exec.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "main.h"
#include <stdio.h>
/**
* builtin_command - Executes a built-in cmd if it is found
* @sh: Pointer to the shell structure
* Return: Index of the built-in cmd that was executed, or 0 if none was found
*/
int builtin_command(shell *sh)
{
int i;
for (i = 0; i < sh->num_builtins; i++)
{
if (sh->args[0] && _strcmp(sh->args[0], sh->builtins[i].name, -1) == 0)
{
sh->builtins[i].func(sh);
break;
}
}
return (i);
}
/**
* external_command - Self explain
* @sh: Pointer to the shell structure
* @curr_line: Pointer to the current line number
*/
void external_command(shell *sh, int *curr_line)
{
pid_t pid;
int ret, wstatus;
char *full_path = NULL;
/* Check if the command is an absolute or relative path */
if (sh->args[0][0] == '/' || sh->args[0][0] == '.')
full_path = sh->args[0];
/* OR find the full path of the command */
else
full_path = find_command(sh->args[0]);
if (full_path)
{
pid = fork();
if (pid == 0)
{
ret = execve(full_path, sh->args, environ);
if (ret == -1)
perror(sh->args[0]);
_exit(ret);
}
else
{
wait(&wstatus);
/* Get the exit status of the child */
if (WIFEXITED(wstatus))
sh->status = WEXITSTATUS(wstatus);
}
if (full_path != sh->args[0])
free(full_path);
}
else
{
if (sh->interactive)
_fprintf(STDERR_FILENO, "%s: command not found\n", sh->args[0]);
else
_fprintf(STDERR_FILENO, "%s: %d: %s: not found\n",
SH_NAME, *curr_line, sh->args[0]);
sh->status = 127;
}
}
/**
* execute_command - Executes a command
* @sh: Pointer to the shell structure
* @curr_line: Pointer to the current line number
*/
void execute_command(shell *sh, int *curr_line)
{
int j;
char *alias_value;
j = builtin_command(sh);
if (j == sh->num_builtins)
{
/* TODO: add aliases contain also args */
alias_value = get_alias_value(sh, sh->args[0]);
if (alias_value)
sh->args[0] = alias_value;
external_command(sh, curr_line);
}
(*curr_line)++;
free(sh->args);
sh->args = NULL;
}
/**
* process_command - Reads input, parses it, and executes the cmd
* @sh: Pointer to the shell structure
* NOTE: '&&' still doesn't handle failed cmd
*/
void process_command(shell *sh)
{
int i, curr_line = 1;
char *oprs = ";|&", *saveptr, *cmd;
read_input(sh);
if (!sh->input)
return;
for (i = 0; i < sh->cmd_count; i++)
{
cmd = _strtok_r(sh->input[i], oprs, &saveptr);
while (cmd != NULL)
{
/* Parse the command and its arguments */
parse_command(sh, cmd);
/* Check if sh->args[0] is NULL or an empty string */
if (sh->args[0] && sh->args[0][0])
execute_command(sh, &curr_line);
/* Check for || and previous cmd success */
if (saveptr[0] == '|' && sh->status == 0)
break;
/* Check for && and previous cmd failed */
if (saveptr[0] == '&' && sh->status != 0)
break;
cmd = _strtok_r(NULL, oprs, &saveptr);
}
}
sh->cmd_count = 0;
if (sh->input)
free_double(&sh->input);
}