9
9
#include <sys/wait.h>
10
10
#include <termios.h>
11
11
#include <unistd.h>
12
+ #include <sys/stat.h>
13
+ #include <dirent.h>
12
14
13
15
#include "tokenizer.h"
14
16
@@ -42,6 +44,9 @@ int cmd_exit(struct tokens *tokens);
42
44
int cmd_help (struct tokens * tokens );
43
45
int cmd_pwd (struct tokens * tokens );
44
46
int cmd_cd (struct tokens * tokens );
47
+ char * procpathenv (char * , char * );
48
+
49
+ const int MAX_PATH_SIZE = 128 ;
45
50
46
51
/* Built-in command functions take token array (see parse.h) and return int */
47
52
typedef int cmd_fun_t (struct tokens * tokens );
@@ -74,7 +79,6 @@ int cmd_exit(unused struct tokens *tokens) {
74
79
75
80
/* Prints current working directory */
76
81
int cmd_pwd (unused struct tokens * tokens ){
77
- const int MAX_PATH_SIZE = 128 ;
78
82
char * path_buff = NULL ;
79
83
path_buff = (char * )malloc (sizeof (char ) * MAX_PATH_SIZE );
80
84
if (!path_buff )
@@ -118,6 +122,57 @@ int shell_exec(struct tokens *tokens){
118
122
return 1 ;
119
123
}
120
124
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
+
121
176
/* Looks up the built-in command, if it exists. */
122
177
int lookup (char cmd []) {
123
178
for (unsigned int i = 0 ; i < sizeof (cmd_table ) / sizeof (fun_desc_t ); i ++ )
@@ -141,7 +196,7 @@ void init_shell() {
141
196
while (tcgetpgrp (shell_terminal ) != (shell_pgid = getpgrp ()))
142
197
kill (- shell_pgid , SIGTTIN );
143
198
144
- /* Saves the shell's process id */
199
+ /* Saves the shell's process id */
145
200
shell_pgid = getpid ();
146
201
147
202
/* Take control of the terminal */
0 commit comments