-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathshellutil.c
More file actions
201 lines (185 loc) · 3.64 KB
/
shellutil.c
File metadata and controls
201 lines (185 loc) · 3.64 KB
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#include "shell.h"
/**
* _getenv - Gets the value of an environment variable.
* @name: The name of the environment variable.
*
* Return: A pointer to the environment variable, or NULL if not found.
*/
char *_getenv(const char *name)
{
int n = strlen(name);
int i = 0;
while (environ[i])
{
if (_strncmp(name, environ[i], n) == 0 && environ[i][n] == '=')
return (&environ[i][n + 1]);
i++;
}
return (NULL);
}
/**
* nopath - Searches for an executable in directories specified by PATH.
* @command: A pointer to store the resulting full path of the executable.
* @argv: An array of strings containing command and arguments.
* @status: status of exit
* Return: 0 to continue
*/
int nopath(char *command, char *argv[], int *status)
{
char *path = _getenv("PATH");
char *path_copy = _strdup(path);
char *dir = NULL;
int ndir;
if (!path)
{
perror("PATH");
return (0);
}
dir = strtok(path_copy, ":");
while (dir)
{
ndir = _strlen(dir) + _strlen(argv[0]) + 2;
command = malloc(sizeof(char) * ndir);
command[0] = '\0';
_strcpy(command, dir);
_strcat(command, "/");
_strcat(command, argv[0]);
if (access(command, X_OK) == 0)
break;
free(command);
command = NULL;
dir = strtok(NULL, ":");
}
free(path_copy);
if (!command)
{
if (access(command, X_OK) == -1)
{
perror("./hsh");
free(command);
return (-1);
}
*status = 2;
perror("");
return (0);
}
argv[0] = command;
return (1);
}
/**
* tokenize - Tokenizes a string into an array of strings.
* @nnread: Pointer to store the token during tokenization.
* @argv: Array of strings to store the tokens.
* @line: The input string to be tokenized.
*
* Return: 0 on failure.
*/
int tokenize(char *nnread, char *argv[], char *line)
{
int i = 0;
nnread = strtok(line, " \n");
while (nnread != NULL)
{
argv[i] = nnread;
i++;
nnread = strtok(NULL, " \n");
}
argv[i] = NULL;
if (argv[0] == NULL)
{
free(line);
return (0);
}
if (argv[0][0] == '#')
{
free(line);
exit(EXIT_SUCCESS);
}
return (1);
}
/**
* checkbuiltins - Checks for built-in shell commands and handles them.
* @check: An error code for checking errors.
* @line: The input line from the user.
* @nread: The number of characters read from the input line.
* @last_exit: exit status from forking
* Return: 0 to continue
*/
int checkbuiltins(int check, char *line, ssize_t nread, int last_exit)
{
int n;
if ((nread == -1 && check == errno))
{
free(line);
exit(EXIT_SUCCESS);
}
if ((_strcmp(line, "exit\n") == 0) || (_strcmp(line, "exit") == 0))
{
free(line);
exit(last_exit);
}
if (_strcmp(line, "env\n") == 0 || _strcmp(line, "env") == 0)
{
n = print_env();
free(line);
exit(EXIT_SUCCESS);
if (n == -1)
perror("environ");
}
if (nread == 1)
{
free(line);
return (0);
}
if (nread == -1 && check != errno)
{
perror("getline");
free(line);
exit(EXIT_FAILURE);
}
return (1);
}
/**
* forking - Creates a child process and executes a program in it.
* @argv: An array of strings containing the program path and arguments.
* @mode: 1 for interactive and 2 for non interactive
* @line: line from user
* Return: status number
*/
int forking(char *argv[], int mode, char *line)
{
char *newargv[2];
pid_t pid;
int status = 0;
pid = fork();
if (pid == -1)
{
free(line);
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0)
{
if (mode == 1)
{
execve(argv[0], argv, environ);
}
else
{
newargv[0] = argv[0];
newargv[1] = NULL;
execve(argv[0], newargv, environ);
}
perror("execve");
exit(EXIT_FAILURE);
}
else
{
wait(&status);
if (WIFEXITED(status))
{
status = WEXITSTATUS(status);
}
}
return (status);
}