Skip to content
Gallery
CS480 Notes
Share
Explore
Project files

icon picker
Project 1

Last edited 199 days ago by System Writer
Name
Priority
Status
Finished
1
Open up Project 4 files
🚀 Done
Done
2
Notes and Article on System Implementation
🚀 Done
Done
3
Study Concepts and review
🚀 Done
Done
4
Pseudo Code
🚀 Done
Done
5
Implement project functionality
🚀 Done
Done
6
Get started on Project 4
🚀 Done
Done
There are no rows in this table

megaphone

Project parameters:

Purpose

This assignment intends to familiarize you with system calls such as fork, exec, wait, exit and etc., to spawn and terminate other user programs.

Assignment

This assignment builds on programming assignment#0, so you must have two executable files ready:
testalphabet and testspecial under ~/programming/zero folder before taking this assignment.
You will be provided two new files:
makefile
mulproc.c
Your assignment is to write code in mulproc.c to fork two child processes running the two programs testalphabet and testspecial generated in preliminary programming test in parallel.
Detailed Requirements:
Spawn exactly two child processes, one is to run testspecial program and the other is to run testalphabet program;
When a child process starts executing a program, print a message to the output screen showing which child process (with PID) is running this program (with program name), for example:
"CHILD <PID: 16741> process is executing testalphabet program!"
When one child process finishes executing a program, this child process should be terminated, and at the same time, a message should be print to the output screen showing which process (with PID) is done with this program (with program name), for example:
"CHILD <PID: 16741> process has done with testalphabet program !"
The messages should match the real execution orders, i.e. when the testspecial program starts/ends, the right message should pop up immediately. Hence, you need to track the starting/ending point of each child process.
The expected screen printing should be similar as follows:
CHILD <PID: 16741> process is executing testalphabet program!
CHILD <PID: 16742> process is executing testspecial program!
,-> 745668
. -> 798072
... ...
CHILD <PID: 16742> process has done with testspecial program! See the results above!
a -> 2973036
b -> 556908
... ...
CHILD <PID: 16741> process has done with testalphabet program! See the results above!
Note: Feel free to do any change of the file (fill the code, create new functions and etc). You also can create new .h and .c files (but I don’t think you really need).
Your program must execute correctly on Edoras machine, the instructor/TA will type the following commands to test your code:
make// generate executable file mulproc
./mulproc // two child processes will be generated to run testspecial and testalphabet programs as stated above.

Directions to complete your assignment

Login Edoras machine
Double check you have successfully completed programming assignment#0 and two executable files testalphabet and testspecial are generated under zero folder on edoras
Copy one.zip from the shared folder cs480-02 on Edoras server to programming folder
Unzip the zip on edoras using the commands:
unzip one.zip
so you will have one more folders: one (source files) under programming directory on edoras machine
Copy two executable programs: testalphabet and testspecial from your folder zero to folder one
Modify source files under folder one to complete this assignment.
Test your program to make sure it works correctly.
Re-test your program following the commands provided above and record the terminal session to Test.log
Write README file to explain your code and include your test result

How to submit your assignment

The source files under the one folder on edoras machine will be considered for grading.
Please finish your coding by 11:59pm July 16th and make sure your program must execute correctly on edoras. In addition, you also need to do canvas submission by adding a text saying "programming assignment#1 has been submitted and ready for grading". -5 points if missing the text in canvas submission.
Your grading may be started immediately after the deadline unless notice otherwise, so please make your files ready by the deadline.
If you plan to submit late with penalty, please let TA know before the due date.
Excuses of “but it worked on my machine” will not be accepted, so if you develop elsewhere, plan to leave time for any migration problems that might arise.
info

Terminal Commands Reference

To Connect, and pull from Edoras:
YKRw973o
ssh cssc 1710@edoras.sdsu.edu
ssh in with your account
Passwd:
After you login you can run finger $USER to check
check ls
Go to shared folder, find the folder labeled in the project requirements & copy the project files over to your programming file.
$: cd /home/cs/zhengli/cs480-02
$: ls
data.zip zero.zip
$: cp *.zip /home/cs/zhengli/cssc1710/programming
$: cd /home/cs/zhengli/cssc1710/programming
$: ls
data.zip zero.zip
For local pull of the project files:
$: scp cssc1710@edoras.sdsu.edu:/home/cs/zhengli/cssc1710/localpull/project.tar.gz ./
$: tar -xzvf project.tar.gz
$: unzip data.zip, zero.zip
$: rm project.tar.gz
Submission of project back to edoras:
$: zip -r project.zip programming
$: scp /home/eddie/workplace/cs480/prelimproj.zip cssc1710@edoras.sdsu.edu:~/programming








make testalphabet
Generate testalphabet executable
make testspecial
Generate testspecial executable
./testalphabet
./testspecial
script test.log
record test log to test.log file
exit
exit the recording to the log file

info

mulproc.c

sdf
/* * The main function will contain the following steps: */
int main(void) { // 1. Fork the first child process. // If we're in the child process: // 1.1 Print a message indicating that this child is starting the `testalphabet` program. // 1.2 Use exec (or a variant like execl, execv, execle, etc.) to replace the current process image with the `testalphabet` program. // If we're in the parent process: // 1.3 Do nothing, allowing the parent process to continue to the next step.
// 2. Fork the second child process. // If we're in the child process: // 2.1 Print a message indicating that this child is starting the `testspecial` program. // 2.2 Use exec (or a variant like execl, execv, execle, etc.) to replace the current process image with the `testspecial` program. // If we're in the parent process: // 2.3 Do nothing, allowing the parent process to continue to the next step.
// 3. Wait for the first child process to finish. // 3.1 Print a message indicating that the first child process has finished the `testalphabet` program.
// 4. Wait for the second child process to finish. // 4.1 Print a message indicating that the second child process has finished the `testspecial` program.
// 5. End the program. }
Order of Program Execution: The order in which the testalphabet and testspecial programs start and finish might not be the same as the order in which we fork the child processes. This is because process scheduling is managed by the operating system, and it can vary based on many factors. If the exact order of execution is important, we might need to implement some form of synchronization between the processes.
Error Handling: The pseudocode above assumes that all system calls (fork, exec, and wait) succeed. In a real program, we should check the return values of these functions and handle any errors that might occur.
Finding the Executable Files: The exec function will need to know the exact path to the testalphabet and testspecial programs. We need to make sure these paths are correct.
Child Termination Message: The requirement for a message to be printed when a child process finishes executing a program is a bit tricky, as typically when a child process ends, it's no longer in control (it has exited). We can get around this by having the parent process print out this message after the wait call, but it's worth noting that technically it won't be the child process that's printing this message.
make clean
make
./mulproc
eddie@eddie-pcmasterrace:~/workplace/cs480/programming/one$ ./mulproc CHILD <15307> process has started executing testalphabet program! CHILD <15308> process has started executing testspecial program! a -> 2973036 b -> 556908 c -> 765864 d -> 1786752 e -> 4883076 f -> 765336 g -> 809292 h -> 2818068 i -> 2586276 j -> 35112 k -> 401412 l -> 1728276 m -> 1050852 n -> 2509320 o -> 2766192 p -> 562848 q -> 28776 r -> 2177076 s -> 2465496 t -> 3291684 u -> 1015608 v -> 276804 w -> 1085040 x -> 46860 y -> 730752 z -> 12936 CHILD <15307> process has finished with testalphabet program! , -> 745668 . -> 798072 : -> 15708 ; -> 32340 ! -> 63228 CHILD <15308> process has finished with testspecial program!



ok

Special char Start

The function reads the .txt files in the specified directory, counts the frequency of each specified special character, and writes these frequencies to the specified output file. It also includes error checks for file and directory operations.
#include <stdio.h> #include "count.h"
void specialcharcount(char *path, char *filetowrite, long charfreq[]) { // Define the special characters to count. // Open the directory specified by the 'path' parameter. // If the directory cannot be opened, return.
// For each file in the directory: // Check if the file has a .txt extension by comparing the last 4 characters of the filename to ".txt". // If it is a .txt file, construct the full file path and open the file. // If the file cannot be opened, continue to the next file. // For each character in the file: // Iterate over the list of special characters. // If the character matches a special character, increment the corresponding element in the 'charfreq' array. // Close the file.
// Open the output file specified by the 'filetowrite' parameter. // If the file cannot be opened, return. // Write the 'charfreq' array to the output file in the format "character -> frequency". // Close the output file and the directory. }

Considerations/assumptions:

File List: We could first create a list of .txt files to process. This could potentially reduce the number of directory operations, as we wouldn't need to check each file's extension individually.
Special Characters Flexibility: We could modify the function to take an additional parameter: an array of the special characters we're interested in. This makes our function much more versatile, as we can easily change the special characters we're counting without altering the function itself.
NEW THOUGHTS:
Error Handling:
Question: How does your implementation handle errors when opening files or directories?
Reflection: The code you provided includes checks after each file and directory operation, similar to the code we discussed. However, it chooses to "silently ignore" files that cannot be opened for reading, whereas the code we discussed prints an error message for each file that cannot be opened. Again, the choice between these two strategies depends on the specific requirements of the project and personal preference.
File Extension Check:
Question: How does your implementation check for .txt files?
Reflection: Your code checks the file extension by looking at the last 4 characters of the filename and comparing them to ".txt". This is similar to the comment we made in the alphabetlettercount function review. This approach is more precise than using the strstr function, which checks if ".txt" appears anywhere in the filename.
Character Counting:
Question: How does your implementation handle the counting of special characters?
Reflection: Your code iterates over a hardcoded list of special characters and increments the corresponding element in the charfreq array if a match is found. This is similar to the approach we discussed, but your implementation doesn't use a separate function or array to check if a character is special. This makes your code more concise but less flexible if the list of special characters needs to change.
Output Writing:
Question: How does your implementation write the output?
Reflection: Your code writes the output to the specified file in the format "character -> frequency", which is slightly different from the format we discussed ("character: frequency"). Both formats are clear and easy to understand, and the choice between them would depend on the specific requirements of the project.
ok

alphabet count start

The function reads the .txt files in the specified directory, counts the frequency of each alphabet letter (case-insensitive), and writes these frequencies to the specified output file. It also includes error checks for file and directory operations.
#include <stdio.h> #include "count.h"
void alphabetlettercount(char *path, char *filetowrite, long alphabetfreq[]) { // Open the directory specified by the 'path' parameter. // If the directory cannot be opened, return.
// For each file in the directory: // Check if the file has a .txt extension by comparing the last 4 characters of the filename to ".txt". // If it is a .txt file, construct the full file path and open the file. // If the file cannot be opened, continue to the next file. // For each character in the file: // Check if the character is an alphabet letter. // If it is, convert it to lowercase using the 'tolower' function and increment the corresponding element in the 'alphabetfreq' array. // Close the file.
// Open the output file specified by the 'filetowrite' parameter. // If the file cannot be opened, return. // Write the 'alphabetfreq' array to the output file in the format "letter -> frequency". // Close the output file and the directory. }
Considerations/assumptions:
Error Handling:
Question: How does your implementation handle errors when opening files or directories?
Reflection: The code you provided includes checks after each file and directory operation, similar to the code we discussed. However, it chooses to "silently ignore" files that cannot be opened for reading, whereas the code we discussed prints an error message for each file that cannot be opened. The choice between these two strategies depends on the specific requirements of the project and personal preference.
File Extension Check:
Question: How does your implementation check for .txt files?
Reflection: Your code checks the file extension by looking at the last 4 characters of the filename and comparing them to ".txt". This is a straightforward and effective method. The code we discussed uses the strstr function, which checks if ".txt" appears anywhere in the filename. While strstr works, it could potentially match files that are not .txt files (for example, "file.txt.bak"). Therefore, your implementation is more precise in this regard.
Character Conversion and Counting:
Question: How does your implementation handle case conversion and letter counting?
Reflection: Your code converts uppercase letters to lowercase using the tolower function and increments the corresponding element in the alphabetfreq array. This is exactly the same as the approach we discussed.
Output Writing:
Question: How does your implementation write the output?
Reflection: Your code writes the output to the specified file in the format "letter -> frequency", which is slightly different from the format we discussed ("letter: frequency"). Both formats are clear and easy to understand, and the choice between them would depend on the specific requirements of the project.
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.