1. cmdfile.txt
sleep 5
ls -latr
sleep 3
pwd
sleep 1
wc /etc/passwd
CommandNode.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CommandNode.h"
/**
*CommandNode.c
*The function bodies for a linked list of commands
**/
/**
Example of linked list initialization in code:
2. //First command node (head of list)
headCommand =
(CommandNode*)malloc(sizeof(CommandNode));
CreateCommandNode(headCommand, command, index,
NULL);
index = 1;
.....
//Later command nodes
while ((linesize = getline(&line, &len, fp)) >= 0) {
...
index++;
nextCommand1 =
(CommandNode*)malloc(sizeof(CommandNode));
CreateCommandNode(nextCommand1, command, index,
NULL);
InsertCommandAfter(headCommand, nextCommand1);
}
**/
//create a new command node. usually nextCmd can be NULL
and function InsertCommandAfter can be called to insert after
head node.
void CreateCommandNode(CommandNode* thisNode, char
cmd[20][20], int ind, CommandNode* nextCmd) {
3. //this is useful if you store a string (char *): strcpy(thisNode-
>command, cmd);
for (int i = 0; i < 20; i++)
for (int j = 0; j < 20; j++)
thisNode->command[i][j] = cmd[i][j];
thisNode->index = ind;
thisNode->nextCommandPtr = nextCmd;
return;
}
//insert node newNode after thisNode
void InsertCommandAfter(CommandNode* thisNode,
CommandNode* newNode) {
CommandNode* tmpNext = NULL;
tmpNext = thisNode->nextCommandPtr;
thisNode->nextCommandPtr = newNode;
newNode->nextCommandPtr = tmpNext;
return;
}
4. //get next command node in linked list
CommandNode* GetNextCommand(CommandNode* thisNode)
{
return thisNode->nextCommandPtr;
}
//find a command based on the pid
CommandNode* FindCommand(CommandNode* cmd, int pid) {
CommandNode* tmpNext = cmd;
while (tmpNext != NULL) {
if (tmpNext->PID == pid) { return tmpNext; }
tmpNext = tmpNext->nextCommandPtr;
}
return NULL;
}
CommandNode.h
/**
*CommandNode.h
*The struct for a Command Node and function prototypes for a
5. linked list of commands
**/
typedef struct command_struct {
char command[20][20];
int index;
int PID;
int starttime;
struct command_struct* nextCommandPtr;
} CommandNode;
void CreateCommandNode(CommandNode* thisNode, char
cmd[20][20], int ind, CommandNode* nextCmd);
void InsertCommandAfter(CommandNode* thisNode,
CommandNode* newNode);
CommandNode* GetNextCommand(CommandNode* thisNode);
CommandNode* FindCommand(CommandNode* cmd, int pid);
7. printf("Retrieved line of length %zu:n", read);
printf("%s", line);
for (int i=0; i<20; i++)
for (int j=0; j<20; j++)
newString[i][j]=0;
j=0; ctr=0;
for(i=0;i<=(strlen(line));i++)
{
// if space or NULL found, assign NULL into
newString[ctr]
if(line[i]==' '||line[i]=='0')
{
newString[ctr][j]='0';
ctr++; //for next word
j=0; //for next word, init index to 0
}
else
{
newString[ctr][j]=line[i];
j++;
}
}
printf("n Strings or words after split by space are :n");
for(i=0;i < ctr;i++)
printf(" %sn",newString[i]);
}
fclose(fp);
if (line)
free(line);
9. exit(127);
}
/* parent */
if ((pid = waitpid(pid, &status, 0)) < 0)
err_sys("waitpid error");
printf("DONE ");
exit(0);
}
HWdetails&helperFile/skeleton_solution.c
//---------------------------
//fork the commands and record the start times
CommandNode *headNode; /** This is the beginning of your
linked list of CommandNodes **/
....
CommandNode *tmpNode;
tmpNode = headNode;
while (tmpNode != NULL) {
10. //save the startime!
// tmpNode.starttime = starttime
pid = fork();
if (pid < 0) {
fprintf(stderr, "error forking");
exit(2);
} else if (pid == 0) { /*child */
//See shell1_execvp.c for execvp usage
execvp(....tmpNode.command); /*executes the command in
the specific node */
} else if (pid > 0) { /* parent goes to the next node */
11. tmpNode.pid = pid;
int fdout = open("%d.out", tmpNode.index);
int fderr = open("%d.err", tmpNode.index);
fprintf(fdout, "Starting command INDEX %d: child PID
%d of parent PPID %d.n", tmpNode.index, pid, getpid() );
tmpNode = tmpNode->nextCommandPtr;
}
} /*end of while loop */
12. //---------------------------
//Final while loop: waits until anything has completed,
//this will exit (wait returns -1)
//when there is no more child process. Then your parent process
exits.
while((pid = wait(&status)) >= 0) {
if(pid > 0) {
//finishtime = get the finish time
//search your linked list for the node that corresponds to
pid
//The function FindNode was provided
//node=FindNode(pid)
//signal handling
int fdout = open("%d.out", node.index);
int fderr = open("%d.err", node.index);
13. fprintf(stderr, "Process with PID %d terminated.n", pid);
if (WIFEXITED(status)) {
fprintf(fderr, "Child %d terminated normally with exit
code: %dn",
pid, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
fprintf(fderr, "Child %d terminated abnormally with
signal number: %dn",
pid, WTERMSIG(status)); }
//
//to compute the elapsed time you subtract
//elapsedtime = finishtime - node.start_time
//decide if you will restart
//if (elapsedtime > 2) {
//record the new starttime
// node.starttime = new starttime
// pid = fork();
// if (pid < 0) //error
14. // else if (pid == 0) { //child
//See shell1_execvp.c for execvp usage
// execvp(node.cmd);
// } else if (pid > 0) {
// node.pid = pid;
// }
}
}
time_demo.c
/* Program to demonstrate time taken by function fun() */
#include <stdio.h>
#include <time.h>
// A function that terminates when enter key is pressed
void fun()
{
printf("fun() starts n");
printf("Press enter to stop fun n");
while(1)
{
if (getchar())
break;
}
printf("fun() ends n");
}
15. // The main program calls fun() and measures time taken by
fun()
int main()
{
// Calculate the time taken by fun()
struct timespec start, finish;
double elapsed;
clock_t t;
t = clock();
clock_gettime(CLOCK_MONOTONIC, &start);
printf("start %ldn", start.tv_sec);
fun();
clock_gettime(CLOCK_MONOTONIC, &finish);
printf("finish %ldn", finish.tv_sec);
//printf("CLOCKSPERSEC %ldn", CLOCKS_PER_SEC);
//double time_taken =
((double)t)*1000.0/CLOCKS_PER_SEC; // in seconds
elapsed = (finish.tv_sec - start.tv_sec);
//Alternative with more precision:
//elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
printf("fun() took %f seconds to execute n", elapsed);
return 0;
}