-
Notifications
You must be signed in to change notification settings - Fork 0
/
shell.h
178 lines (148 loc) · 3.74 KB
/
shell.h
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
/* shell.h - Mini POSIX Shell
*
* Author: Matus Marhefka
* Date: 2015-04-23
*
* Global variables declarations/definitions, jobs and cd commands
* implementation.
*
*/
#ifndef JOBS_H
#define JOBS_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#define MAXLEN 513
#define MAXARG 256
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(1); } while (0)
struct job_item {
int pid;
char name[MAXARG];
struct job_item *next;
};
struct job_list {
struct job_item *first;
pthread_mutex_t jmtx;
};
/* count of arguments on command line */
int argsc;
/* array of argument strings ending with NULL element (for execvp) */
char **args;
/* variables exec_args, mtx and cond are forming our monitor for sync.
* between input and execution threads */
volatile int exec_args;
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
/* used for storing filenames for IO redirection */
char redir_t[MAXARG];
char redir_f[MAXARG];
/* indicates exit if set, protected by mtx_exit mutex */
volatile int exit_flag;
pthread_mutex_t mtx_exit = PTHREAD_MUTEX_INITIALIZER;
/* stores jobs running in background */
struct job_list jobs;
/* background flag: if set process is launched in background */
volatile int run_bg;
/* Changes the current working directory. */
int change_cwd(void)
{
int argc = argsc - 1; /* don't count the trailing NULL in args */
if (argc != 2) {
fprintf(stderr, "cd: one argument required\n");
return 1;
}
if (chdir(args[1]) == -1) {
if (errno == ENOENT || errno == ENOTDIR) {
fprintf(stderr, "cd: %s: No such directory\n", args[1]);
return 1;
}
return -1;
}
return 0;
}
/* Initializes job_list structure and mutexe variable. Returns 0 on success,
* error code (of pthread_mutex_init) on error. */
int jobs_init(struct job_list *list)
{
int rc;
rc = pthread_mutex_init(&(list->jmtx), NULL);
list->first = NULL;
return rc;
}
/* Frees the memory occupied by the job_list structure. */
void jobs_free(struct job_list *list)
{
struct job_item *it;
pthread_mutex_lock(&(list->jmtx));
if (list->first != NULL) {
it = list->first;
while (it != NULL) {
list->first = list->first->next;
free(it);
it = list->first;
}
list->first = NULL;
}
pthread_mutex_unlock(&(list->jmtx));
pthread_mutex_destroy(&(list->jmtx));
}
/* Inserts job with name and pid into the job_list. */
int jobs_insert(struct job_list *list, char *name, int pid)
{
struct job_item *it;
pthread_mutex_lock(&(list->jmtx));
it = malloc(sizeof(struct job_item));
if (it == NULL) {
fprintf(stderr, "Could not allocate memory for job\n");
pthread_mutex_unlock(&(list->jmtx));
return -1;
}
it->pid = pid;
strcpy(it->name, name);
it->next = list->first;
list->first = it;
pthread_mutex_unlock(&(list->jmtx));
return 0;
}
/* Finds and removes job from the job_list. Returns 1 if job is found
* and removed, 0 otherwise. */
int jobs_find_remove(struct job_list *list, int pid)
{
struct job_item *it, *prev;
pthread_mutex_lock(&(list->jmtx));
if (list->first != NULL) {
it = prev = list->first;
while (it != NULL) {
if (it->pid == pid) {
if (it == list->first)
list->first = it->next;
/* remove job_item from list */
prev->next = it->next;
free(it);
pthread_mutex_unlock(&(list->jmtx));
return 1;
}
prev = it;
it = it->next;
}
}
pthread_mutex_unlock(&(list->jmtx));
return 0;
}
/* Prints all background jobs on the stdout. */
void jobs_print(struct job_list *list)
{
struct job_item *it;
pthread_mutex_lock(&(list->jmtx));
if (list->first != NULL) {
it = list->first;
while (it != NULL) {
printf("[%d] %s\n", it->pid, it->name);
it = it->next;
}
}
pthread_mutex_unlock(&(list->jmtx));
}
#endif /* SHELL_H */