Computer Science 330
Operating Systems
Fall 2025, Siena University
Quote: UNIX system calls, reading about those can be about as interesting as reading the phone book... - George Williams, Union College Computer Science, March 12, 1991.
(so we will not learn about them through a lecture, but by trying them out)
In this lab, you will learn and/or review some of the aspects of Unix systems programming that you will need for the upcoming shell project.
You must work individually on this lab.
Learning goals:
Getting Set Up
In Canvas, you will find a link to follow to set up your GitHub repository, which will be named sysprog-lab-yourgitname, for this lab.
Answers to written questions may be given in a PDF document committed and pushed to your repository (give the name in the README.md file), by writing them in a readable (reasonably nicely formatted, not all one big line of text) GitHub Markdown form in your repository's README.md file, or by linking to a shared document containing your answers from your README.md file.
Examples related to this lab are in
https://github.com/SienaCSISOperatingSystems/sysprog-examples
You should clone a copy of it outside of the repository you create and clone for this lab.
Low-level File Operations
You have used at least some of the C standard file I/O (stdio) routines defined in stdio.h, such as fopen(), fscanf(), fprintf(), and fclose(). These provide relatively "high-level" access to files in that you deal with formatted data (hence the `f' in `printf') rather than a low-level stream of bytes.
If we were to look at the implementations of those stdio functions, you would find these low-level operations: open(), close(), read(), write(). Our programs can call those directly, if we want.
Error Checking and Reporting
Before we look at those, we look at the standard error reporting mechanism. We have seen this in some of our examples, but have not looked closely at it.
Most Unix system calls can fail for a variety of reasons. You should always check the return value of system calls that may fail.
Read the intro(2) man page on noreaster and the errno(3) and perror(3) man pages on a Linux system to learn about or refresh your knowledge of the errno error condition variable and the system calls perror(3) and strerror(3) that allow you to print out (hopefully) meaningful error messages when you detect a failed system call.
perror/perror-ex.c in https://github.com/SienaCSISOperatingSystems/sysprog-examples.
Compile it in your clone of that repository (it has a Makefile).
A More Complete Example
Whereas fopen returns a value of type FILE *, the open call returns an int. This int has a special meaning - it is a file descriptor. It can subsequently be used in read and write calls, and is later passed to close when we are done.
There are three file descriptors that are automatically created for each process:
|
0 | the standard input (stdin) | |
| 1 | the standard output (stdout) | |
| 2 | the standard error output (stderr) | |
Note that stdin, stdout and stderr are the corresponding FILE * pointers that are created automatically by stdio.
Read through the man pages for these four system calls.
everyother/everyother.c in https://github.com/SienaCSISOperatingSystems/sysprog-examples.
Running a New Program - the exec Calls
Recall that the fork() system call creates an almost-exact copy of a process - each running the same program and executing at the statement immediately following the fork() call.
To create processes that do "something else", the fork() is followed by one of these "exec" calls, in the child process:
execl() - exec a process with list of arguments
execv() - exec a process with args specified in an array (the 'v' means use an argument "vector")
execlp() - like execl, but use the search PATH to find the program
execvp() - like execv, but use the search PATH to find the program
execvP() - like execv, but specify a search path to find the program
The man pages have details.
The related vfork() system call is often more appropriate when the child process will be doing an exec() immediately. It doesn't duplicate all of the memory for the parent process. Beware: this may cause you trouble in the shell if you use it, since the parent is usually suspended until the child exits or calls an exec.
We consider a series of example programs, all in the exec directory of https://github.com/SienaCSISOperatingSystems/sysprog-examples.
Start by looking at the exec.c program:
For each program you are asked to run in this part of the lab, run both on noreaster and on your Linux VM. When the output differs, include outputs and/or note any differences in your response, as appropriate.
Next, we look at a program that doesn't use any of the "exec" calls, but which will be useful as we look at further examples: procinfo. This one simply prints the process id and the command-line parameters (including one beyond the last).
Run the procinfo program a few times, giving it first no command-line parameters, then a few different combinations of command-line parameters.
Our last example program is execwithargs, which uses its command-line parameters to determine which program it should become (weird).
Practice With exec
Submission
Commit and push!
Grading
This assignment will be graded out of 45 points.
|
Feature | Value | Score |
| Question 1 | 1 | |
| Question 2 | 1 | |
| Question 3 | 1 | |
| Question 4 | 2 | |
| Question 5 | 1 | |
| Question 6 | 2 | |
| Question 7 | 4 | |
| Question 8 | 1 | |
| eo.txt file | 2 | |
| Question 9 | 1 | |
| Question 10 | 1 | |
| Question 11 | 1 | |
| Question 12 | 1 | |
| Question 13 | 1 | |
| Question 14 | 1 | |
| Question 15 | 2 | |
| Question 16 | 1 | |
| Question 17 | 1 | |
| Question 18 | 4 | |
| Question 19 | 2 | |
| Question 20 | 1 | |
| Question 21 | 3 | |
| execlsloop.c program | 10 | |
| Total | 45 | |