-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathprompt.c
166 lines (155 loc) · 3.32 KB
/
prompt.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include "shell.h"
/**
* getHistoryHead - intializes static head to struct hstry
* for passing to functions
* Return: address of hstrory head
**/
hstory **getHistoryHead(void)
{
static hstory *head = NULL;
return (&head);
}
/**
* getAliasHead - intializes static head to struct alias
* for passing to functions
* Return: address of alias head
**/
alias **getAliasHead(void)
{
static alias *head = NULL;
return (&head);
}
/**
* excute - forks a parent process and wait for child process
* to complete executing its child process
* @tokens: pointer to user input
* Return: nothing
**/
void excute(char **tokens)
{
pid_t pid;
int status;
char *p;
if (tokens[0][0] != '/')
{
if (find_builtins(tokens) == 0)
return;
}
pid = fork();
if (pid == -1)
{
_puts("Forking Error\n");
ext(NULL);
}
if (pid == 0)
{
/* Create a special node at beginning of child.. */
/* After child is done, free up all nodes until this node */
/* NOTE: because nodes were prepended */
p = NULL;
if (tokens[0][0] != '/')
check_path(tokens, p);
else if (execve(tokens[0], tokens, NULL) == -1)
{
_puts("No such file or directory\n");
ext(NULL);
}
}
else
waitpid(pid, &status, 0);
}
/**
* linep_withoutspaces - remove empty the spaces from begining of
* input string recursively
* @line: input string
* Return: pointer to first non space char
**/
char *linep_withoutspaces(char *line)
{
/* no need to null check, as empty string will not be passed */
if (*line == ' ')
{
line++;
return (linep_withoutspaces(line));
}
return (line);
}
/**
* promptUser - prompts user and recieves and input
* Return: nothing and exits when user enters cntrlD
**/
void promptUser(void)
{
char *input, **tokens, **cmds;
int hstryCount, *hstryPtr;
char *file;
hstory **h_head;
alias **a_head, *temp;
input = NULL;
tokens = NULL;
cmds = NULL;
temp = NULL;
h_head = getHistoryHead();
a_head = getAliasHead();
hstryCount = 0;
hstryPtr = &hstryCount;
file = _strcat(_getenv("HOME"), ".simple_shell_history", '/');
/* read history from file */
readFromFile(file, h_head, hstryPtr);
/* ignore cntrl+C */
signal(SIGINT, SIG_IGN);
_puts("$ ");
while (_getline(&input, STDIN_FILENO) != 0)
{
addHistory(h_head, input, hstryPtr);
/* discard the begining spaces */
input = linep_withoutspaces(input);
if (*input != '\0')
{
/* command separator */
cmds = tokenize(input, ';');
if (cmds)
{
while (*cmds)
{
/* add cyclic alias */
temp = findAlias(a_head, *cmds);
/* check if an alias is not pointing to itself */
if (temp != NULL && (_strcmp(temp->key, temp->value) != 0))
{
temp = find_aliasToalias(a_head, temp->value);
*cmds = temp->value;
}
tokens = tokenize(*cmds, ' ');
if (tokens)
{
excute(tokens);
_free(tokens);
}
cmds++;
}
}
else
{
/* add cyclic alias */
temp = findAlias(a_head, *cmds);
/* check if an alias is not pointing to itself */
if (temp != NULL && (_strcmp(temp->key, temp->value) != 0))
{
temp = find_aliasToalias(a_head, temp->value);
*cmds = temp->value;
}
tokens = tokenize(*cmds, ' ');
if (tokens)
{
excute(tokens);
_free(tokens);
}
}
_free(cmds);
} /* input if block ends */
_puts("$ ");
}
/* need to read history before exit */
ext(NULL);
}