Write a C program called runsim.c. The program takes exactly one command-line ar
ID: 3714347 • Letter: W
Question
Write a C program called runsim.c. The program takes exactly one command-line argument that specifies the maximum number of simultaneous execution. The runsim program runs up to pr_limit processes at a time. The executable must be called runsim. Follow the outline below for implementing runsim.
Check the appropriate command-line argument and output a usage message if the command line is incorrect.
• Initialize pr_limit from the command line. The pr_limit variable specifies the maximum number of children allowed to execute at a time.
• The pr_count variable holds the number of active children. Initialize it to 0.
• Execute the following main loop until the end-of-file is reached on standard input: o If pr_count is pr_limit, wait for a child to finish and decrement pr_count.
o Read a line from standard input (fgets) of up to MAX_BUF characters and execute a program corresponding to that command line by forking a child and execute the file. o Increment pr_count to track the number of active children.
o Check to see if any of the children have finished (**). Decrement pr_count for each child that has completed.
• After encountering end-of-file on standard input, wait for all of the remaining children to finish and then exit.
• For each terminated child, prints out its exit code value.
A parent process can check if one of its children terminated without blocking itself by using waitpid() system call as follow waitpid(-1, &status, WNOHANG). The system call returns 0 if there are still children to be waited for, or the pid of the terminated child.
In this exercise, use runsim to run multiple copies of the testsim program. The testsim program is given below. It takes two command-line arguments: the sleep time and the repeat factor. The testsim program loops repeat factor times. In the loop, testsim sleeps for the specified sleep time and then output a message with its process ID to standard output.
/* testsim.c */
#include <stdio.h>
int main(int argc, char *argv[]) {
int n;
int sec;
if (argc <= 2) {
fprintf(stderr, “Usage: %s sleep_time repeat_factor ”, argv[0]);
exit(1); }
sscanf(argv[1], “%d”, &sec);
sscanf(argv[2], “%d”, &n);
while (n-- > 0) sleep(sec);
printf(“Process ID = %d ”, getpid());
return sec; }
To run simulation: Create a test file called testing.data that contains commands to run. For example, the file might contain the following lines.
testsim 5 10
testsim 8 10
testsim 4 10
testsim 13 6
testsim 1 12
Run the program by entering a command such as the following.
runsim 2 < testing.data
Below program creates a fan of n processes where n is passed as a command-line argument. You can expand on this to create the runsim program.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[]) {
pid_t childpid = 0;
int i, n;
if (argc != 2){
/* check for valid number of command-line arguments */
fprintf(stderr, "Usage: %s processes ", argv[0]); return 1; }
n = atoi(argv[1]);
for (i = 1; i < n; i++)
if ((childpid = fork()) <= 0)
break;
fprintf(stderr, "i:%d process ID:%ld parent ID:%ld child ID:%ld ",
i, getpid(), getppid(), childpid);
return 0;
}
Explanation / Answer
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
const char* USAGE = "Usage: mycat [-n] [file ...] [@ file] [file ...] ";
const mode_t OPENMODE = S_IRUSR|S_IWUSR|S_IXUSR|
S_IRGRP|S_IWGRP|S_IXGRP|
S_IROTH|S_IWOTH|S_IXOTH;
const int OPENFLAGS = O_CREAT|O_TRUNC|O_WRONLY;
void writeLineNumber(int output, int number) {
char *stringValue;
sprintf(stringValue, "%d: ", number);
write(output, stringValue, strlen(stringValue));
}
void readfile(char* filename, int output, char numLines) {
int fd = open(filename, O_RDONLY);
int lineNum = 1;
if (fd < 0) {
write(output, "Failed to read file: ", 21);
write(output, filename, strlen(filename));
write(output, " ", 1);
return;
}
// Write the first line number, if it is desired
if (numLines) { writeLineNumber(output, lineNum); }
char *character;
while(read(fd, character, 1)) {
write(output, character, 1);
if (*character == ' ' && numLines) {
lineNum++;
writeLineNumber(output, lineNum);
}
}
// Newline at the end
write(output, " ", 1);
}
void readline(char *line) {
char *input;
int amt = read(0, input, 255);
int index;
for (index = 0; index < amt; index++) {
line[index] = input[index];
}
line[index] = 0;
}
void readInput(int output, char numLines) {
char *line;
char **input;
int inputIndex = 0;
while (1) {
readline(line);
if (!strcmp(line, ":q ")) { break; }
input[inputIndex] = line;
inputIndex++;
}
while (*input) {
write(output, *input, strlen(*input));
input++;
}
}
int main(int argc, char** argv) {
char numberLines = 0;
int output = 0; // By default, write to standard out
// Must have at least two arguments
if (argc < 2) {
write(0, USAGE, strlen(USAGE));
}
// Pre parse arguments
int argIndex;
for (argIndex = 1; argIndex < argc; argIndex++) {
if (!strcmp(argv[argIndex], "-n")) {
numberLines = 1;
}
else if(*argv[argIndex] == '@') {
// Jump to next character (from @ to ...)
argv[argIndex]++;
// If form is @filename
if (*argv[argIndex]) {
output = open(argv[argIndex], OPENFLAGS, OPENMODE);
}
// Else, from is @ filename (separate argument)
else {
output = open(argv[argIndex + 1], OPENFLAGS, OPENMODE);
}
// If output file cannot be opened
if (output < 0) {
output = 0;
write(output, "Couldn't open file to write to ", 31);
}
}
}
// Drop first argument
argv++;
// Now loop through and actually read
while (*argv) {
// If the argument is not -n
if (strcmp(*argv, "-n")) {
// If its an @ (specify write file)
// We skip it, and optionally jump an arugment
if (**argv == '@') {
// If the write file is not attached, skip the next argument
if (!*argv[1]) { argv++; }
}
// If just a dash, read a line of input
else if (!strcmp(*argv, "-")) {
readInput(output, numberLines);
}
// Else, just read the specified file
else {
readfile(*argv, output, numberLines);
}
}
// Go to next argument
argv++;
}
return 0;
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.