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.
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:
nsd
– the greatest common divisor
nd
– the greatest divisor
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).
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.
Create a Makefile
that has at least the following three targets:
lib
– for creation of shared library
all
– for creation of executable application
clean
– for cleaning all generated files
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.
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
.
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).
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.
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).
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.
In fact you are implementing something like this: while : ; do echo $RANDOM $RANDOM ; sleep 1; done | ./c1_task > out.txt
dup
function.
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>
– a seed for random generator
–verify
– turns on verification of the sequence numbers in the second sub-process
–error
– changes randomly selected numbers in the random sequence of the first sub-process
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>
).
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.
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).
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
/* (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; }