Search
WARNING: This information might be out of date. This version is up-to-date for the winter term 2016/2017.
The aim of this project is to understand the phases of program creation and compilation in the C language in the POSIX environment and the Makefile file creation for an automated build of the whole project.
Makefile
Implement a Makefile that creates a shared library libnsd.so from the source codes. nsd.c, nsd.h, nd.c and nd.h. The header files contain definition of the following functions:
libnsd.so
nsd
nd
Note: If the previous links do not work, download the files from the Czech version of the course.
Create a main program that uses the libnsd.so library. The program reads lines from stdin and interprets each line as two integer numbers (space separated). In case of erroneous input data, the program outputs an usage help onto the standard error output.
If the user entered two primes, output a string prime (ended by the EOL character). In other cases print the greatest common divisor of both numbers found (a number and an EOL).
prime
The program continues reading (and processing) the stdin until the stdin is closed (an EOF char received). Before the program exits, it prints a DONE string to stderr.
DONE
Create a Makefile that has at least the following three targets:
lib
all
clean
The target all is the default one (when the make is invoked with no arguments). Write the makefile so that only changed sources are compiled.
make
The task is evaluated automatically. You have to stick to the output format and to the makefile targets for the task to be accepted.
Into the Upload System upload only a zip file containing ONLY the source files (.h and .c including the nsd.h, nsd.c, nd.h and nd.c files) and the Makefile.
zip
.h
.c
nsd.h
nsd.c
nd.h
nd.c
General information of static and dynamic libraries
Tutorial on static and dynamic libraries
Hint: Prime number definition
This assignment is oriented towards the basic operation related to creating processes in the C language.
In the C or C++ language create a program that creates two processes (fork function) and connects them via pipe (the pipe function).
fork
pipe
The first descendant redirects its' stdout into the pipe and writes (space separated) pairs of random numbers into it (function rand). Delay the output of the numbers (i.e. by 1 second). The first descendant has to treat the SIGUSR1 signal (sigaction function) and in case of receiving such signal it prints a string “TERMINATED” to it's stderr and terminates.
rand
sigaction
The second descendant redirects the pipe output to it's stdin, redirects it's stdout into a file called out.txt in the current directory and executes a binary file (execl function) for finding the greatest common divisor (the output of C1 task).
out.txt
execl
C1
The parent process waits 5 seconds and then sends SIGUSR1 to the first process (number generator). This should perform a correct termination of both processes. It waits for the sub-processes to terminate (wait function) and terminates itself.
SIGUSR1
wait
In fact you are implementing something like this: while : ; do echo $RANDOM $RANDOM ; sleep 1; done | ./c1_task > out.txt
while : ; do echo $RANDOM $RANDOM ; sleep 1; done | ./c1_task > out.txt
dup
Create a Makefile that builds a binary application. In case of need the Makefile must also build the application for computing the greatest common divisor in a separate directory.
Make sure you followed the specification.
Make sure your code works on the computers in the lab.
In case to verify the correct implementation of your task you should1) implement the following commandline options (the order is not fixed, may repeat also):
–seed <num>
–verify
–error
The parent process should share the seed with both descendants.
Both the sub-processes use the seed for initializing the random sequence2).
If the –seed <num> option is not specified, use a random seed. In such case print the 'seed' to the stderr (Seed: <SEED>).
Seed: <SEED>
If the –verify option is specified, the second subprocess verifies whether the numbers received from the first sub-process are correct (match the sequence). In case it detects an error it prints a message: Error, expected: <ORIGINAL>, received: <RECEIVED> to stderr (substituting relevant values). It's wise to implement this in the (modified) program C1.
Error, expected: <ORIGINAL>, received: <RECEIVED>
If the –error option is specified, the first subprocess randomly replaces some number(s) from the sequence with different numbers. Therefore only a few numbers of the sequence are incorrect. In case of error injection it prints the message Modified <ORIGINAL> to <NEW> to stderr (substituting relevant values).
Modified <ORIGINAL> to <NEW>
Create an application (modify the C1 task program) that can verify the 'out.txt' file: Provided with a seed (as as –seed <num> parameter) it generates the same sequence of input values and verifies the out.txt file. Add it as a Makefile target: make test
make test
/* (Please update this header. Not updating it is an act of ignorance.) Name: John Doe Course: AE3B33OSD Semester: Summer term, 2016 Short description: ... I confess to plagiarism and other sins... */ int main() { char str[]="XX hex is 150\n"; unsigned char a=150; asm volatile ( "mov %%eax, %%ebx;" "shr $4, %%eax;" "and $15, %%eax;" "cmpl $9, %%eax;" "jg 1f;" "add $'0', %%eax;" "jmp 2f;" "1: add $'A', %%eax;" "2: movb %%al, (%%ecx);" /* Task: Complete the task below: 1) Understand what the code does 2) Complete the remaining part 3) Use syscall WRITE to print out the resulting string (str[]) 4) Write the resulting string (str[]) to a file: 4a) Using the open() function 4b) Using the open() syscall */ /* TODO: Insert your code here... */ : : "a" (a), "c" (str) : "ebx", "edx"); return 0; }