Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I have a program with a pipe and fork. it is not fully running the program can i

ID: 1813110 • Letter: I

Question

I have a program with a pipe and fork. it is not fully running the program can i please have assitance. the program is listed below:


#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <string.h>


#define MAX_STR 256

#define MAX_LINE 64

#define MAX_PROCS 256


#define BLOCK 0

#define READY 1

#define RUNNING 2


#define DEBUG true

#define true 1

#define false 0



#define MAX_PRIORITY 4

#define CLASS_0 0

#define CLASS_1 1

#define CLASS_2 2

#define CLASS_3 3



#define REPORT


  

  

struct Cpu

{

int pc;

int pid;

int value;

int t_slice;

int t_remain;

};


struct Proc

{

int pid;

int ppid;

int pc;

int value;

int priority;

int state;

int t_start;

int t_used;

char fname[MAX_STR];

char prog[MAX_LINE][MAX_STR];

};


typedef struct Que {

int pid;

struct Proc proc;

struct Que *next;

} QUE;


struct TA_TIME{

int times[MAX_PROCS];

int count;

};

  

char buffer[BUFSIZ];

int quantum[4];



QUE *insert_head(QUE **p, int pid)

{

QUE *n = (QUE *) malloc(sizeof(QUE));

if (n == NULL) return NULL;


n->next = *p;

*p = n;


n->pid = pid;


return n;

}



QUE *enqueue(QUE **p, int pid)

{

QUE *tail = *p;

  

if(*p == NULL)

return insert_head(p, pid);


while(tail->next != NULL)

tail = tail->next;


QUE *n = (QUE *) malloc(sizeof(QUE));

if (n == NULL)

return NULL;


n->next = tail->next;

tail->next = n;

n->pid = pid;


return n;

}



int dequeue(QUE **p){

int pid = -1;

if (*p != NULL){

printf("DEQ(pid =%d) ", (*p)->proc.pid);

pid = (*p)->pid;

QUE *n = *p;

*p = n->next;

free(n);

return pid;

}else{

printf("cannot remove, because queue is empty ");

return pid;

}

}



struct Proc create_proc(int pid, int ppid, int priority, int pc, int value,

int t_start, int t_used, char *fname){

static struct Proc proc;

proc.pid = pid;

proc.ppid = ppid;

proc.priority = priority;

proc.pc = pc;

proc.value = value;

proc.t_start = t_start;

proc.t_used = t_used;

strcpy(proc.fname, fname);

readProgram(proc.fname, proc.prog);

return proc;

}



struct Proc dup_proc(struct Proc *pp, int new_pid,

int dup_times, int current_time){

static struct Proc cp;

cp.pid = new_pid;

cp.ppid = pp->pid;

cp.priority = pp->priority;

cp.pc = pp->pc;

cp.value = pp->value;

cp.t_start = current_time;

cp.t_used = 0;

strcpy(cp.fname, pp->fname);

readProgram(cp.fname, cp.prog);

return cp;

}



void show(QUE *n, struct Proc pcbTable[]){

struct Proc proc;

  

if (n == NULL){

printf("queue is empty ");

return ;

}

while (n != NULL){

proc = pcbTable[n->pid];

printf("pc, pid, ppid, priority, value, start time, CPU time used so far ");

printf("%2d, %3d, %3d, %8d, %5d, %10d, %3d ",

proc.pc, proc.pid, proc.ppid, proc.priority,

proc.value, proc.t_start, proc.t_used);

n = n->next;

}

printf(" ");

return;

}



void show_by_priority(QUE *n, struct Proc pcbTable[], int priority){

struct Proc proc;

int count = 0;

  

while (n != NULL){

if(pcbTable[n->pid].priority == priority){

proc = pcbTable[n->pid];

printf("pc, pid, ppid, priority, value, start time, CPU time used so far ");

printf("%2d, %3d, %3d, %8d, %5d, %10d, %3d ",

proc.pc, proc.pid, proc.ppid, proc.priority,

proc.value, proc.t_start, proc.t_used);

count++;

}

n = n->next;

}

  

if (count == 0){

printf("queue is empty ");

return ;

}

printf(" ");

return;

}



void cpu2proc(struct Cpu *cpu, struct Proc *proc){

proc->pc = cpu->pc;

proc->pid = cpu->pid;

proc->value = cpu->value;

proc->t_used = cpu->t_remain;

return;

}



void proc2cpu(struct Proc *proc, struct Cpu *cpu){

cpu->pc = proc->pc;

cpu->pid = proc->pid;

cpu->value = proc->value;

cpu->t_slice = quantum[proc->priority];

if(proc->t_used > 0){

printf("Blocked process was assigned to CPU. ");

cpu->t_remain = proc->t_used;

}else{

printf("New process was assigned to CPU. ");

cpu->t_remain = cpu->t_slice;

}

return;

}



void set_next_priority(struct Proc *p){

if(p->priority == CLASS_3){

p->priority = CLASS_3;

}else{

p->priority += 1;

}

return;

}



int calc_ta_time(int current_time, struct Proc *p){

return current_time - p->t_start;

}



double calc_ta_time_avg(struct TA_TIME ta){

int i;

int total = 0;

for(i=0; i<ta.count; i++){

total += ta.times[i];

}

if(ta.count == 0){

return 0;

}else{

return total/ta.count;

}

}



int readProgram(char *fname, char prog[][MAX_STR]){

FILE *fp;

char buff[MAX_STR], *pp;

int x, y, i, j;

  

for(x=0;x<MAX_LINE;x++){

for(y=0;y<MAX_STR;y++){

prog[x][y] = '';

}

}


fp = fopen(fname, "r");

if(fp == NULL){

printf("Can't open the file: '%s' ", fname);

exit(1);

}


i=0;

printf("Read '%s' program: ", fname);

while(1){

pp = fgets(buff, MAX_STR, fp);

  

// delete ' ' character if exists.

j=0;

while(buff[j] != ''){

if(buff[j] == ' ') buff[j] = '';

j++;

}

  

strcpy(prog[i], buff);

if(pp == NULL){

break;

}

printf("%3d: '%s' ", i, buff);

i++;

}


fclose(fp);

return(0);

}



char **split(int *n, char *string)

{

char **array=NULL;

char *p=string;

char *s;


for(*n=0; (s = strtok(p, " ")) != NULL; (*n)++) {

array = (char**)realloc(array, sizeof(char*) * (*n+1));

array[*n] = s;

p = NULL;

}


return array;

}



void copy(FILE *fin, FILE *fout)

{

while (fgets(buffer, BUFSIZ, fin) != NULL) {

fputs(buffer, fout);

fflush(fout);

}

}



void commanderProcess(int wfd)

{

FILE *fp = fdopen(wfd, "w");

int status;

char cmd[MAX_STR];

  

if (fp == NULL) {

perror("parent: fdopen");

exit(3);

}

copy(stdin, fp);

fclose(fp);


if(wait(&status) == -1) {

perror("wait");

exit(4);

}

}



void reporterProcess(int wfd, struct Proc pcbTable[], int time, struct TA_TIME ta,

QUE *s_run, QUE *s_ready, QUE *s_block){

int i;

printf("********************************************* ");

printf("The current system state is as follows: ");

printf("********************************************* ");

printf("CURRENT TIME: %d ", time);

printf("AVERAGE TURN AROUND TIME: %f. ", calc_ta_time_avg(ta));

printf(" ");

printf("RUNNING PROCESS: ");

show(s_run, pcbTable);

  

printf(" ");

printf("BLOCKED PROCESSES: ");

printf("Queue of blocked processes: ");

show(s_block, pcbTable);

  

printf(" ");

printf("PROCESSES READY TO EXECUTE: ");


for(i=0; i<MAX_PRIORITY; i++){

printf("Queue of processes with priority %d: ", i);

show_by_priority(s_ready, pcbTable, i);

}

  

close(wfd);

exit(3);

}



void processManagerProcess(int rfd, char *init_program)

{

FILE *fp = fdopen(rfd, "r");

int fd[2];

  

char **cmd;

int c, n;

int pid_count;

int arg;

int i,x,y;

int err_flg = false;

  

int wait4unblocking = false;

  


struct TA_TIME ta;

  

struct Proc temp_Proc;

int temp_value;

int temp_pid;

char temp_fname[MAX_STR];

int temp_index;

  

  

int current_time;

struct Cpu cpu;

struct Proc pcbTable[MAX_PROCS];


QUE *ready_states;

QUE *blocked_states;

QUE *running_states;

  

  

  

quantum[CLASS_0] = 1;

quantum[CLASS_1] = 2;

quantum[CLASS_2] = 4;

quantum[CLASS_3] = 8;

  

pid_count = 0;

ta.count = 0;

ta.times[0] = 0;

current_time = 0;

cpu.pc = 0;

cpu.pid = 0;

cpu.value = 0;

cpu.t_slice = quantum[CLASS_0];

cpu.t_remain = cpu.t_slice;

  

pcbTable[cpu.pid] = create_proc(pid_count++, -1, CLASS_0, cpu.pc, cpu.value,

current_time, quantum[CLASS_0]-current_time,

init_program);

  

ready_states = NULL;

blocked_states = NULL;

running_states = NULL;

enqueue(&running_states, cpu.pid);

  

  

while (fgets(buffer, BUFSIZ, fp) != NULL) {

  

printf("Command = %s",buffer);

if(!strcmp(buffer, "Q ") || !strcmp(buffer, "q ")){

if(wait4unblocking == true){

printf("Only blocked processes remain, so waiting for unblocking. ");

printf(" ");

printf("> ");

fflush(stdout);

continue;

}

  

printf("End of one unit of time. ");

printf("Instruction = '%s' ", pcbTable[cpu.pid].prog[cpu.pc]);

if(!strcmp(pcbTable[cpu.pid].prog[cpu.pc], "")){

printf("Instructions unexpectedly finished, so exit forcefully with printing. ");

sprintf(cmd[0], "E");

err_flg = true;

}else{

cmd = split(&n, pcbTable[cpu.pid].prog[cpu.pc]);

}

  

current_time++;

cpu.pc++;

cpu.t_remain--;

  

if(!strcmp(cmd[0], "S")){

printf("Set the value of the integer variable to %d. ", atoi(cmd[1]));

temp_value = cpu.value;

cpu.value = atoi(cmd[1]);

printf("CPU value: %d -> %d ", temp_value, cpu.value);


}else if(!strcmp(cmd[0], "A")){

printf("Add %d to the value of the integer variable. ", atoi(cmd[1]));

temp_value = cpu.value;

cpu.value += atoi(cmd[1]);

printf("CPU value: %d -> %d ", temp_value, cpu.value);


}else if(!strcmp(cmd[0], "D")){

printf("Subtract %d from the value of the integer variable. ", atoi(cmd[1]));

temp_value = cpu.value;

cpu.value -= atoi(cmd[1]);

printf("CPU value: %d -> %d ", temp_value, cpu.value);


}else if(!strcmp(cmd[0], "B")){

printf("Block this simulated process. ");

dequeue(&running_states);

cpu2proc(&cpu, &pcbTable[cpu.pid]);

printf("Running Process(pid=%d) was blocked. ", cpu.pid);

enqueue(&blocked_states, cpu.pid);


}else if(!strcmp(cmd[0], "E")){

printf("Terminate this simulated process. ");

dequeue(&running_states);

printf("pid=%d is Terminated. ", cpu.pid);

ta.times[ta.count++] = calc_ta_time(current_time, &pcbTable[cpu.pid]);


}else if(!strcmp(cmd[0], "F")){

printf("Create %d new simulated process(es). ", atoi(cmd[1]));

arg = atoi(cmd[1]);


cpu2proc(&cpu, &pcbTable[cpu.pid]);

pcbTable[pid_count++] = dup_proc(&pcbTable[cpu.pid], pid_count,

arg, current_time);

enqueue(&ready_states, pid_count-1);

printf("Created a process(pid=%d). ", pid_count-1);


cpu.pc += arg;


}

else if(!strcmp(cmd[0],"R")){

printf("Replace the program of the simulated process with the program in the file '%s'. ", cmd[1]);

strcpy(temp_fname, cmd[1]);

cpu.pc = 0;

cpu.value = 0;


readProgram(temp_fname, pcbTable[cpu.pid].prog);

printf("Replaced the current program with the program in '%s' file. ", temp_fname);


}else{

printf("Unknown Instruction. ");

printf("Exited by error. ");

return;

}


  

if(ready_states == NULL){

if(running_states != NULL){

printf("No ready processes, so continue to run the current process. ");

}else if(blocked_states != NULL){

printf("Only blocked processes remain, so waiting for unblocking. ");

wait4unblocking = true;

}else{

if(err_flg == false) printf("Program was successfully executed. ");

printf(" ");

printf("=== RESULT === ");

if (pipe(fd)) {

perror("pipe");

} else if ((temp_pid = fork()) == -1) {

perror("fork");

} else if (temp_pid == 0) {

close(fd[0]);

if(DEBUG) cpu2proc(&cpu, &pcbTable[cpu.pid]);

reporterProcess(fd[1], pcbTable, current_time, ta,

running_states, ready_states, blocked_states);

} else {

close(fd[1]);

while(i=(read(fd[0],&c,1)) > 0); // Pipe Synchronization

}

printf("=== END OF SYSTEM === ");

return;

}



}else if(running_states == NULL){ // When process was blocked or terminated.

printf("There are no process running, so assign the first process in the queue to CPU. ");

temp_pid = dequeue(&ready_states);

proc2cpu(&pcbTable[temp_pid], &cpu);

enqueue(&running_states, temp_pid);

printf("Assigned: cpu <--- pcbTable[%d] ", temp_pid);


}else if(cpu.t_remain <= 0) { // When quantum expired

printf("Quantum was expired, so assign the first process in the queue to CPU. ");

set_next_priority(&pcbTable[cpu.pid]);

printf("Pid(%d)'s priority class was raised to %d. ",

cpu.pid, pcbTable[cpu.pid].priority);

cpu2proc(&cpu, &pcbTable[cpu.pid]);

enqueue(&ready_states, cpu.pid);

temp_pid = dequeue(&running_states);


proc2cpu(&pcbTable[dequeue(&ready_states)], &cpu);

enqueue(&running_states, cpu.pid);

printf("Swithed: cpu(%d) <--> pid(%d) ", temp_pid, cpu.pid);


}else if(cpu.t_remain > 0){

printf("cpu time is still remained, so continue to run the current process. ");


}else{

printf("Unknown condition to schedule. ");

}

  

free(cmd);

  

}else if(!strcmp(buffer, "U ") || !strcmp(buffer, "u ")){

printf("Unblock the first simulated process in blocked queue. ");

temp_index = dequeue(&blocked_states);

if(temp_index == -1){

printf("There are no states in blocked queue. ");

}else{

printf("pid=%d moves from blocked queue to ready queue. ", temp_index);

enqueue(&ready_states, temp_index);

wait4unblocking = false;

}

  

}else if(!strcmp(buffer, "P ") || !strcmp(buffer, "p ")){

printf("Print the current state of the system. ");

if (pipe(fd)) {

perror("pipe");

} else if ((temp_pid = fork()) == -1) {

perror("fork");

} else if (temp_pid == 0) {

close(fd[0]);

if(DEBUG) cpu2proc(&cpu, &pcbTable[cpu.pid]);

reporterProcess(fd[1], pcbTable, current_time, ta,

running_states, ready_states, blocked_states);

} else {

close(fd[1]);

while(i=(read(fd[0],&c,1)) > 0);

}


}else if(!strcmp(buffer, "help ")){

printf("

The following commands are accepted:

Q:End of one unit of time

- CPU consumes 1 instruction from programs, and execute it.

U: Unblock the first simulated process in blocked queue

- If there is a blocked process, move its state from Blocked toReady.

P: Print the current state of the system.

- The state include PC, PID, PPID, Priority, Value, Time, etc.

T: Terminate the system after printing the current state.

- The printing is same as 'P' command. ");

  

}else if(!strcmp(buffer, "T ") || !strcmp(buffer, "t ")){

printf("Print the average turnaround time, and terminate the system. ");

  

printf("Average turn around time is %f. ", calc_ta_time_avg(ta));

if (pipe(fd)) {

perror("pipe");

} else if ((temp_pid = fork()) == -1) {

perror("fork");

} else if (temp_pid == 0) {

close(fd[0]);

if(DEBUG) cpu2proc(&cpu, &pcbTable[cpu.pid]);

reporterProcess(fd[1], pcbTable, current_time, ta,

running_states, ready_states, blocked_states);

} else {

close(fd[1]);

while(i=(read(fd[0],&c,1)) > 0);

}

printf(" ");

printf("Terminate the system. ");

return;

  

}else{

printf("Unknown command. ");

}

fputs(buffer, stdout);

printf(" ");

printf("> ");

fflush(stdout);

}

fclose(fp);

}

int argc;

int main(char argc, char *argv[]){

int rv = 0, fd[2], pid;

char fname[MAX_STR];


if(argc != 2){

printf("program failed");

return ;

}

  

printf("> ");

strcpy(fname, argv[1]);

  


if (pipe(fd)) {

perror("pipe");

rv = 1;

} else if ((pid = fork()) == -1) {

perror("fork");

rv = 2;

} else if (pid > 0) {

close(fd[0]);

commanderProcess(fd[1]);

} else {

close(fd[1]);

processManagerProcess(fd[0], fname);

}

  



return rv;

}

Explanation / Answer