-
Notifications
You must be signed in to change notification settings - Fork 3
/
backgroundProcess.c
182 lines (135 loc) · 5.76 KB
/
backgroundProcess.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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include "main.h"
// void bgChildHandler(ll totalArgsInEachCommand, char *listofArgs[]) {
// // Make the child process as the leader of the new group of processes.
// // Setting the process ID of child = Process ID of group
// setpgid(0, 0);
// // Removing the last '&' as we need the name
// listOfArgs[totalArgsInEachCommand - 1] = NULL;
// // Since the child has become the leader, so now give the control back to the
// // default signals. SIGINT - Ctrl + C(Interrupt handler)
// signal(SIGINT, SIG_DFL);
// // Causes the system to set the default signal handler for the given signal
// // Ctrl + Z.
// signal(SIGTSTP, SIG_DFL);
// // Returns of calling process(i.e. the group leader)
// pid_t pidVal = getpid();
// // Overlay's a process that has been created by a call to the fork function.
// // Execute the files.
// ll check_execvp = execvp(listOfArgs[0], listOfArgs);
// // Check for the errors.
// if(check_execvp < 0){
// printf("Invalid command!\n");
// exit(1);
// }
// exit(0);
// }
// void bgParentHandler(pid_t pid) {
// // Now store the process details in the processes Arrays
// // Store pid
// processesIndex[totalNoOfProcesses] = pid;
// // Get length of the command
// ll lengthOfCommand = strlen(listOfArgs[0]);
// // create a space in memory
// processesNames[totalNoOfProcesses] = (char *) malloc(lengthOfCommand * sizeof(char));
// // Copy command into this array
// strcpy(processesNames[totalNoOfProcesses], listOfArgs[0]);
// // Update the status to 1
// processesStatus[totalNoOfProcesses] = 1;
// // Inc no. of processes by 1
// totalNoOfProcesses++;
// printf("[%lld]\n", processesIndex[totalNoOfProcesses - 1]);
// return;
// }
// void backgroundProcess(long long int totalArgsInEachCommand, char *listofArgs[]) {
// // Forking child process
// pid_t pid = fork();
// // Checking for error
// if (pid < 0) {
// printf("Unable to fork");
// return;
// }
// // Sending the child process to background
// else if (pid == 0){
// bgChildHandler(totalArgsInEachCommand, &listOfArgs);
// }
// // Means PID > 0, i.e. the parent's process
// else {
// if (kill(pid, SIGCONT) < 0) {
// perror("Could not run background process");
// return;
// }
// bgParentHandler(pid);
// }
// }
// This is the function for running a background process, i.e a command ending with &
void backgroundProcess(long long totalArgsInEachCommand, char *listOfArgs[]) {
// Forking child process
ll forkReturnedValue = fork();
if(forkReturnedValue < 0) {
fprintf(stderr, "Unable to fork\n");
return;
}
// Sending the child process to background
if(forkReturnedValue == 0) {
// Make the child process as the leader of the new group of Jobs.
// Setting the process ID of group = Process ID of child
setpgrp();
// Removing the last '&' as we need the name
listOfArgs[totalArgsInEachCommand - 1] = NULL;
// Since the child has become the leader, so now give the control back to the
// default signals. SIGINT - Ctrl + C(Interrupt handler)
signal(SIGINT, SIG_DFL);
// Causes the system to set the default signal handler for the given signal
// Ctrl + Z.
signal(SIGTSTP, SIG_DFL);
// Returns of calling process (i.e. the group leader)
pid_t pid = getpid();
// Overlay's a process that has been created by a call to the fork function.
// Execute the execuateble files.
ll execcvpReturnedValue = execvp(listOfArgs[0], listOfArgs);
// Check for the errors.
if(execcvpReturnedValue < 0){
fprintf(stderr, "Invalid command!\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
// Handle the parent process
else {
ll len = strlen(listOfArgs[0]);
for (int i = 1; i < totalArgsInEachCommand - 1; i++) {
len += strlen(listOfArgs[i]);
}
// Now store the process details in the Jobs Arrays
// Store pid
myJobs[totalNoOfJobs].pid = forkReturnedValue;
myJobsTemp[totalNoOfJobs].pid = forkReturnedValue;
// create a space in memory
myJobs[totalNoOfJobs].jobsNames = malloc(len * sizeof(char));
myJobsTemp[totalNoOfJobs].jobsNames = malloc(len * sizeof(char));
// Check for errors
if(listOfArgs[0] == NULL){
fprintf(stderr, "Memory Error!\n");
}
strcpy(myJobs[totalNoOfJobs].jobsNames, listOfArgs[0]);
strcpy(myJobsTemp[totalNoOfJobs].jobsNames, listOfArgs[0]);
// Copy the commandName in the processesNames array
for (int i = 1; i < totalArgsInEachCommand-1; i++) {
strcat(myJobs[totalNoOfJobs].jobsNames, " ");
strcat(myJobsTemp[totalNoOfJobs].jobsNames, " ");
strcat(myJobs[totalNoOfJobs].jobsNames, listOfArgs[i]);
strcat(myJobsTemp[totalNoOfJobs].jobsNames, listOfArgs[i]);
}
// Set status of bg processes as 1
myJobs[totalNoOfJobs].jobsStatus = 1;
myJobsTemp[totalNoOfJobs].jobsStatus = 1;
// Store index
myJobs[totalNoOfJobs].jobsIndex = totalNoOfJobs;
myJobsTemp[totalNoOfJobs].jobsIndex = totalNoOfJobs;
// Increase the total no of processes
totalNoOfJobs++;
// Print the ID
fprintf(stderr,"[%lld] started\n", myJobs[totalNoOfJobs-1].pid);
return;
}
}