-
Notifications
You must be signed in to change notification settings - Fork 0
/
execve.c
143 lines (133 loc) · 2.63 KB
/
execve.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
140
141
142
143
#include "shell.h"
/**
* countArgs - count the number of command line arguments
* @cmd: the command line argument
* Return: the number of command line arguments
*/
int countArgs(const char *cmd)
{
char *token, *delimiters = " \n\t\r", *copy_cmd;
int num_tokens = 0;
copy_cmd = _strdup((char *)cmd);
if (copy_cmd == NULL)
{
perror("Error duplicating command string");
exit(EXIT_FAILURE);
}
token = strtok(copy_cmd, delimiters);
while (token)
{
num_tokens++;
token = strtok(NULL, delimiters);
}
free(copy_cmd);
return (num_tokens);
}
/**
* split_string - this function tokenize the string
* @cmd: command to be tokenized
* Return: the tokenized command
*/
char **split_string(const char *cmd)
{
char *token, *delimiters = " \n\t\r", *copy_cmd;
char **av;
int i = 0, j, num_tokens;
copy_cmd = _strdup((char *)cmd);
if (copy_cmd == NULL)
{
perror("Error duplicating command string");
exit(EXIT_FAILURE);
}
num_tokens = countArgs(copy_cmd);
av = (char **)malloc(sizeof(char *) * (num_tokens + 1));
if (av == NULL)
{
perror("Allocating memory using malloc failed");
free(copy_cmd);
exit(EXIT_FAILURE);
}
token = strtok(copy_cmd, delimiters);
while (token)
{
av[i] = _strdup(token);
if (av[i] == NULL)
{
perror("Error duplicating token string");
for (j = 0; j < i; j++)
free(av[j]);
free(av);
free(copy_cmd);
exit(EXIT_FAILURE);
}
token = strtok(NULL, delimiters);
i++;
}
av[i] = NULL;
free(copy_cmd);
return (av);
}
/**
* execute_cmd - it executes the command
* @cmd: the command to be executed
* @envp: envp is set to NULL
* Return: nothing
*/
void execute_cmd(const char *cmd, char *const envp[])
{
int status;
char **new_av = split_string(cmd);
pid_t pid;
char *path_cmd = NULL;
if (new_av == NULL)
{
perror("Error splitting command");
exit(EXIT_FAILURE);
}
pid = fork();
if (pid == -1)
{
_perror(cmd, "not found");
free_new_av(new_av);
exit(EXIT_FAILURE);
}
if (pid == 0)
{
path_cmd = handle_path(new_av[0]);
if (path_cmd == NULL)
{
_perror(cmd, "not found");
free_new_av(new_av);
free(path_cmd);
free((void *)cmd);
exit(EXIT_FAILURE);
}
else if (execve(path_cmd, new_av, envp) == -1)
{
_perror(cmd, "not found");
free_new_av(new_av);
free(path_cmd);
free((void *)cmd);
_exit(1);
}
}
else
waitpid(pid, &status, 0);
free_new_av(new_av);
free(path_cmd);
}
/**
* free_new_av - it frees the new_av variable used in the execve function
* @new_av: the variable to be freed
*/
void free_new_av(char **new_av)
{
int i = 0;
if (new_av == NULL)
return;
for (; new_av[i] != NULL; i++)
{
free(new_av[i]);
}
free(new_av);
}