Skip to content

Commit 566a586

Browse files
author
hyqooo
committed
First version of search in PATH env var
1 parent f0ad7ad commit 566a586

File tree

1 file changed

+57
-2
lines changed

1 file changed

+57
-2
lines changed

shell.c

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <sys/wait.h>
1010
#include <termios.h>
1111
#include <unistd.h>
12+
#include <sys/stat.h>
13+
#include <dirent.h>
1214

1315
#include "tokenizer.h"
1416

@@ -42,6 +44,9 @@ int cmd_exit(struct tokens *tokens);
4244
int cmd_help(struct tokens *tokens);
4345
int cmd_pwd(struct tokens *tokens);
4446
int cmd_cd(struct tokens *tokens);
47+
char *procpathenv(char *, char *);
48+
49+
const int MAX_PATH_SIZE = 128;
4550

4651
/* Built-in command functions take token array (see parse.h) and return int */
4752
typedef int cmd_fun_t(struct tokens *tokens);
@@ -74,7 +79,6 @@ int cmd_exit(unused struct tokens *tokens) {
7479

7580
/* Prints current working directory */
7681
int cmd_pwd(unused struct tokens *tokens){
77-
const int MAX_PATH_SIZE = 128;
7882
char *path_buff = NULL;
7983
path_buff = (char *)malloc(sizeof(char) * MAX_PATH_SIZE);
8084
if (!path_buff)
@@ -118,6 +122,57 @@ int shell_exec(struct tokens *tokens){
118122
return 1;
119123
}
120124

125+
/*
126+
Shell can use both absolute path and relative path.
127+
TODO: shell should use PATH variables to lookup programs
128+
1. Determine whether is there the symbol '/'.
129+
2. If it does then path is absolute, so we just use it.
130+
3. If it doesn't then either it is a relative path and we use it or it is name of the program.
131+
4. If it's a name so we lookup in the current working directory.
132+
5. If it absent we lookup on the PATH environment.
133+
*/
134+
char* detpath(char *ppath){
135+
/* ppath is absolute path */
136+
if (*ppath == '/')
137+
return ppath;
138+
139+
/* Maybe dir would be opened and not closed. */
140+
if (opendir(ppath)){
141+
/* A component of ppath is not a directory so it's a name of the program */
142+
if (errno == ENOENT){
143+
/* enpath - path from PATH environment variable concatenated w/ name of the program */
144+
char *enpath = procpathenv(getenv("PATH"), ppath);
145+
if (!enpath) return NULL;
146+
return enpath;
147+
}
148+
}
149+
150+
/* ppath is relative path */
151+
return ppath;
152+
}
153+
154+
/* process PATH environment variables */
155+
char* procpathenv(char* env, char *name){
156+
static char *path = NULL;
157+
path = (char *)malloc(sizeof(char) * MAX_PATH_SIZE);
158+
if (!path) return NULL;
159+
160+
int i = 0;
161+
for (char *c = env; *c != '\000'; c++, i++){
162+
if (*c == ':'){
163+
if (!stat(strcat(path, name), NULL))
164+
break;
165+
166+
i = -1;
167+
continue;
168+
}
169+
*(path + i) = *c;
170+
}
171+
172+
path[i] = '\000';
173+
return path;
174+
}
175+
121176
/* Looks up the built-in command, if it exists. */
122177
int lookup(char cmd[]) {
123178
for (unsigned int i = 0; i < sizeof(cmd_table) / sizeof(fun_desc_t); i++)
@@ -141,7 +196,7 @@ void init_shell() {
141196
while (tcgetpgrp(shell_terminal) != (shell_pgid = getpgrp()))
142197
kill(-shell_pgid, SIGTTIN);
143198

144-
/* Saves the shell's process id */
199+
/* Saves the shell's process id */
145200
shell_pgid = getpid();
146201

147202
/* Take control of the terminal */

0 commit comments

Comments
 (0)