-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
200 lines (186 loc) · 4.67 KB
/
main.c
File metadata and controls
200 lines (186 loc) · 4.67 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
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
extern char **environ;
int start(char *command[]);
void ret_msg(pid_t pid, int ret_code);
int run(char *command[]);
int shell_kill(char *command[]);
int shell_stop(char *command[]);
int shell_continue(char *command[]);
void shell_wait();
int main()
{
int n;
char *token[100];
char palavra[100] = "";
while (1)
{
printf("myshell>");
fflush(stdout);
if (fgets(palavra, 100, stdin) == NULL) {
return 0;
}
token[0] = strtok(palavra, " \t\n");
if (token[0] != NULL) {
n = 0;
while (token[n] != 0)
{
n++;
token[n] = strtok(NULL, " \t\n");
if (token[n] == NULL)
{
/*if (n == 2)
{ // Precisei colocar isso por que se o argv no execvp for direto null ele da erro.
token[n] = "";
n++;
}*/
token[n] = 0;
break;
}
}
/*for (int i = 0; i <= n; i++) // Print do comando para debug
{
printf("%s ", token[i]);
}*/
printf("\n");
if (strcmp(token[0], "start") == 0) {
start(token+1);
}
else if (strcmp(token[0], "wait") == 0)
{
shell_wait();
}
else if (strcmp(token[0], "run") == 0)
{
run(token+1);
}
else if (strcmp(token[0], "kill") == 0)
{
shell_kill(token+1);
}
else if (strcmp(token[0], "stop") == 0)
{
shell_stop(token+1);
}
else if (strcmp(token[0], "continue") == 0)
{
shell_continue(token+1);
}
else if (strcmp(token[0], "pid") == 0) // Só pra facilitar
{
printf("pid %d\n", getpid());
/*printf("token %d\n", token);
printf("token+1 %d\n", token+1);
printf("token[1] %d\n", token[1]);*/
}
else if (strcmp(token[0], "exit") == 0)
{
printf("Closing myshell\n");
return 0;
}
else
{
printf("myshell: comando desconhecido: %s\n", token[0]);
}
}
}
}
void shell_wait() {
int wstatus;
pid_t wait_code = wait(&wstatus); // @todo Verificar como essa função se comporta, pois parece que ela não é bloqueante nesse nível aqui
if (wait_code == -1) {
printf("myshell: não há processos restantes\n");
} else if ( WIFEXITED(wstatus)) {
printf("myshell: processo %d terminou normalmente com sinal %d\n", wait_code, WEXITSTATUS(wstatus));
} else if ( WIFSIGNALED(wstatus)) {
printf("myshell: processo %d terminou de forma anormal com sinal %d\n", wait_code, WTERMSIG(wstatus));
}
}
int start(char *command[]) {
if (command[0] != NULL) {
pid_t pid;
pid = fork();
if (pid == 0) {
int ret_code = execvp(command[0], command);
pid = getpid();
ret_msg(pid, ret_code);
exit(ret_code);
}
else
{
printf("myshell: processo %d iniciado\n", pid);
return 0;
}
}
return -1;
}
int run(char *command[]) {
if (command[0] != NULL) {
pid_t pid;
pid = fork();
if (pid == 0) {
int ret_code = execvp(command[0], command);
pid = getpid();
ret_msg(pid, ret_code);
exit(ret_code);
}
else
{
printf("myshell: processo %d iniciado\n", pid);
shell_wait();
return 0;
}
}
return -1;
}
int shell_kill(char *command[]) {
if (command[0] != NULL) {
int pid = atoi(*(command));
if (kill(pid, SIGKILL) == 0) {
printf("myshell: processo %d foi finalizado\n", pid);
} else {
printf("myshell: processo %d não pôde ser finalizado\n", pid);
}
} else {
printf("myshell: argumento esperado\n");
}
return -1;
}
int shell_stop(char *command[]) {
if (command[0] != NULL) {
int pid = atoi(*(command));
if (kill(pid, SIGSTOP) == 0) {
printf("myshell: processo %d parou a execução\n", pid);
} else {
printf("myshell: processo %d não pôde ser parado\n", pid);
}
} else {
printf("myshell: argumento esperado\n");
}
return -1;
}
int shell_continue(char *command[]) {
if (command[0] != NULL) {
int pid = atoi(*(command));
if (kill(pid, SIGCONT) == 0) {
printf("myshell: processo %d voltou a execução\n", pid);
} else {
printf("myshell: processo %d não pôde ser reativado\n", pid);
}
} else {
printf("myshell: argumento esperado\n");
}
return -1;
}
void ret_msg(pid_t pid, int ret_code) {
if (ret_code == 0) {
printf("myshell: processo %d finalizou normalmente com status 0\n", pid);
} else {
printf("myshell: processo %d finalizou com status desconhecido: %d \n", pid, ret_code);
}
}