Protection and system calls
This session is dedicated to the study of protection and system calls in Operating Systems.
You don't need to submit source files or reports for this session.
For this session, you will need to log into a PC running Linux. If you are at Eurecom, simply log on a PC of rooms 52 or 53. If you were to use another PC running GNU/Linux, I cannot guarantee that the lab works in the same way (outputs could be different, manual pages could be different, etc.).
Important: you will create test files, some of which will be large.
As your disk quota is limited you will create these files in the /tmp
directory which purpose is actually to store temporary files.
It can perfectly be that another student works remotely on the same computer as you.
To avoid clashes first create a subdirectory with your user name (in the following we represent your user name as USERNAME
):
# Do not just copy-paste this: replace USERNAME with your user name $ mkdir -p /tmp/USERNAMEAt the end of the lab please do not forget to delete all temporary files to free disk space in
/tmp
(but be careful when using rm -rf
, if you get it wrong the consequences can be catastrophic; check your typing twice):$ rm -rf /tmp/USERNAME
Trick. Under GNU/Linux you can easily copy/paste with the mouse: select some text (click and drag, double-click or triple-click), move your cursor to the destination and click with the middle button (or the wheel).
I. Basic
- Be sure you have understood all the slides on the Introduction on Operating Systems
- How would you define a system call? Once you are happy with your definition, you can check on wikipedia for instance.
II. Services
-
Type the following command. How do you explain the difference with the
write()
function of the source code given as example in the slides?$ man write
-
Similarly, try to figure out if the following command are
bash
commands,syscalls
, or C library functions:read
,print
,printf
,malloc
,exit
,getpid
,ps
(Help me!) Useman -s2 f
to know if a functionf
is a syscall or not
III. Using system calls and data structures
In this exercise you will learn how to compile a C program, how to correct errors and warnings, how to use basic data structures, and finally how to use Linux system calls. You will also discover how to manipulate files from a C program.
- In this exercise, you will manipulate files: we read from a text files lines one by one, and we put each line content in a linked list. A linked list is a set of cells, each cell containing a value and a pointer to the next cell. It is typically defined in C as follows:
typedef struct LinkedList { char value[MAX_VALUE_SIZE]; struct LinkedList * next; } LinkedList;
value = "first cell" value = "second cell next = pointer to second cell
next = NULL
-
Save the
ll.c
file into your work directory, open it with your favorite text editor. Locate where theopen()
function is used. Verify thatopen()
is a system call. Find out how many syscalls are used inll.c
. - Study this source code in detail, find out its main purpose. What errors can be raised during execution? Can you explain in which case each of them is raised?
-
Compile
ll.c
to a binary file namedll
:$ gcc -Wall -o ll ll.c
-
Execute
writeToFile
. But first, create a file namedhello.txt
that contains on word per line. For instance,hello\nworld\nhow\nare\nyou\ntoday?
.$ ./ll hello.txt
The process should openhello.txt
and load it into a linked list. Verify that everything works as expected. Have you understood how the linked list is progressively filled with the file content? Be sure to have understood this before switching to the next questions! - Start the program without any argument:
$ ./ll
What happens? How could you do to provide a better error message even beforeopen()
is called?
(Help me!) Check that an argument is indeed provided on the command line. You could useargc
for instance. - Complete the
printListContent
function ofll.c
. Basically, you should go through the different cells of the list, starting from the first one, and print the value of each cell.First, think of how to access each cell. Then, for each cell, you just need to perform a
printf
on the value of the cell.Look at the help that follows only once you have really tried!
(Help me!) SPOILER!!!
TRY BEFORE LOOKING AT THIS!while(ll != NULL) { printf("%s ", ll->value); ll = ll->next; } printf("\n");
- Freeing the list. What exactly makes the call to
free(ll);
? Remember whatfree
makes: it frees the memory allocated at the provide address. What was allocated at this address? Only one cell! So, only one cell is freed with that call.Now that you have understood the problem, you are asked to code a function
freeLinkedList()
that frees the whole linked list given as parameter. Code and test.When starting to program with data structures, this is quite frequent to obtain "segmentation fault" errors, which means that you have tried to access to an invalid address. Putting
printf
in your code to try debugging an allocation error might not be the best solution. A better solution is to use a debugger likegdb
. For this, you need to compile your program with debugging information:$ gcc -Wall -g -o ll ll.c
And then you can investigate your error. Execute withgdb
(to run typerun
, to quit typequit
, to restart from the beginning type:start
):$gdb ./ll hello.txt ... (gdb) run ...
You should reach your error.gdb
is a complex debugger: you will learn more commands ofgdb
during the next lab. But at least, during this lab, this should give you the line number at which the error occurs in your code. - Implement a function that returns the current size of a linked list:
int sizeOfList(LinkedList *ll) { ... }
Test with different linked lists. - Implement a function to remove the nth element of a linked list:
void removeElementAt(LinkedList *ll, int index) { ... }
Test by removing the first element of the list, one in the middle, and the one at the end. - Implement a new C function that stores a new element at the end of the list. Currently, elements in the provided program are stored at the beginning of the list.
LinkedList* addToTheEndOfTheList(LinkedList *ll, char *content, int startIndex, int lastIndex) { ... }
- BONUS: implement a function that saves the linked list to a file.