To be completed including bonus marks. 100% is required.
Microsoft Word - assignment5_[v2].docx ©2021 Doron Nussbaum COMP 2401 Page1 of 5 Assignment 5 COMP 2401 Date: November 22, 2021 Due: on December 9, 2021 before 23:55 Submission: Electronic submission on Brightspace. Objectives: a. Reading from binary files: opening and closing a file (fopen() and fclose(), reading from a file (fread()) b. Process spawning: differentiating between parent and child processes (fork()), examining the return code of the child process(), waiting for a child process (wait() and waitpid()) c. Program Morphing – changing from one program to another (excevp()) d. Inter process communication – using signals and return code e. Usage of signals – signals and function pointers. Submission (10 pts.) Submission must be in Brightspace by the due date. Submit a single tar file with all the c and h files. The tar file name is A5.tar The tar file should include all programs and code (code that you wrote and code that was provided as part of the assignment) Submit a Readme.txt file explaining o Purpose of software o Who the developer is and the development date o How the software is organized (partitioned into files) o Instruction on how to compile the program (give an example) o Any issues/limitations problem that the user must be aware of o Instructions explaining how to use the software Coding Instructions: 1. Comments in Code – as provided in the slides given in class 2. No usage of global variables except for Bonus Task IV. All data must be passed or received via function parameters except when specifically stated. Provided Resources The following files are provided in assignment5.tar 1. drAssessment.c – a program that examines the patient and determines whether a patient must be hospitalized and if so, then for how many days. This program simulates a doctor’s assessment of a patient. 2. patient.o ‐ an object file that contains the patient assessment function patientAssessment() and printPatient(). See file patient.h for a description of the function’s parameters 3. patient.h – a header file that contains the struct definition of the patient record, the prototype of available functions: copyright ©2021 Doron Nussbaum COMP 2401 Page2 of 5 patientAssessment() and printPatient() 4. patient.bin – a file containing 12 patient records in binary format 5. patient.bin.txt – a file containing 12 patient records in ascii format 6. createBinary.c – a program that creates a binary file of patients’ records. Assuming that the executable is a.out, thenthe usage is: a.out filename x, where filename is the binary file name and x is the number of patients to be created. For example, a.out newPatients.bin 17 will create a binary file (file name is newPatients.bin) with 17 patients. Grading: Assignment is graded out of 100. The grade may be reduced to 0 If the correct file names are not used. Part or all the assignment may be tested by another program. You will be graded with respect to what you have submitted. Namely, you earn points for working code and functionality. Grading will look at how the functions are coded, whether functions meet the required functionality, memory allocation and de‐ allocation, setting pointers to NULL as needed, etc. 1 Background You are tasked to write a program that assesses a set of patients and determines for each patient whether the patient needs to be hospitalized and if so for how many days. To complete the task, you are given a program (drAssessment.c), which accepts, through command line parameters, the information of a single patient (id, the priorityLevel, and medicalProblem) where id is the patient id, priorityLevel is the patient’s treatment priority, which was assigned buy the triage nurse, and the patient’s medical problem; and return: 0 if the patients should not be hospitalized >0 the number of days that the patient should be hospitalized for ‐1 if the range of priority level is not in the range of 0‐9 The given program assumes that the input, if provided to the program, is correct and therefore the program does not require to check whether the input is correct. The assessment takes time and therefore the function simulates the need for additional time. As a result, each assessment will take a few seconds (up to 35 seconds). This assignment is a progressive assignment. Namely, it is divided into several tasks each building on the previous one. For each task (1‐3) you will be asked to create a program (including a makefile). Thus, once you completed the code for one task you can use it (e.g., by duplicating it) and then expand it to complete the next task. 2 Task 0 Understanding the base code (0 points) In this task you will understand the prime testing program that was provided. 1. Review the program drAssessment.c. Make sure that you understand the program and how it works. Do the following: 1.1. Compile the program and create an executable called drAssessment. Note that you must compile the file drAssessment and link it with the file patient.o. Note, that at this stage you can use the patient id 99999999 to bypass the time that it requires to assess the patient. 1.2. Test the program as follows: 1.2.1. Test 1: drAssessment 99999999 2 “broken bone” 1.2.2. Test 1: drAssessment 99999999 8 “broken bone” 1.2.3. Test 1: drAssessment 13573 3 “broken bone” Since you will not see any output use the debugger to ensure that your code is working by putting breakpoints at each of the return() function calls. Alternatively, you can temporarily add print statements indicating whether the patient needs to be hospitalized and if so the number of days. This can assist you in testing Task I. 2. Compile the file and create an executable program called drAssessment. copyright ©2021 Doron Nussbaum COMP 2401 Page3 of 5 3 Task I Morphing (40 points) Task overview In this task you will write a program that will morph itself into the drAssessment program. Here you will use the drAssessment program from Task 0. In this task you will process a binary file. You can assume that if the file exists then it contains at least one patient’s record. The program that you write will read from a binary file the first patient record and then morph itself to the drAssessment program. The file name will be given as a command line parameter. To do 1. (10 pts.) Create a program singleAssessment that accepts the binary file name as a single command line parameter. Here you can use the tutorial tools that you developed. Name the code file singleAssessment.c, 1.1. (3 pts.) The program will check that a file name was provided as command line parameter. If a file name was not provided, then it will print how to use the program – Usage: singleAssessment fileName. See below for correct program return code. 1.2. (7 pts.) The program should check if the file exists. If the file does not exist then the program should produce an error message (e.g.,): file file.bin does not exist, where file.bin is the provided file name. See below for correct program return code. 2. (10 pts.) Create a function morph() which will take as input three parameters , the id, the priorityLevel and the medical issue (all strings) and morph itself to the drAssessment program using the excev or execvp system function call. 2.1. Prototype int morph(char *id, char *priorityLevel, char *medicalProblem); 2.2. Input: id (the patient’s id), priorityLevel (the patient’s priority level) and medicalProblem (the patient’s medical problem) 2.3. Return ‐ ‐1 if the morph failed 3. (10 pts.) If the binary file exists then the program should read the first patients record from the file, convert the required data to strings, using the function sprintf(), and then call the morph function that you coded. 4. (5 pts.) Program return codes: 4.1. 0 – if the patient should be hospitalized 4.2. >0 I the patient needs to be hospitalized (the value indicates the number of days) 4.3. ‐2 – if file name was not provided 4.4. ‐3 – if the file does not exist 5. (5 pts.) Create a makefile to compile the program. The make file name should be Makefile1. The executable program name should be singleMorph. 6. Test your program. Here you are provided with a. a binary file patient.bin which contains 12 patient records in a binary format. b. a utility to create a binary file (the utility is createBinary.c). 4 Task II Spawning a single child (35 points) Task overview In this task you will write a program that will spawn a child process. The child process will morph itself into the drAssessment program. The parent program will wait until the child program completes its task and output whether the patient needs to be hospitalized and if so for how many days by using the return code from the child process. To do 1. (5 pts.) Copy the program from Task I into a file with the name singleSpawn.c. Remove any print statements that you may have added to the drAssessment program (see Task 0). 2. (10 pts.) Expand the program to so that the program shall spawn a single child. 2.1. The parent should perform the subtasks of handling the file (checking existence, reading the record from the file etc.). It will then transfer the patient record to the child function. Note, that the program should conduct the same checks for the binary file as it did in Task I. 2.2. The child function will convert the require data to strings (as stated in subtask 3 of Task I and morph itself into the drAssessment program using the function from Task I. 3. (15 points) The parent program should wait until the child process has completed its execution and then, using the return code from the child process, print whether the patient needs to be hospitalized and if the patient needs hospitalized then for how many copyright ©2021 Doron Nussbaum COMP 2401 Page4 of 5 days. Note, that here the parent needs to check whether the child properly terminated its execution 3.1. Here you will have to use the wait() function. Output example: Patient Don Little id (34532) does not hospitalization Or Patient Don Little id (34532) requires 4 hospitalization days 4. (5 points) Create a makefile to compile the program. Makefile name should be Makefile2. The executable program name should be singleSpawn. 5 Task III Spawning multiple children (45 points) Task overview In this task you will write a program that will spawn multiple child processes. Each child process will morph itself into the drAssessment program. The parent program will wait until all the child processes have completed their work and then output all patients that need to be hospitalized and the number of days. Note, patients that should not be hospitalized should not be printed. You can assume that the binary file (if it exists) contains at least 10 patients. For simplicity the program will need to process only the first 10 patients. You can also obtain additional points by doing the bonus section in this task. To do 1. (5 points) Copy the program from Task II into a file with the name multiSpawn.c. 2. Reading data from file (10 pts.) ‐ The program shall read the first 10 patient records into an array of PatientInfo using a single call to fread(). 3. (10 points) The program should spawn a child process for each patient record. Each child should morph itself into the drAssessment program using the function in Task I. 3.1. The program needs to spawn all child processes before it starts collecting the responses from the child processes. Namely, the program must follow the manager‐worker paradigm. 4. (25 points) The parent program should only print the patients that require hospitalization. This will be done by examining the return code from the child processes. Note that if the child processes are not spawned before the program starts to collect the replies from the children, then the maximum for this section is 15. 4.1. (5 points) Here you will have to use the waitpid() function, which waits for child processes to complete their tasks. You will invoke the function as waitpid(‐1, &status, 0) where ‐1 indicates wait for any child process to complete their task. 4.2. (15 points) In order to complete this step, the program will need to “remember” which patient was assigned to each child process. The simplest way of handling it is to create an array of 10 integers for storing the children pid, e.g., childProcessIds[], and then assigning the process id of each spawned child in Step 3 to the corresponding array location. For example, assume that the patient records, which were read from the file, are stored in the array patients[]. Thus, when the program spawns a child to process the third patient (i.e., patients[2]), then the program would store the child process id (pid) in childProcessIds[2]. Then when the waitpid() returns the child process id, cpid, the parent program would search for cpid in the array childProcessIds and print the corresponding patient information, if needed. 4.3. (5 points) The parent program also needs to know when to quit. This can be done in two ways a. check the return code from waitpid(); If it is ‐1 then there are no more children, or an error has occurred. In this case the program can quit. B. count how many times it has received input from the children and quit once all children have responded. 5. (5 points) Create a make file for the program. Makefile name should be Makefile3. The program name should be multiSpawn 6. Bonus Section (10 points) 6.1. Allocating memory complete Section 3 and 4 above by determining how many numbers are in the file and then allocating memory for the array of numbers and array of process ids. Determining how many numbers are contained in the binary file copyright ©2021 Doron Nussbaum COMP 2401 Page5 of 5 is accomplished by determining the file size: a. moving the file pointer to the end of the file using fseek() and then b. determining the file size using ftell(), c. determine how many records are in the file (size of file / size of record) d. allocate memory for the array and read all the records Bonus Task IV Signals (10 points) In this task you will write enhance the program in Task III to use a simple signal SIGUSR1 1. Add a counter to your program from Task III, which tracks/collects the number of processes that have responded so far. 2. If signal SIGUSR1 is invoked, then the program should print how many processes have finished their execution and how many processes are still working. Note, that to accomplish this, you will need to use global variable within the file scope. For example, you can either declare it as static int countFinished or int countFinished. You will also need to keep as a global variable the total number of child processes that were launched. Otherwise, you will not be able to complete access the information from the interrupt function. 3. Create a make file for the program. Makefile name should be Makefile4. The program name should be multiSpawnSignal copyright