├── cw01 ├── zad1 │ ├── e.txt │ ├── f.txt │ ├── a.txt │ ├── b.txt │ ├── c.txt │ ├── d.txt │ ├── makefile │ ├── library.h │ ├── main.c │ └── library.c ├── zad2 │ ├── u.txt │ ├── a.txt │ ├── b.txt │ ├── i.txt │ ├── o.txt │ ├── e.txt │ ├── f.txt │ ├── makefile │ ├── l.txt │ ├── k.txt │ ├── j.txt │ ├── args.txt │ ├── c.txt │ ├── d.txt │ ├── h.txt │ ├── g.txt │ ├── m.txt │ ├── raport2.txt │ ├── main.c │ └── n.txt ├── zad3a │ ├── makefile │ ├── main.c │ ├── main_dyn.c │ └── raport3a.txt ├── zad3b │ ├── main.c │ ├── makefile │ └── main_dyn.c └── README.md ├── cw05 ├── zad2 │ ├── test.txt │ ├── makefile │ └── main.c ├── zad1 │ ├── commands.txt │ ├── makefile │ └── main.c ├── zad3 │ ├── makefile │ ├── consumer.c │ ├── producer.c │ └── main.c └── README.md ├── cw04 ├── zad1 │ ├── makefile │ └── main.c ├── zad4b │ ├── additionalReport4b │ ├── makefile │ ├── catcher.c │ └── sender.c ├── zad3 │ ├── makefile │ └── main.c ├── zad4a │ ├── additionalReport4a.txt │ ├── makefile │ ├── sender.c │ └── catcher.c ├── zad2 │ ├── raport2.txt │ ├── makefile │ ├── exec.c │ └── main.c └── README.md ├── cw09 ├── zad1 │ ├── makefile │ └── main.c └── README.md ├── cw06 ├── zad1 │ ├── makefile │ └── common.h ├── zad2 │ ├── makefile │ └── common.h └── README.md ├── cw10 ├── zad2 │ ├── makefile │ ├── client.c │ └── common.h ├── zad1 │ ├── makefile │ ├── common.h │ └── client.c └── README.md ├── cw07 ├── zad2 │ ├── common.c │ ├── makefile │ ├── common.h │ ├── receiver.c │ ├── packer.c │ ├── sender.c │ └── main.c ├── zad1 │ ├── makefile │ ├── common.c │ ├── common.h │ ├── sender.c │ ├── receiver.c │ ├── packer.c │ └── main.c └── README.md ├── cw03 ├── zad2 │ ├── makefile │ ├── generator.c │ └── test.c ├── zad3 │ ├── makefile │ ├── generator.c │ └── test.c ├── zad1 │ ├── makefile │ └── main.c └── README.md ├── cw02 ├── zad2 │ ├── makefile │ └── main.c ├── zad1 │ └── makefile └── README.md ├── README.md └── cw08 ├── zad1 ├── makefile └── Times.txt └── README.md /cw01/zad1/e.txt: -------------------------------------------------------------------------------- 1 | ala 2 | ola 3 | mama 4 | -------------------------------------------------------------------------------- /cw01/zad1/f.txt: -------------------------------------------------------------------------------- 1 | ala 2 | ola 3 | mama 4 | -------------------------------------------------------------------------------- /cw01/zad1/a.txt: -------------------------------------------------------------------------------- 1 | aaa 2 | bbb ccc 3 | ddd 4 | eee 5 | hhh iii 6 | -------------------------------------------------------------------------------- /cw01/zad1/b.txt: -------------------------------------------------------------------------------- 1 | jjj kkk 2 | aaa 3 | fff ccc 4 | eee 5 | bbb ggg 6 | -------------------------------------------------------------------------------- /cw01/zad1/c.txt: -------------------------------------------------------------------------------- 1 | ggg 2 | hhh ooo 3 | ppp 4 | ala 5 | ola 6 | xxx 7 | -------------------------------------------------------------------------------- /cw01/zad1/d.txt: -------------------------------------------------------------------------------- 1 | ggg 2 | ola 3 | hhh ooo 4 | mmm 5 | ala 6 | ppp 7 | yyy aaa 8 | -------------------------------------------------------------------------------- /cw05/zad2/test.txt: -------------------------------------------------------------------------------- 1 | ZZ 2 | AB 3 | CD 4 | CC 5 | G 6 | P 7 | OL 8 | W 9 | EL 10 | HI 11 | I 12 | MN -------------------------------------------------------------------------------- /cw01/zad2/u.txt: -------------------------------------------------------------------------------- 1 | abscised 2 | abscises 3 | abscising 4 | abscissa 5 | abscissas 6 | abscission 7 | abscond 8 | -------------------------------------------------------------------------------- /cw04/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o main main.c 5 | 6 | clean: main 7 | rm main -------------------------------------------------------------------------------- /cw01/zad2/a.txt: -------------------------------------------------------------------------------- 1 | aaa 2 | bbb ccc 3 | ddd 4 | eee 5 | hhh iii 6 | xxx 7 | bbbqqq 8 | agh 9 | uiop 10 | asd 11 | wdi 12 | -------------------------------------------------------------------------------- /cw01/zad2/b.txt: -------------------------------------------------------------------------------- 1 | jjj kkk 2 | aaa 3 | fff ccc 4 | eee 5 | bbb ggg 6 | asd 7 | wdi 8 | xdd 9 | ha 10 | lalka 11 | qqq 12 | -------------------------------------------------------------------------------- /cw05/zad1/commands.txt: -------------------------------------------------------------------------------- 1 | cat ./main.c | wc -l 2 | cat ./main.c | head -5 | sort 3 | cat ./makefile | wc -l 4 | ps -aux | grep root | wc -l 5 | ls -al ./ | sort -r | head -1 -------------------------------------------------------------------------------- /cw05/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o main main.c 5 | 6 | clean: main 7 | rm main 8 | 9 | test: 10 | make compile 11 | ./main test.txt -------------------------------------------------------------------------------- /cw05/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o main main.c 5 | 6 | clean: main 7 | rm main 8 | 9 | test: 10 | make compile 11 | ./main commands.txt -------------------------------------------------------------------------------- /cw09/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o main main.c -lpthread -lm 5 | 6 | clean: 7 | rm -f main 8 | 9 | test: 10 | make compile 11 | ./main 2 8 -------------------------------------------------------------------------------- /cw04/zad4b/additionalReport4b: -------------------------------------------------------------------------------- 1 | Niezależnie od sposobu wysyłania sygnałów oraz ich ilości catcher otrzymuje prawidłową ilość sygnałów 2 | oraz sender otrzymuje prawidłową ilość sygnałów powracających. -------------------------------------------------------------------------------- /cw06/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o client client.c 5 | $(CC) -o server server.c 6 | 7 | clean: 8 | rm -f server client 9 | 10 | test: 11 | make compile 12 | ./server -------------------------------------------------------------------------------- /cw04/zad3/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o main main.c 5 | 6 | test: 7 | make compile 8 | ./main child 9 | ./main segFault 10 | ./main status 11 | 12 | clean: main 13 | rm main -------------------------------------------------------------------------------- /cw06/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o client client.c -lrt 5 | $(CC) -o server server.c -lrt 6 | 7 | clean: 8 | rm -f server client 9 | 10 | test: 11 | make compile 12 | ./server -------------------------------------------------------------------------------- /cw10/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -Wall 3 | 4 | compile: client.c server.c 5 | $(CC) $(FLAGS) -o client client.c -lpthread -lm 6 | $(CC) $(FLAGS) -o server server.c -lpthread -lm 7 | 8 | clean: 9 | rm -f client 10 | rm -f server -------------------------------------------------------------------------------- /cw04/zad4a/additionalReport4a.txt: -------------------------------------------------------------------------------- 1 | Najwięcej sygnałów gubiło się podczas przesyłania sygnałów przez funkcję kill(). 2 | Procent odebranych sygnałów rośnie wraz z ilością wysłanych sygnałów. 3 | Procent odebranych sygnałów jest największy dla sygnałów czasu rzeczywistego. -------------------------------------------------------------------------------- /cw04/zad4a/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | 4 | sender: 5 | $(CC) $(FLAGS) sender.c -o sender 6 | 7 | catcher: 8 | $(CC) $(FLAGS) catcher.c -o catcher 9 | 10 | compile: 11 | make sender 12 | make catcher 13 | 14 | clean: 15 | rm -rf sender catcher -------------------------------------------------------------------------------- /cw04/zad4b/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | 4 | sender: 5 | $(CC) $(FLAGS) sender.c -o sender 6 | 7 | catcher: 8 | $(CC) $(FLAGS) catcher.c -o catcher 9 | 10 | compile: 11 | make sender 12 | make catcher 13 | 14 | clean: 15 | rm -rf sender catcher -------------------------------------------------------------------------------- /cw04/zad2/raport2.txt: -------------------------------------------------------------------------------- 1 | FORK: 2 | Proces potomny dziedziczy ignorowanie, handlery i maskowanie sygnalow. 3 | Sygnal czekajacy w przodku, nie jest widoczny w potomku. 4 | 5 | EXEC: 6 | Proces potomny dziedziczy ignorowanie i maskowanie sygnalow. 7 | Sygnal czekajacy w przodku, jest widoczny w potomku. -------------------------------------------------------------------------------- /cw06/zad2/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #define MAX_CLIENTS 5 5 | #define MAX_MESSAGE_LEN 8192 6 | #define NAME_LEN 20 7 | 8 | typedef enum message_type{ 9 | STOP = 1, DISCONNECT = 2, INIT = 3, LIST = 4, CONNECT = 5 10 | }message_type; 11 | 12 | const char* SERVER_QUEUE_NAME = "/MYSERVER"; 13 | 14 | #endif //COMMON_H -------------------------------------------------------------------------------- /cw07/zad2/common.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | int rand_int(){ 4 | return (rand() % (MAX_VAL - MIN_VAL + 1) + MIN_VAL); 5 | } 6 | 7 | int rand_time(){ 8 | return ((rand() % (MAX_SLEEP - MIN_SLEEP + 1) + MIN_SLEEP) * 1000); 9 | } 10 | 11 | void error_exit(char* message, char* place){ 12 | printf("ERROR: %s, in %s\n", message, place); 13 | exit(EXIT_FAILURE); 14 | } -------------------------------------------------------------------------------- /cw10/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC=gcc -Wall 2 | 3 | compile: client.c server.c 4 | $(CC) -o client client.c -lpthread -lm 5 | $(CC) -o server server.c -lpthread -lm 6 | 7 | runServer: server 8 | ./server 6666 socket 9 | 10 | runClientNet: client 11 | ./client "Jan" INET 127.0.0.1 6666 12 | 13 | runClientLocal: client 14 | ./client "Ala" LOCAL socket 15 | 16 | clean: 17 | rm -f client server socket -------------------------------------------------------------------------------- /cw01/zad2/i.txt: -------------------------------------------------------------------------------- 1 | written 2 | wrns 3 | wrong 4 | wrongdoer 5 | wrongdoers 6 | wrongdoing 7 | wronged 8 | wrongful 9 | wrongfully 10 | wronging 11 | wrongly 12 | wrongs 13 | wrote 14 | wroth 15 | wrotham 16 | wrought 17 | wrung 18 | wrvs 19 | wry 20 | zing 21 | zinged 22 | zinger 23 | aaa 24 | bbb ccc 25 | ddd 26 | eee 27 | hhh iii 28 | wryer 29 | wryest 30 | wryly 31 | wsw 32 | wyatt 33 | wycombe 34 | -------------------------------------------------------------------------------- /cw04/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | 4 | compile: 5 | $(CC) $(FLAGS) main.c -o main 6 | $(CC) $(FLAGS) exec.c -o exec 7 | 8 | clean: 9 | rm -rf main exec 10 | 11 | forkTest: 12 | make clean 13 | make compile 14 | ./main ignore fork 15 | ./main pending fork 16 | ./main mask fork 17 | ./main handler fork 18 | 19 | execTest: 20 | make clean 21 | make compile 22 | ./main ignore exec 23 | ./main pending exec 24 | ./main mask exec -------------------------------------------------------------------------------- /cw03/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compileM: 4 | $(CC) macierz.c -lm -o macierz 5 | 6 | compileG: 7 | $(CC) -o generator generator.c 8 | mkdir macierze 9 | 10 | compileT: 11 | $(CC) -o test test.c 12 | 13 | testAll: 14 | make clean 15 | make compileG 16 | ./generator 15 4 18 17 | make compileM 18 | ./macierz lista 10 100000 1 19 | make compileT 20 | ./test lista 21 | 22 | clean: 23 | rm -f macierz generator lista test 24 | rm -rf macierze 25 | -------------------------------------------------------------------------------- /cw03/zad3/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compileM: 4 | $(CC) macierz.c -lm -o macierz 5 | 6 | compileG: 7 | $(CC) -o generator generator.c 8 | mkdir macierze 9 | 10 | compileT: 11 | $(CC) -o test test.c 12 | 13 | testAll: 14 | make clean 15 | make compileG 16 | ./generator 15 4 18 17 | make compileM 18 | ./macierz lista 10 100000 commonFile 1 100 19 | make compileT 20 | ./test lista 21 | 22 | clean: 23 | rm -f macierz generator lista test 24 | rm -rf macierze 25 | -------------------------------------------------------------------------------- /cw01/zad2/o.txt: -------------------------------------------------------------------------------- 1 | abstractedly 2 | abstractedness 3 | abstracter 4 | zibelines 5 | ziggurat 6 | ziggurats 7 | zigzag 8 | zigzagged 9 | zigzagging 10 | zigzags 11 | zilch 12 | zilches 13 | episode 14 | episodes 15 | episodic 16 | episodical 17 | episodically 18 | epistemological 19 | epistemologies 20 | epistemology 21 | epistle 22 | epistles 23 | epistola 24 | zimbabwe 25 | zimbabwean 26 | zimbabweans 27 | zimmer 28 | zimmerman 29 | zinc 30 | zinfandel 31 | abstracters 32 | abstracting 33 | -------------------------------------------------------------------------------- /cw05/zad3/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | 4 | main: main.c 5 | $(CC) $(FLAGS) main.c -o main 6 | 7 | producer: producer.c 8 | $(CC) $(FLAGS) producer.c -o producer 9 | 10 | consumer: consumer.c 11 | $(CC) $(FLAGS) consumer.c -o consumer 12 | 13 | compile: main.c producer.c consumer.c 14 | make main 15 | make producer 16 | make consumer 17 | mkdir files 18 | touch files/results 19 | 20 | clean: 21 | rm -f main 22 | rm -f producer 23 | rm -f consumer 24 | rm -f pipe 25 | rm -rf files -------------------------------------------------------------------------------- /cw07/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | all: test clean 4 | 5 | compile: 6 | make main 7 | make receiver 8 | make packer 9 | make sender 10 | 11 | main: main.c 12 | $(CC) -o main main.c common.c 13 | 14 | receiver: receiver.c 15 | $(CC) -o receiver receiver.c common.c 16 | 17 | packer: packer.c 18 | $(CC) -o packer packer.c common.c 19 | 20 | sender: sender.c 21 | $(CC) -o sender sender.c common.c 22 | 23 | clean: 24 | rm -f main receiver sender packer 25 | 26 | test: 27 | make compile 28 | ./main -------------------------------------------------------------------------------- /cw01/zad2/e.txt: -------------------------------------------------------------------------------- 1 | epigraph 2 | epigraphic 3 | epigraphs 4 | epigraphy 5 | epilepsy 6 | epileptic 7 | epiphytic 8 | episcopacies 9 | episcopacy 10 | episcopal 11 | episcopalian 12 | episcopalians 13 | episcopate 14 | episcopates 15 | episcope 16 | episode 17 | episodes 18 | episodic 19 | episodical 20 | episodically 21 | epistemological 22 | epistemologies 23 | epistemology 24 | epistle 25 | epistles 26 | epistola 27 | epistolae 28 | epistolary 29 | epitaph 30 | epitaphs 31 | epithelial 32 | epithelium 33 | epithet 34 | epithets 35 | -------------------------------------------------------------------------------- /cw01/zad2/f.txt: -------------------------------------------------------------------------------- 1 | enunciate 2 | enunciation 3 | enunciator 4 | envelop 5 | envisioned 6 | envisioning 7 | envisions 8 | envoi 9 | envois 10 | envoy 11 | enwraps 12 | enzymatic 13 | zoologist 14 | zoologists 15 | zoology 16 | zoom 17 | zoomed 18 | zooming 19 | zooms 20 | zoophyte 21 | eosin 22 | epaulet 23 | epaulets 24 | epaulette 25 | epaulettes 26 | epee 27 | epees 28 | ephedrine 29 | ephemera 30 | ephemeral 31 | ephemerally 32 | ephesians 33 | ephesus 34 | ephraim 35 | epic 36 | epicene 37 | epicenter 38 | epicenters 39 | epicentre 40 | epicentres 41 | -------------------------------------------------------------------------------- /cw02/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o myFind main.c 5 | 6 | clean: 7 | rm -f myFind 8 | 9 | test: 10 | mkdir dir1 11 | mkdir dir1/dir2 12 | mkdir dir1/dir2/dir3 13 | touch dir1/file1 14 | touch dir1/dir2/file2 15 | touch dir1/dir2/dir3/file3 16 | touch dir1/file12 17 | ln -s dir1 link1 18 | ln -s dir1/dir2 link2 19 | make compile 20 | ./myFind ../ -maxdepth 2 -mtime 0 21 | 22 | clean_all: 23 | make clean 24 | rm -f file1 25 | rm -f file2 26 | rm -f file3 27 | rm -f link1 28 | rm -f link2 29 | rm -r dir1 -------------------------------------------------------------------------------- /cw03/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o zad1 main.c 5 | 6 | clean: 7 | rm -f zad1 8 | 9 | test: 10 | mkdir dir1 11 | mkdir dir1/dir2 12 | mkdir dir1/dir2/dir3 13 | touch dir1/file1 14 | touch dir1/dir2/file2 15 | touch dir1/dir2/dir3/file3 16 | touch dir1/file12 17 | ln -s dir1 link1 18 | ln -s dir1/dir2 link2 19 | make compile 20 | ./zad1 ~/OperatingSystems/cw03/zad1 21 | 22 | clean_all: 23 | make clean 24 | rm -f file1 25 | rm -f file2 26 | rm -f file3 27 | rm -f link1 28 | rm -f link2 29 | rm -r dir1 -------------------------------------------------------------------------------- /cw06/zad1/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #define MAX_CLIENTS 5 5 | #define MAX_MESSAGE_LEN 1024 6 | 7 | typedef enum message_type{ 8 | STOP = 1, DISCONNECT = 2, INIT = 3, LIST = 4, CONNECT = 5 9 | }message_type; 10 | 11 | typedef struct message{ 12 | long message_type; 13 | char text[MAX_MESSAGE_LEN]; 14 | int client_id; 15 | int connected_client_id; 16 | key_t queue_key; 17 | } message; 18 | 19 | const int MESSAGE_SIZE = sizeof(message) - sizeof(long); 20 | const int SERVER_KEY_ID = 5; 21 | 22 | #endif //COMMON_H -------------------------------------------------------------------------------- /cw07/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | all: test clean 4 | 5 | compile: 6 | make main 7 | make receiver 8 | make packer 9 | make sender 10 | 11 | main: main.c 12 | $(CC) -o main main.c common.c -lpthread -lrt 13 | 14 | receiver: receiver.c 15 | $(CC) -o receiver receiver.c common.c -lpthread -lrt 16 | 17 | packer: packer.c 18 | $(CC) -o packer packer.c common.c -lpthread -lrt 19 | 20 | sender: sender.c 21 | $(CC) -o sender sender.c common.c -lpthread -lrt 22 | 23 | clean: 24 | rm -f main receiver sender packer 25 | 26 | test: 27 | make compile 28 | ./main -------------------------------------------------------------------------------- /cw01/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | LIB_NAME = lib_diff 4 | LIB_PATH = ../zad1 5 | REPORT_FILE = raport2.txt 6 | 7 | static: main.c 8 | $(CC) $(FLAGS) main.c -o main -I$(LIB_PATH) $(LIB_PATH)/$(LIB_NAME).a 9 | 10 | shared: 11 | $(CC) $(FLAGS) main.c -o main -L$(LIB_PATH) -I$(LIB_PATH) -l_diff 12 | 13 | dynamic: 14 | $(CC) $(FLAGS) -I$(LIB_PATH) main.c -ldl -D DYNAMIC -o main 15 | 16 | test: 17 | make static 18 | rm -f $(REPORT_FILE) 19 | LD_LIBRARY_PATH=$(LIB_PATH) ./main $(shell cat args.txt) 20 | mv raport.txt $(REPORT_FILE) 21 | 22 | clean: 23 | rm -rf main raport2.txt 24 | -------------------------------------------------------------------------------- /cw01/zad2/l.txt: -------------------------------------------------------------------------------- 1 | widespread 2 | widest 3 | widgeon 4 | widgeons 5 | morse 6 | morsel 7 | mort 8 | mortal 9 | mortally 10 | mortals 11 | laryngologist 12 | laryngoscope 13 | laryngoscopes 14 | larynx 15 | larynxes 16 | las 17 | lasagna 18 | lasagnas 19 | lasagne 20 | lasagnes 21 | lascivious 22 | lasciviously 23 | lasciviousness 24 | laser 25 | laserjet 26 | lasers 27 | kenyan 28 | kepi 29 | lash 30 | kensington 31 | kent 32 | jagger 33 | jags 34 | jaguar 35 | jaguars 36 | jai 37 | jail 38 | jailed 39 | jailer 40 | jailers 41 | irreplevisable 42 | irrepressibility 43 | jailhouse 44 | irreproachable 45 | irresistible 46 | irresistibly 47 | -------------------------------------------------------------------------------- /cw01/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -Wall 3 | LIB_NAME = lib_diff 4 | SOURCE_NAME = library 5 | 6 | 7 | static: 8 | $(CC) $(FLAGS) -c $(SOURCE_NAME).c -o $(LIB_NAME).o 9 | ar rcs $(LIB_NAME).a $(LIB_NAME).o 10 | 11 | shared: 12 | $(CC) -fPIC $(FLAGS) -c library.c -o $(LIB_NAME).o 13 | $(CC) -fPIC $(FLAGS) -shared -o $(LIB_NAME).so $(LIB_NAME).o 14 | 15 | clean: 16 | rm -f *.o 17 | 18 | clean_all: 19 | make clean 20 | rm main $(LIB_NAME).a $(LIB_NAME).so 21 | 22 | 2static: 23 | make static 24 | $(CC) -c main.c 25 | $(CC) main.o $(LIB_NAME).a -o main 26 | 27 | 2shared: 28 | make shared 29 | $(CC) main.c $(LIB_NAME).so -L ./ -o main -Wl,-rpath,$(shell pwd) 30 | -------------------------------------------------------------------------------- /cw05/zad2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | const int MAX_LINE_LEN = 10000; 8 | 9 | void error(char *msg){ 10 | printf("%s\n", msg); 11 | exit(EXIT_FAILURE); 12 | } 13 | 14 | int main(int argc, char **argv){ 15 | if (argc != 2){ 16 | error("Wrong number of arguments. Expected: [path]"); 17 | } 18 | 19 | FILE *file = fopen(argv[1], "r"); 20 | char* line = malloc(MAX_LINE_LEN); 21 | FILE *sorted_file = popen("sort", "w"); 22 | while(fgets(line, MAX_LINE_LEN, file) != NULL){ 23 | fputs(line, sorted_file); 24 | } 25 | pclose(sorted_file); 26 | free(line); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /cw01/zad2/k.txt: -------------------------------------------------------------------------------- 1 | widest 2 | widgeons 3 | widgeon 4 | morrows 5 | mors 6 | morse 7 | morsel 8 | morsels 9 | mort 10 | mortal 11 | mortality 12 | mortally 13 | mortals 14 | mortar 15 | mortarboard 16 | mortarboards 17 | lasagna 18 | lasagnas 19 | lasagne 20 | laser 21 | kenny 22 | keno 23 | kenos 24 | kensington 25 | kent 26 | kentledge 27 | kentucky 28 | kenya 29 | kenyan 30 | jaguar 31 | jaguars 32 | jai 33 | kepi 34 | jailhouse 35 | irreplaceably 36 | irrepleviable 37 | irreplevisable 38 | irrepressibility 39 | irrepressible 40 | zing 41 | zinged 42 | zinger 43 | aaa 44 | bbb ccc 45 | ddd 46 | eee 47 | hhh iii 48 | irrepressibly 49 | irreproachable 50 | irreproachably 51 | irreproducible 52 | irresistibility 53 | irresistible 54 | irresistibly 55 | -------------------------------------------------------------------------------- /cw04/zad2/exec.c: -------------------------------------------------------------------------------- 1 | #define _POSIX_C_SOURCE 1 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char **argv){ 9 | if (argc != 2){ 10 | printf("Wrong number of arguments. Expected: ./prog [mask / pending]\n"); 11 | exit(EXIT_FAILURE); 12 | } 13 | 14 | if (strcmp("pending", argv[1]) != 0){ 15 | raise(SIGUSR1); 16 | } 17 | 18 | if (!strcmp("pending", argv[1]) || !strcmp("mask", argv[1])){ 19 | sigset_t mask; 20 | sigpending(&mask); 21 | if(sigismember(&mask, SIGUSR1)){ 22 | printf("Signal pending in child.\n\n"); 23 | } 24 | else{ 25 | printf("Signal not pending in child.\n\n"); 26 | } 27 | } 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SysOpy 2 | 3 | ## AGH Operating Systems 2020 4 | 5 | 6 | | Lab | Theme | Done | 7 | |-----| -----| -----| 8 | |[1](../master/cw01 "Cw 01") | Memory management. Libraries. Time measurement |✓| 9 | |[2](../master/cw02 "Cw 02") | File system. File operations |✓| 10 | |[3](../master/cw03 "Cw 03") | Creating process. Process environment, process control |✓| 11 | |[4](../master/cw04 "Cw 04") | Signals |✓| 12 | |[5](../master/cw05 "Cw 05") | Inter-process communication (pipeline) |✓| 13 | |[6](../master/cw06 "Cw 06") | Inter-process communication (queue message) |✓| 14 | |[7](../master/cw07 "Cw 07") | Inter-process communication (semaphore) |✓| 15 | |[8](../master/cw08 "Cw 08") | Threads - image filtering |✓| 16 | |[9](../master/cw09 "Cw 09") | Threads - synchronization methods |✓| 17 | |[10](../master/cw10 "Cw 10") | Network sockets |✓| -------------------------------------------------------------------------------- /cw07/zad1/common.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | int rand_int(){ 4 | return (rand() % (MAX_VAL - MIN_VAL + 1) + MIN_VAL); 5 | } 6 | 7 | int rand_time(){ 8 | return ((rand() % (MAX_SLEEP - MIN_SLEEP + 1) + MIN_SLEEP) * 1000); 9 | } 10 | 11 | void error_exit(char* message, char* place){ 12 | printf("ERROR: %s, in %s\n", message, place); 13 | exit(EXIT_FAILURE); 14 | } 15 | 16 | int get_semaphore_id(){ 17 | key_t key = ftok(getenv("HOME"), 0); 18 | int id = semget(key, 0, 0); 19 | if (id < 0) error_exit("Cannot get semaphore id", "function get_semaphore_id"); 20 | return id; 21 | } 22 | 23 | int get_shared_memory_id(){ 24 | key_t key = ftok(getenv("HOME"), 1); 25 | int id = shmget(key, 0, 0); 26 | if (id < 0) error_exit("Cannot access shared memory", "function get_shared_memory"); 27 | return id; 28 | } -------------------------------------------------------------------------------- /cw02/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall -std=c11 -ggdb 2 | 3 | compile: 4 | $(CC) -o program main.c 5 | 6 | clean: 7 | rm -f program wyniki.txt 8 | 9 | test: 10 | make clean 11 | make compile 12 | 13 | #generate and copy 14 | for length in 1 4 512 1024 4096 8192 ; do \ 15 | for numberOfRecords in 1000 5000 10000; do \ 16 | ./program generate dane $$numberOfRecords $$length ;\ 17 | ./program copy dane dane.$$numberOfRecords.$$length.lib $$numberOfRecords $$length lib ;\ 18 | ./program copy dane dane.$$numberOfRecords.$$length.sys $$numberOfRecords $$length sys ;\ 19 | done; \ 20 | done 21 | 22 | #sort 23 | for length in 1 4 512 1024 4096 8192 ; do \ 24 | for numberOfRecords in 1000 5000 10000; do \ 25 | ./program sort dane.$$numberOfRecords.$$length.lib $$numberOfRecords $$length lib ;\ 26 | ./program sort dane.$$numberOfRecords.$$length.sys $$numberOfRecords $$length sys ;\ 27 | done ;\ 28 | done 29 | rm -rf dane* 30 | -------------------------------------------------------------------------------- /cw08/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | compile: 4 | $(CC) -o main main.c -lpthread -lm 5 | 6 | clean: 7 | rm -f main Times.txt 8 | rm -rf results 9 | 10 | test: 11 | make clean 12 | make compile 13 | mkdir results 14 | ./main 1 sign mountain.ascii.pgm results/sign1.txt 15 | ./main 1 block mountain.ascii.pgm results/block1.txt 16 | ./main 1 interleaved mountain.ascii.pgm results/interleaved1.txt 17 | 18 | ./main 2 sign mountain.ascii.pgm results/sign2.txt 19 | ./main 2 block mountain.ascii.pgm results/block2.txt 20 | ./main 2 interleaved mountain.ascii.pgm results/interleaved2.txt 21 | 22 | ./main 4 sign mountain.ascii.pgm results/sign4.txt 23 | ./main 4 block mountain.ascii.pgm results/block4.txt 24 | ./main 4 interleaved mountain.ascii.pgm results/interleaved4.txt 25 | 26 | ./main 8 sign mountain.ascii.pgm results/sign8.txt 27 | ./main 8 block mountain.ascii.pgm results/block8.txt 28 | ./main 8 interleaved mountain.ascii.pgm results/interleaved8.txt -------------------------------------------------------------------------------- /cw01/zad2/j.txt: -------------------------------------------------------------------------------- 1 | windsurfing 2 | windsurfs 3 | windswept 4 | windup 5 | windward 6 | windy 7 | wine 8 | wined 9 | wineglass 10 | wineries 11 | winery 12 | wines 13 | wineskin 14 | wing 15 | winged 16 | winger 17 | wingers 18 | winging 19 | wingless 20 | wings 21 | wingspan 22 | wingspans 23 | winifred 24 | wining 25 | wink 26 | winked 27 | winker 28 | winking 29 | winkle 30 | winkled 31 | winkles 32 | winkling 33 | winks 34 | winnable 35 | winner 36 | winners 37 | winnie 38 | winning 39 | winningly 40 | winnings 41 | winnipeg 42 | winnow 43 | winnowed 44 | winnowing 45 | winnows 46 | wino 47 | winos 48 | wins 49 | winslow 50 | winsome 51 | winsomely 52 | winston 53 | winter 54 | wintered 55 | wintergreen 56 | wintering 57 | winterise 58 | winterised 59 | winterises 60 | winterising 61 | winterize 62 | winterized 63 | winterizes 64 | winterizing 65 | winters 66 | wintertime 67 | wintery 68 | winthrop 69 | wintriness 70 | wintry 71 | wipe 72 | wiped 73 | wiper 74 | wipers 75 | wipes 76 | wiping 77 | wire 78 | -------------------------------------------------------------------------------- /cw05/zad3/consumer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | const int MAX_MSG_LEN = 100; 8 | 9 | int main(int argc, char **argv){ 10 | if (argc != 4){ 11 | printf("Wrong number of arguments. Expected: [pipe's path] [file's path] [number of characters]\n"); 12 | exit(EXIT_FAILURE); 13 | } 14 | 15 | char* pipe_path = argv[1]; 16 | char* file_path = argv[2]; 17 | int N = atoi(argv[3]); 18 | 19 | FILE *pipe = fopen(pipe_path, "r"); 20 | 21 | if (pipe == NULL){ 22 | printf("Cannot open file %s\n", pipe_path); 23 | exit(EXIT_FAILURE); 24 | } 25 | 26 | FILE *file = fopen(file_path, "w"); 27 | 28 | if (file == NULL){ 29 | printf("Cannot open file %s\n", file_path); 30 | fclose(pipe); 31 | exit(EXIT_FAILURE); 32 | } 33 | 34 | char buffer[N]; 35 | 36 | while(fgets(buffer, N, pipe) != NULL){ 37 | fprintf(file, buffer, strlen(buffer)); 38 | } 39 | 40 | fclose(pipe); 41 | fclose(file); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /cw04/zad1/main.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 700 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int stop = 0; 8 | 9 | // SIGINT - CTRL+C 10 | void signalSIGINT(int signum){ 11 | printf("\nOdebrano sygnal SIGINT\n"); 12 | exit(0); 13 | } 14 | 15 | // SIGTSTP - CTRL+Z 16 | void signalSTP(){ 17 | if (stop == 0){ 18 | printf("\nOczekuje na CTRL + Z - kontynuacja albo CTR + C - zakonczenie programu\n"); 19 | } 20 | else{ 21 | printf("\n"); 22 | } 23 | stop = 1 - stop; 24 | } 25 | 26 | int main(){ 27 | // set the disposition of the signal SIGINT to function signalSIGINT() 28 | signal(SIGINT, signalSIGINT); 29 | 30 | // change the action taken by a process on receipt of signal SIGSTP 31 | struct sigaction act; 32 | act.sa_handler = signalSTP; 33 | act.sa_flags = 0; 34 | sigemptyset(&act.sa_mask); // initialize the signal set given by set to empty 35 | sigaction(SIGTSTP, &act, NULL); 36 | 37 | while(1){ 38 | if (stop == 1){ 39 | pause(); // wait for signal 40 | } 41 | system("ls"); 42 | sleep(2); // sleep process 43 | } 44 | 45 | return 0; 46 | } -------------------------------------------------------------------------------- /cw01/zad1/library.h: -------------------------------------------------------------------------------- 1 | #ifndef LAB1_LIBRARY_H 2 | #define LAB1_LIBRARY_H 3 | 4 | 5 | struct Block{ 6 | int numberOfOperations; 7 | char** operations; 8 | }; 9 | 10 | struct MainArray{ 11 | int numberOfBlocks; //number of pairs of files 12 | struct Block ** blocks; 13 | }; 14 | 15 | struct MainArray* createArray(int numberOfBlocks); 16 | 17 | struct Block *createBlock(int numberOfOperations); 18 | 19 | void deleteBlock(struct MainArray* mainArray, int index); 20 | 21 | void deleteOperation(struct MainArray* mainArray, int block_index, int operation_index); 22 | 23 | void deleteArray(struct MainArray* mainArray); 24 | 25 | void compareTwoFiles(char* file1, char*file2); 26 | 27 | int countOperationsInBlock(char *file1, char *file2); 28 | 29 | struct Block* createBlockAndOperations(char *tmp, int numberOfOperations); 30 | 31 | void definePairSequence(char* files, char**newFiles); 32 | 33 | void comparePairs(char *filesInString, struct MainArray *mainArray); 34 | 35 | int countNumberOfFiles(char* filesInString); 36 | 37 | int getNumberOfOperations(struct MainArray* mainArray, int indexOfBlock); 38 | 39 | char* getOperation(struct MainArray* mainArray, int indexOfBlock, int indexOfOperation); 40 | 41 | #endif //LAB1_LIBRARY_H 42 | -------------------------------------------------------------------------------- /cw05/zad3/producer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | const int MAX_MSG_LEN = 100; 8 | 9 | int main(int argc, char **argv){ 10 | if (argc != 4){ 11 | printf("Wrong number of arguments. Expected: [pipe's path] [file's path] [number of characters]\n"); 12 | exit(EXIT_FAILURE); 13 | } 14 | 15 | char* pipe_path = argv[1]; 16 | char* file_path = argv[2]; 17 | int N = atoi(argv[3]); 18 | 19 | srand(time(NULL)); 20 | 21 | FILE *pipe = fopen(pipe_path, "w"); 22 | 23 | if (pipe == NULL){ 24 | printf("Cannot open file %s\n", pipe_path); 25 | exit(EXIT_FAILURE); 26 | } 27 | FILE *file = fopen(file_path, "r"); 28 | 29 | if (file == NULL){ 30 | printf("Cannot open file %s\n", file_path); 31 | fclose(pipe); 32 | exit(EXIT_FAILURE); 33 | } 34 | 35 | char buffer[N]; 36 | 37 | while(fread(buffer, 1, N, file) > 0){ 38 | sleep(rand() % 2 + 1); 39 | char msg [N + 20]; 40 | sprintf(msg, "#%d#%s\n", getpid(), buffer); 41 | fwrite(msg, 1, strlen(msg), pipe); 42 | } 43 | 44 | fclose(pipe); 45 | fclose(file); 46 | return 0; 47 | } -------------------------------------------------------------------------------- /cw07/zad2/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAX_ORDERS 5 14 | #define MIN_SLEEP 100 15 | #define MAX_SLEEP 1000 16 | #define MIN_VAL 1 17 | #define MAX_VAL 100 18 | 19 | #define RECEIVERS 3 20 | #define SENDERS 3 21 | #define PACKERS 3 22 | 23 | #define ALL_WORKERS (RECEIVERS + SENDERS + PACKERS) 24 | 25 | #define SHARED_MEMORY "/SHARED_MEMORY" 26 | 27 | 28 | #define SEMAPHORES_NUMBER 6 29 | 30 | // is array modifying right now by someone 31 | #define FREE_ARRAY 0 32 | // first free index in array 33 | #define FREE_INDEX 1 34 | // first index order to prepare (pack) 35 | #define PACK_INDEX 2 36 | // number of orders to prepare (pack) 37 | #define PACK_NUMBER 3 38 | // first index order to send 39 | #define SEND_INDEX 4 40 | // number of orders to send 41 | #define SEND_NUMBER 5 42 | 43 | extern const char* SEMAPHORES_NAMES[6]; 44 | 45 | typedef struct orders{ 46 | int values[MAX_ORDERS]; 47 | }orders; 48 | 49 | int rand_int(); 50 | int rand_time(); 51 | void error_exit(char *message, char* place); 52 | 53 | #endif //COMMON_H -------------------------------------------------------------------------------- /cw01/zad2/args.txt: -------------------------------------------------------------------------------- 1 | create_table 60 2 | compare_pairs "a.txt:b.txt o.txt:u.txt a.txt:o.txt b.txt:u.txt b.txt:o.txt a.txt:u.txt e.txt:f.txt m.txt:n.txt n.txt:o.txt e.txt:f.txt h.txt:i.txt k.txt:l.txt a.txt:h.txt j.txt:u.txt u.txt:u.txt" 3 | compare_pairs "a.txt:b.txt" 4 | remove_block 0 5 | remove_block 2 6 | compare_pairs "a.txt:b.txt a.txt:a.txt b.txt:b.txt" 7 | remove_operation 3 0 8 | remove_block 5 9 | remove_operation 6 0 10 | compare_pairs "o.txt:a.txt a.txt:u.txt b.txt:m.txt k.txt:k.txt" 11 | remove_operation 7 0 12 | remove_block 1 13 | remove_block 8 14 | compare_pairs "k.txt:l.txt" 15 | remove_operation 4 0 16 | remove_block 4 17 | remove_block 9 18 | compare_pairs "a.txt:b.txt" 19 | compare_pairs "a.txt:b.txt o.txt:u.txt a.txt:o.txt b.txt:u.txt b.txt:o.txt a.txt:u.txt e.txt:f.txt m.txt:n.txt n.txt:o.txt e.txt:f.txt h.txt:i.txt k.txt:l.txt a.txt:h.txt j.txt:u.txt u.txt:u.txt" 20 | remove_block 11 21 | compare_pairs "o.txt:a.txt a.txt:k.txt n.txt:m.txt i.txt:l.txt" 22 | remove_operation 12 0 23 | remove_operation 13 0 24 | remove_block 14 25 | compare_pairs "o.txt:a.txt a.txt:k.txt n.txt:m.txt i.txt:l.txt a.txt:b.txt o.txt:u.txt a.txt:o.txt b.txt:u.txt b.txt:o.txt a.txt:u.txt e.txt:f.txt m.txt:n.txt n.txt:o.txt e.txt:f.txt h.txt:i.txt k.txt:l.txt a.txt:h.txt j.txt:u.txt u.txt:u.txt" 26 | -------------------------------------------------------------------------------- /cw07/zad1/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON2_H 2 | #define COMMON2_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define MAX_ORDERS 5 13 | #define MIN_SLEEP 100 14 | #define MAX_SLEEP 1000 15 | #define MIN_VAL 1 16 | #define MAX_VAL 100 17 | 18 | #define RECEIVERS 3 19 | #define SENDERS 3 20 | #define PACKERS 3 21 | 22 | #define ALL_WORKERS (RECEIVERS + SENDERS + PACKERS) 23 | 24 | // semaphores 25 | 26 | // is array modifying right now by someone 27 | #define FREE_ARRAY 0 28 | // first free index in array 29 | #define FREE_INDEX 1 30 | // first index order to prepare (pack) 31 | #define PACK_INDEX 2 32 | // number of orders to prepare (pack) 33 | #define PACK_NUMBER 3 34 | // first index order to send 35 | #define SEND_INDEX 4 36 | // number of orders to send 37 | #define SEND_NUMBER 5 38 | 39 | // number of semaphores 40 | #define SEMAPHORES 6 41 | 42 | typedef struct orders{ 43 | int values[MAX_ORDERS]; 44 | }orders; 45 | 46 | typedef struct sembuf sembuf; 47 | 48 | union semun { 49 | int val; 50 | struct semid_ds *buf; 51 | unsigned short *array; 52 | struct seminfo *__buf; 53 | }; 54 | 55 | int rand_int(); 56 | int rand_time(); 57 | void error_exit(char *message, char* place); 58 | int get_semaphore_id(); 59 | int get_shared_memory_id(); 60 | 61 | #endif //COMMON2_H -------------------------------------------------------------------------------- /cw01/zad1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "library.h" 5 | #include 6 | 7 | int main(){ 8 | struct MainArray* mainArray = createArray(10); 9 | 10 | comparePairs("a.txt:b.txt c.txt:d.txt e.txt:f.txt", mainArray); 11 | 12 | printf("%d\n\n", mainArray->blocks[0]->numberOfOperations); 13 | printf("%s\n\n", mainArray->blocks[0]->operations[0]); 14 | printf("%s\n\n", mainArray->blocks[0]->operations[1]); 15 | printf("%s\n\n", mainArray->blocks[0]->operations[2]); 16 | printf("%d\n\n", mainArray->blocks[1]->numberOfOperations); 17 | printf("%s\n\n", mainArray->blocks[1]->operations[0]); 18 | printf("%s\n\n", mainArray->blocks[1]->operations[1]); 19 | printf("%s\n\n", mainArray->blocks[1]->operations[2]); 20 | 21 | deleteBlock(mainArray, 0); 22 | if (mainArray -> blocks[0] == NULL) printf("block 0 deleted\n"); 23 | deleteBlock(mainArray, 2); 24 | if (mainArray -> blocks[2] == NULL) printf("block 2 deleted\n"); 25 | 26 | comparePairs("a.txt:c.txt", mainArray); 27 | if (mainArray -> blocks[1] != NULL) printf("block 1\n"); 28 | comparePairs("c.txt:f.txt", mainArray); 29 | if (mainArray -> blocks[2]!= NULL) printf("block 2"); 30 | 31 | deleteBlock(mainArray, 0); 32 | deleteBlock(mainArray, 1); 33 | deleteBlock(mainArray, 2); 34 | deleteArray(mainArray); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /cw01/zad3a/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | LIB_NAME = lib_diff 4 | LIB_PATH = ../zad1 5 | TEST_PATH = ../zad2 6 | TEST_SOURCE_NAME = main.c 7 | REPORT_FILE = raport3a.txt 8 | 9 | static: 10 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -I$(LIB_PATH) $(LIB_PATH)/$(LIB_NAME).a 11 | 12 | shared: 13 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -I$(LIB_PATH) -L$(LIB_PATH) -l_diff 14 | 15 | dynamic_main: main_dyn.c 16 | make shared 17 | $(CC) $(FLAGS) main_dyn.c -ldl -o main_dyn -I . 18 | 19 | clean_all: 20 | make clean 21 | rm -f main 22 | rm -f main_dyn 23 | rm -rf raport3a.txt 24 | 25 | test: 26 | LD_LIBRARY_PATH=$(LIB_PATH) ./main $(shell cat args.txt) 27 | 28 | test_dyn: 29 | LD_LIBRARY_PATH=$(LIB_PATH) ./main_dyn $(shell cat args.txt) 30 | 31 | testStatic: 32 | printf "static:\n" > raport.txt 33 | make static 34 | make test 35 | mv raport.txt $(REPORT_FILE) 36 | 37 | testShared: 38 | printf "shared:\n" >> raport.txt 39 | make shared 40 | make test 41 | mv raport.txt $(REPORT_FILE) 42 | 43 | testDynamic: 44 | printf "dynamic:\n" >> raport.txt 45 | make dynamic_main 46 | make test_dyn 47 | mv raport.txt $(REPORT_FILE) 48 | 49 | test_all: 50 | printf "static:\n" > raport.txt 51 | make static 52 | make test 53 | printf "shared:\n" >> raport.txt 54 | make shared 55 | make test 56 | printf "dynamic:\n" >> raport.txt 57 | make dynamic_main 58 | make test_dyn 59 | mv raport.txt $(REPORT_FILE) 60 | -------------------------------------------------------------------------------- /cw01/zad2/c.txt: -------------------------------------------------------------------------------- 1 | Aarau 2 | AARC 3 | poll 4 | true 5 | aardvark 6 | aardvarks 7 | aardwolf 8 | Aarau 9 | babsbs 10 | cdcdcd 11 | alala 12 | cardiology 13 | unacceptable 14 | rescuers 15 | griped 16 | wedged 17 | false 18 | meditatively 19 | tediousness 20 | adelante 21 | Adelanto 22 | Adelarthra 23 | Adelarthrosomata 24 | elitism 25 | elitist 26 | grandee 27 | housewives 28 | grandees 29 | grander 30 | grandest 31 | grandeur 32 | grandfather 33 | grandfathers 34 | grandiloquence 35 | grandiloquent 36 | grandiloquently 37 | grandiose 38 | grandiosely 39 | grandiosity 40 | grandly 41 | housemasters 42 | salvia 43 | salvias 44 | salving 45 | salvo 46 | salvoes 47 | salvor 48 | salvors 49 | salvos 50 | salzburg 51 | sam 52 | samantha 53 | samara 54 | samaras 55 | samaria 56 | samaritan 57 | houseplants 58 | houses 59 | velte 60 | sw 61 | swab 62 | swabbed 63 | swabbin 64 | tautology 65 | tavern 66 | taverner 67 | taverners 68 | taverns 69 | tavistock 70 | taw 71 | tawdrier 72 | tawdriest 73 | tawdrily 74 | tawdriness 75 | tawdry 76 | tawney 77 | tawnier 78 | tawniest 79 | tawny 80 | taws 81 | unworthiest 82 | unworthiness 83 | unworthy 84 | unwound 85 | unwounded 86 | unwrap 87 | unwrapped 88 | unwrapping 89 | vales 90 | valet 91 | valets 92 | valetta 93 | valetudinarian 94 | valetudinarianism 95 | valetudinarians 96 | valhalla 97 | valiancy 98 | zachary 99 | zagreb 100 | zaire 101 | zairian 102 | zairians 103 | envenoms 104 | enviable 105 | enviably 106 | -------------------------------------------------------------------------------- /cw01/zad2/d.txt: -------------------------------------------------------------------------------- 1 | Aalto 2 | AAM 3 | AAMSI 4 | Aandahl 5 | A-and-R 6 | Aani 7 | AAO 8 | AAP 9 | AAPSS 10 | Aaqbiye 11 | Aar 12 | Aara 13 | Aarau 14 | AARC 15 | unacceptable 16 | aardvark 17 | aardvarks 18 | aardwolf 19 | aardwolves 20 | Aaren 21 | meditatively 22 | tediousness 23 | Aargau 24 | aargh 25 | Aarhus 26 | grandeur 27 | grandfather 28 | Aarika 29 | obscenest 30 | poll 31 | true 32 | intrenched 33 | madness 34 | elisors 35 | elite 36 | elitism 37 | elitist 38 | Aaron 39 | Aaronic 40 | Aaronical 41 | rescuers 42 | Aaronite 43 | Aaronitic 44 | adelante 45 | Adelanto 46 | housemaid 47 | housemaids 48 | houseman 49 | housemaster 50 | housemasters 51 | housemen 52 | housemother 53 | housemothers 54 | houseplant 55 | houseplants 56 | houses 57 | housesteads 58 | salvos 59 | salzburg 60 | housetop 61 | housetops 62 | housetrain 63 | housetrained 64 | housetraining 65 | housetrains 66 | housewife 67 | housewifery 68 | housewives 69 | swab 70 | swabbed 71 | tawnier 72 | tawniest 73 | tawny 74 | unwrap 75 | unwrapped 76 | unwrapping 77 | unwraps 78 | unwrinkled 79 | unwritten 80 | unyielding 81 | unyieldingly 82 | unyoke 83 | unyoked 84 | unyokes 85 | valetudinarianism 86 | valetudinarians 87 | valhalla 88 | valiancy 89 | valiant 90 | valiantly 91 | valid 92 | validate 93 | validated 94 | validates 95 | validating 96 | validation 97 | zagreb 98 | zaire 99 | zairian 100 | zairians 101 | zambezi 102 | zambia 103 | zambian 104 | zambians 105 | zanier 106 | -------------------------------------------------------------------------------- /cw01/zad2/h.txt: -------------------------------------------------------------------------------- 1 | yule 2 | yuletide 3 | yummier 4 | yummiest 5 | yummy 6 | yuppie 7 | yuppies 8 | yvette 9 | yvonne 10 | ywca 11 | z 12 | zabaglione 13 | zabagliones 14 | zachary 15 | zagreb 16 | zaire 17 | zairian 18 | zairians 19 | zambezi 20 | zambia 21 | zambian 22 | zambians 23 | zanier 24 | zanies 25 | zaniest 26 | zany 27 | zanzibar 28 | zap 29 | zapped 30 | zapper 31 | zappers 32 | zapping 33 | zaps 34 | zeal 35 | zealand 36 | zealander 37 | zealanders 38 | zealot 39 | zealotry 40 | zealots 41 | zealous 42 | zealously 43 | zealousness 44 | zebra 45 | zebras 46 | zebrine 47 | zebu 48 | zebus 49 | zechariah 50 | zed 51 | zeds 52 | zee 53 | zeebrugge 54 | zees 55 | zeffirelli 56 | zeiss 57 | zeitgeist 58 | zen 59 | zenith 60 | zeniths 61 | zephaniah 62 | zephyr 63 | zephyrs 64 | zeppelin 65 | zeppelins 66 | zermatt 67 | zero 68 | zeroed 69 | zeroes 70 | zeroing 71 | zeros 72 | zest 73 | zestful 74 | zestfully 75 | zesty 76 | zetland 77 | zeugma 78 | zeugmas 79 | zeus 80 | zibeline 81 | zibelines 82 | ziggurat 83 | ziggurats 84 | zigzag 85 | zigzagged 86 | zigzagging 87 | zigzags 88 | zilch 89 | zilches 90 | zillion 91 | zillions 92 | zillionth 93 | zillionths 94 | zimbabwe 95 | zimbabwean 96 | zimbabweans 97 | zimmer 98 | zimmerman 99 | zinc 100 | zinfandel 101 | zing 102 | zing 103 | zinged 104 | zinger 105 | aaa 106 | bbb ccc 107 | ddd 108 | eee 109 | hhh iii 110 | zinged 111 | zinger 112 | zingers 113 | zinging 114 | zings 115 | zinnia 116 | zinnias 117 | -------------------------------------------------------------------------------- /cw01/zad2/g.txt: -------------------------------------------------------------------------------- 1 | yule 2 | yuletide 3 | yummier 4 | yummiest 5 | yummy 6 | yuppie 7 | yuppies 8 | yvette 9 | yvonne 10 | ywca 11 | z 12 | zabaglione 13 | zabagliones 14 | zachary 15 | zagreb 16 | zaire 17 | zairian 18 | zairians 19 | zambezi 20 | zambia 21 | zambian 22 | zambians 23 | zanier 24 | zanies 25 | zaniest 26 | zany 27 | zanzibar 28 | zap 29 | zapped 30 | zapper 31 | zappers 32 | zapping 33 | zaps 34 | zeal 35 | zealand 36 | zealander 37 | zealanders 38 | zealot 39 | zealotry 40 | zealots 41 | zealous 42 | zealously 43 | zealousness 44 | zebra 45 | zebras 46 | zebrine 47 | zebu 48 | zebus 49 | zechariah 50 | zed 51 | zeds 52 | zee 53 | zeebrugge 54 | zees 55 | zeffirelli 56 | zeiss 57 | zeitgeist 58 | zen 59 | zenith 60 | zeniths 61 | zephaniah 62 | zephyr 63 | zephyrs 64 | zeppelin 65 | zeppelins 66 | zermatt 67 | zero 68 | zeroed 69 | zeroes 70 | zeroing 71 | zeros 72 | zest 73 | zestful 74 | zestfully 75 | zesty 76 | zetland 77 | zeugma 78 | zeugmas 79 | zeus 80 | zibeline 81 | zibelines 82 | ziggurat 83 | ziggurats 84 | zigzag 85 | zigzagged 86 | zigzagging 87 | zigzags 88 | zilch 89 | zilches 90 | zillion 91 | zillions 92 | zillionth 93 | zillionths 94 | zimbabwe 95 | zimbabwean 96 | zimbabweans 97 | zimmer 98 | zimmerman 99 | zinc 100 | zinfandel 101 | zing 102 | zinged 103 | zinger 104 | aaa 105 | bbb ccc 106 | ddd 107 | eee 108 | hhh iii 109 | xxx 110 | uiop 111 | asd 112 | wdi 113 | zingers 114 | zinging 115 | zings 116 | zinnia 117 | zinnias 118 | -------------------------------------------------------------------------------- /cw01/zad2/m.txt: -------------------------------------------------------------------------------- 1 | investigation 2 | investigations 3 | investigative 4 | investigator 5 | hypersonically 6 | hypertension 7 | hypertext 8 | hyperthermia 9 | hyperthyroid 10 | hyperthyroidism 11 | hypertrophied 12 | hypertrophies 13 | hypertrophy 14 | investigators 15 | coevals 16 | coexist 17 | coexisted 18 | investigatory 19 | blasphemes 20 | blasphemies 21 | blaspheming 22 | blasphemous 23 | blasphemously 24 | blasphemy 25 | blast 26 | blasted 27 | blaster 28 | blasting 29 | blastoffs 30 | blasts 31 | blastula 32 | blastulas 33 | blatancy 34 | blatant 35 | birdseeds 36 | birdsong 37 | birdying 38 | birefringence 39 | birkenhead 40 | birmingham 41 | biro 42 | biros 43 | birth 44 | birthday 45 | birthdays 46 | abactor 47 | abactors 48 | abacus 49 | abacuses 50 | abaft 51 | abalone 52 | abandon 53 | abandoned 54 | abandonee 55 | abandonees 56 | abandoning 57 | abandonment 58 | abandons 59 | birdseed 60 | birdseeds 61 | birdsong 62 | birdying 63 | birefringence 64 | birkenhead 65 | birches 66 | ziggurat 67 | ziggurats 68 | zigzag 69 | zigzagged 70 | zigzagging 71 | zigzags 72 | zilch 73 | zilches 74 | zillion 75 | zillions 76 | zillionth 77 | zillionths 78 | zimbabwe 79 | zimbabwean 80 | zimbabweans 81 | zimmer 82 | zimmerman 83 | zinc 84 | zinfandel 85 | zing 86 | zinged 87 | zinger 88 | aaa 89 | bbb ccc 90 | ddd 91 | eee 92 | hhh iii 93 | xxx 94 | uiop 95 | asd 96 | wdi 97 | zingers 98 | zinging 99 | zings 100 | bird 101 | birdbath 102 | birdbaths 103 | birdbrain 104 | biomedicine 105 | biomes 106 | biometric 107 | binder 108 | binderies 109 | binders 110 | bindery 111 | binding 112 | bindings 113 | bindle 114 | -------------------------------------------------------------------------------- /cw04/zad3/main.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 700 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void childHandle(int sig, siginfo_t *info, void *uncontex){ 11 | printf("\nChild has finished execution\n"); 12 | printf("Signal number: %d\n", info -> si_signo); 13 | printf("Child exit value: %d\n", info -> si_status); 14 | printf("Sending PID: %d\n\n", info -> si_pid); 15 | } 16 | 17 | void segFaultHandle(int sig, siginfo_t *info, void *uncontex){ 18 | printf("\nSegmentation fault occured\n"); 19 | printf("Signal number: %d\n", info -> si_signo); 20 | printf("Sending PID: %d\n", info -> si_pid); 21 | printf("Fault address: %p\n\n", info -> si_addr); 22 | exit(0); 23 | } 24 | 25 | void statusHandle(int sig, siginfo_t *info, void *uncontex){ 26 | printf("\n\nSignal number: %d\n", info -> si_signo); 27 | printf("Sending PID: %d\n", info ->si_pid); 28 | if (info -> si_code == SI_KERNEL){ 29 | printf("Send by KERNEL\n\n"); 30 | } 31 | else if (info -> si_code == SI_USER){ 32 | printf("Send by USER\n\n"); 33 | } 34 | } 35 | 36 | int main(int argc, char **argv){ 37 | if (argc != 2){ 38 | printf("Wrong number of arguments. Expected: ./main [child / segFault / status]"); 39 | exit(EXIT_FAILURE); 40 | } 41 | 42 | struct sigaction act; 43 | sigemptyset(&act.sa_mask); 44 | act.sa_flags = SA_SIGINFO; 45 | 46 | if (!strcmp("child", argv[1])){ 47 | act.sa_sigaction = childHandle; 48 | sigaction(SIGCHLD, &act, NULL); 49 | pid_t childPid = fork(); 50 | 51 | if (childPid == 0){ 52 | exit(123); 53 | } 54 | wait(NULL); 55 | } 56 | else if (!strcmp("segFault", argv[1])){ 57 | act.sa_sigaction = segFaultHandle; 58 | sigaction(SIGSEGV, &act, NULL); 59 | 60 | char *a = NULL; 61 | a[10] = 'a'; 62 | } 63 | else if (!strcmp("status", argv[1])){ 64 | act.sa_sigaction = statusHandle; 65 | sigaction(SIGINT, &act, NULL); 66 | pause(); 67 | } 68 | 69 | return 0; 70 | } -------------------------------------------------------------------------------- /cw05/zad3/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | void generate_files(){ 12 | char file_name[100]; 13 | char number[2]; 14 | 15 | for (int i = 0; i < 5; i++){ 16 | strcpy(file_name, "files/file"); 17 | sprintf(number, "%d", i); 18 | strcat(file_name, number); 19 | FILE *f = fopen(file_name, "w+"); 20 | 21 | for (int j = 0; j < 10; j++){ 22 | char c = 'A' + i; 23 | fwrite(&c, 1, 1, f); 24 | } 25 | fclose(f); 26 | } 27 | } 28 | 29 | int main(int argc, char **argv){ 30 | 31 | pid_t pids[6]; 32 | 33 | if (mkfifo("pipe", 0666) < 0){ 34 | printf("Cannot create named pipe.\n"); 35 | exit(EXIT_FAILURE); 36 | } 37 | 38 | generate_files(); 39 | 40 | char* consumer [] = {"./consumer", "pipe", "./files/results", "10", NULL}; 41 | char* producer0 [] = {"./producer", "pipe", "./files/file0", "5", NULL}; 42 | char* producer1 [] = {"./producer", "pipe", "./files/file1", "5", NULL}; 43 | char* producer2 [] = {"./producer", "pipe", "./files/file2", "5", NULL}; 44 | char* producer3 [] = {"./producer", "pipe", "./files/file3", "5", NULL}; 45 | char* producer4 [] = {"./producer", "pipe", "./files/file4", "5", NULL}; 46 | 47 | 48 | pids[0]=fork(); 49 | if (pids[0] == 0){ 50 | execvp(producer0[0], producer0); 51 | } 52 | 53 | pids[1] = fork(); 54 | if (pids[1] == 0){ 55 | execvp(producer1[0], producer1); 56 | } 57 | 58 | pids[2] = fork(); 59 | if (pids[2] == 0){ 60 | execvp(producer2[0], producer2); 61 | } 62 | 63 | pids[3] = fork(); 64 | if (pids[3] == 0){ 65 | execvp(producer3[0], producer3); 66 | } 67 | 68 | pids[4] = fork(); 69 | if (pids[4] == 0){ 70 | execvp(producer4[0], producer4); 71 | } 72 | 73 | pids[5] = fork(); 74 | if (pids[5] == 0){ 75 | execvp(consumer[0], consumer); 76 | } 77 | 78 | for (int i = 0; i < 6; i++){ 79 | waitpid(pids[i], NULL, 0); 80 | } 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /cw09/README.md: -------------------------------------------------------------------------------- 1 | # Opis problemu: 2 | ## W ramach zadania należy zaimplementować rozwiązanie problemu śpiącego golibrody. 3 | 4 | Salon składa się z gabinetu oraz poczekalni. W gabinecie znajduje się jedno krzesło dla aktualnie obsługiwanego klienta. W poczekalni znajduje się określona liczba krzeseł (K) dla oczekujących. 5 | 6 | ### Zachowania golibrody: 7 | 8 | * Gdy kończy golić brodę klienta, pozwala mu opuścić gabinet, po czym idzie do poczekalni sprawdzić, czy jakiś klient tam czeka: 9 | - Jeśli tak, przyprowadza go do gabinetu, sadza na krześle i goli jego brodę. (Komunikat: Golibroda: czeka ___ klientow, gole klienta ID) 10 | - Jeśli nie, to idzie spać. (Komunikat: Golibroda: ide spac) 11 | 12 | ### Zachowanie klientów: 13 | 14 | * Jeśli przyszedł do salonu, golibroda jest zajęty oraz wszystkie krzesła w poczekalni są zajęte to wychodzi. (Komunikat: Zajete; ID) 15 | * Jeśli przyszedł do salonu i golibroda jest zajęty, ale są wolne miejsca w poczekalni to zajmuje jedno z krzeseł. (Komunikat: Poczekalnia, wolne miejsca: ___; ID) 16 | * Jeśli przyszedł do salonu i golibroda śpi to go budzi i zajmuje krzesło w gabinecie. (Komunikat: Budze golibrode; ID) 17 | 18 | Należy zaimplementować program, w którym golibroda oraz klienci to osobne wątki. Powinny one podczas działania wypisywać komunikaty o podejmowanych akcjach. Użycie odpowiednich mechanizmów ma zagwarantować niedopouszczenie, np. do zdarzeń: 19 | 20 | * W których dwóch klientów zajmuje jedno krzesło w poczekalni. 21 | * Golibroda śpi, choć jest klient w poczekalni. 22 | 23 | Golenie brody przez golibrode powinno zajmować mu losową liczbę sekund. Do spania golibrody powinny być wykorzystane Warunki Sprawdzające (Condition Variables). 24 | 25 | Gdy klient wychodzi z salonu z powodu braku miejsca w poczekalni, powinien odczekać losową liczbe sekund i spróbować wejść jeszcze raz. 26 | 27 | Program należy zaimplementować korzystając z wątków i mechanizmów synchronizacji biblioteki POSIX Threads. Argumentami wywołania programu są: liczba krzeseł K i liczba klientów N. Po uruchomieniu programu wątek główny tworzy wątki dla golibrody i dla klientów (dla klientów wątki powinny być tworzone z losowym opóźnieniem). Należy doprowadzić do sytuacji w której wszystkie krzesła w poczekalni są zajęte. -------------------------------------------------------------------------------- /cw10/README.md: -------------------------------------------------------------------------------- 1 | # Sockety 2 | 3 | Celem zadania jest napisanie prostego systemu pozwalającego na granie w kółko i krzyżyk w architekturze klient/serwer. 4 | 5 | Serwer nasłuchuje jednocześnie na gnieździe sieciowym i gnieździe lokalnym. 6 | Klienci po uruchomieniu przesyłają do serwera swoją nazwę, a ten sprawdza czy klient o takiej nazwie już istnieje - jeśli tak, to odsyła klientowi komunikat że nazwa jest już w użyciu; jeśli nie, to zapamiętuje klienta. 7 | Serwer ma za zadanie łączyć klientów w pary - w przypadku pierwszego klienta wysyła mu informacje o tym, że oczekuje na drugiego klienta. Gdy drugi klient dołączy się do serwera informuje ich o połączeniu w parę, losuje zaczynającego gracza i wysyła do nich pustą planszę wraz z informacją o przydzielonym znaku (X/O). 8 | Klienci następnie na zmianę wykonują ruchy aż do wygranej lub remisu - wybór pól może być wykonany poprzez ich numeracje (1-9). Wiadomości o ruchach powinny być wysyłane do serwera, który je przekaże drugiemu klientowi. Po zakończonej rozgrywce klient powinien wyrejestrować się z serwera. 9 | 10 | Serwer przyjmuje jako swoje argumenty: 11 | 12 | - numer portu TCP/UDP (zależnie od zadania) 13 | - ścieżkę gniazda UNIX 14 | 15 | Wątek obsługujący sieć powinien obsługiwać gniazdo sieciowe i gniazdo lokalne jednocześnie, wykorzystując w tym celu funkcje do monitorowania wielu deskryptorów (epoll/poll/select). 16 | Dodatkowo, osobny wątek powinien cyklicznie "pingować" zarejestrowanych klientów, aby zweryfikować że wciąż odpowiadają na żądania i jeśli nie - usuwać ich z listy klientów. 17 | Można przyjąć, że ilość klientów zarejestrowanych na serwerze jest ograniczona do maksymalnie kilkunastu. 18 | 19 | 20 | Klient przyjmuje jako swoje argumenty: 21 | 22 | - swoją nazwę (string o z góry ograniczonej długości) 23 | - sposób połączenia z serwerem (sieć lub komunikacja lokalna przez gniazda UNIX) 24 | - adres serwera (adres IPv4 i numer portu lub ścieżkę do gniazda UNIX serwera) 25 | 26 | Klient przy wyłączeniu Ctrl+C powinien wyrejestrować się z serwera. 27 | 28 | 29 | ## Zadanie 1 (50%) 30 | Komunikacja klientów i serwera odbywa się z użyciem protokołu strumieniowego. 31 | 32 | ## Zadanie 2 (50%) 33 | Komunikacja klientów i serwera odbywa się z użyciem protokołu datagramowego. -------------------------------------------------------------------------------- /cw07/README.md: -------------------------------------------------------------------------------- 1 | # IPC - pamięć wspólna, semafory 2 | ## Zadanie 3 | 4 | Wykorzystując semafory i pamięć wspólną z IPC Systemu V napisz program symulujący działanie sklepu wysyłkowego. 5 | W sklepie wysyłkowym pracują 3 typy pracowników: 6 | 1) odbierający zamówienie oraz przygotowujący odpowiednie paczki 7 | 2) pakujący zamówienie do paczki 8 | 3) zaklejający paczki oraz wysyłający je kurierem 9 | 10 | Po uruchomieniu, pracownik 1) cyklicznie odbiera zamównienia - losuje dodatnią liczbę całkowitą (wielkość zamówienia/paczki) i umieszcza ją w tablicy przechowywanej w pamięci wspólnej. Po odebraniu nowego zamównienia pracownik 1) wypisuje na ekranie komunikat postaci: 11 | 12 | (pid timestamp) Dodałem liczbę : n. Liczba zamównień do przygotowania: m. Liczba zamównień do wysłania: x. 13 | 14 | gdzie pid to PID procesu pracownika 1), timestamp to aktualny czas (z dokładnością do milisekund), n to wylosowana liczba (wielkość zamówienia), m to liczba zamównień do przygotowania w pamięci wspólnej (licząc z utworzonym zamówieniem), a x to liczba zamównień do wysłania w pamięci wspólnej. 15 | 16 | Po pobraniu zamówienia pracownik 2) pomnaża liczbę przez 2 i wypisuje na ekranie komunikat: 17 | 18 | (pid timestamp) Przygotowałem zamówienie o wielkości n. Liczba zamównień do przygotowania: m. Liczba zamównień do wysłania: x. 19 | 20 | gdzie n to liczba pomnożona przez 2, a m jest bez aktualnie przygotowanego. 21 | 22 | Po pobraniu przygotowanego zamówienia pracownik 3) pomnaża liczbę przez 3 i wypisuje na ekranie komunikat: 23 | 24 | (pid timestamp) Wysłałem zamówienie o wielkości n. Liczba zamównień do przygotowania: m. Liczba zamównień do wysłania: x. 25 | 26 | gdzie n to liczba pomnożona przez 3, a x jest bez aktualnie wysłanego. 27 | 28 | Zakładamy, że równocześnie pracuje wielu pracowników 1), 2) i 3). Rozmiar tablicy z zamówieniami (w pamięci wspólnej) jest ograniczony i ustalony na etapie kompilacji. Tablica ta indeksowana jest w sposób cykliczny - po dodaniu zamówienia na końcu tablicy, kolejne zamówienia dodawane są od indeksu 0. Korzystając w odpowiedni sposób z semaforów należy zagwarantować, że liczba oczekujących zamówień nie przekroczy rozmiaru tablicy oraz że tablica nie będzie modyfikowana przez kilka procesów równocześnie. Rozmiar tablicy zamówień dobierz tak, aby mogła zajść sytuacja, w której tablica jest całkowicie zapełniona. W pamięci wspólnej oprócz tablicy można przechowywać także inne dane dzielone pomiędzy procesami. 29 | Kolejni pracownicy są uruchamiani w pętli przez jeden proces macierzysty (za pomocą funkcji fork oraz exec). 30 | 31 | Zrealizuj powyższy problem synchronizacyjny , wykorzystując mechanizmy synchronizacji procesów oraz pamięć współdzieloną ze standardu: 32 | 33 | ## 1. IPC - System V (50%) 34 | ## 2. IPC - Posix (50%) -------------------------------------------------------------------------------- /cw01/zad2/raport2.txt: -------------------------------------------------------------------------------- 1 | Operation: compare_pairs 2 | Real time: 0.180000 3 | User time: 0.000000 4 | System time: 0.000000 5 | 6 | Operation: compare_pairs 7 | Real time: 0.020000 8 | User time: 0.000000 9 | System time: 0.000000 10 | 11 | Operation: remove_block 12 | Real time: 0.000000 13 | User time: 0.000000 14 | System time: 0.000000 15 | 16 | Operation: remove_block 17 | Real time: 0.000000 18 | User time: 0.000000 19 | System time: 0.000000 20 | 21 | Operation: compare_pairs 22 | Real time: 0.030000 23 | User time: 0.000000 24 | System time: 0.000000 25 | 26 | Operation: remove_operation 27 | Real time: 0.000000 28 | User time: 0.000000 29 | System time: 0.000000 30 | 31 | Operation: remove_block 32 | Real time: 0.000000 33 | User time: 0.000000 34 | System time: 0.000000 35 | 36 | Operation: remove_operation 37 | Real time: 0.000000 38 | User time: 0.000000 39 | System time: 0.000000 40 | 41 | Operation: compare_pairs 42 | Real time: 0.050000 43 | User time: 0.000000 44 | System time: 0.000000 45 | 46 | Operation: remove_operation 47 | Real time: 0.000000 48 | User time: 0.000000 49 | System time: 0.000000 50 | 51 | Operation: remove_block 52 | Real time: 0.000000 53 | User time: 0.000000 54 | System time: 0.000000 55 | 56 | Operation: remove_block 57 | Real time: 0.000000 58 | User time: 0.000000 59 | System time: 0.000000 60 | 61 | Operation: compare_pairs 62 | Real time: 0.010000 63 | User time: 0.000000 64 | System time: 0.000000 65 | 66 | Operation: remove_operation 67 | Real time: 0.000000 68 | User time: 0.000000 69 | System time: 0.000000 70 | 71 | Operation: remove_block 72 | Real time: 0.000000 73 | User time: 0.000000 74 | System time: 0.000000 75 | 76 | Operation: remove_block 77 | Real time: 0.000000 78 | User time: 0.000000 79 | System time: 0.000000 80 | 81 | Operation: compare_pairs 82 | Real time: 0.010000 83 | User time: 0.000000 84 | System time: 0.000000 85 | 86 | Operation: compare_pairs 87 | Real time: 0.180000 88 | User time: 0.000000 89 | System time: 0.000000 90 | 91 | Operation: remove_block 92 | Real time: 0.000000 93 | User time: 0.000000 94 | System time: 0.000000 95 | 96 | Operation: compare_pairs 97 | Real time: 0.050000 98 | User time: 0.000000 99 | System time: 0.010000 100 | 101 | Operation: remove_operation 102 | Real time: 0.000000 103 | User time: 0.000000 104 | System time: 0.000000 105 | 106 | Operation: remove_operation 107 | Real time: 0.000000 108 | User time: 0.000000 109 | System time: 0.000000 110 | 111 | Operation: remove_block 112 | Real time: 0.000000 113 | User time: 0.000000 114 | System time: 0.000000 115 | 116 | Operation: compare_pairs 117 | Real time: 0.260000 118 | User time: 0.000000 119 | System time: 0.000000 120 | -------------------------------------------------------------------------------- /cw07/zad2/receiver.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "common.h" 16 | 17 | sem_t * semaphores[SEMAPHORES_NUMBER]; 18 | int shared_memory_descriptor; 19 | const char* SEMAPHORES_NAMES[6] = {"/FREE_ARRAY", "/FREE_INDEX", "/PACK_INDEX", "/PACK_NUMBER", "/SEND_INDEX", "/SEND_NUMBER"}; 20 | 21 | void sigint_handle(int signum){ 22 | for (int i = 0; i < SEMAPHORES_NUMBER; i ++){ 23 | if (sem_close(semaphores[i]) < 0) { 24 | error_exit("Cannot close semaphore", "receiver"); 25 | } 26 | } 27 | exit(EXIT_SUCCESS); 28 | } 29 | 30 | int get_value(int index){ 31 | int val; 32 | sem_getvalue(semaphores[index], &val); 33 | return val; 34 | } 35 | 36 | void add_order(){ 37 | sem_wait(semaphores[FREE_ARRAY]); 38 | sem_post(semaphores[FREE_INDEX]); 39 | 40 | orders* orders = mmap(NULL, sizeof(orders), PROT_READ | PROT_WRITE, MAP_SHARED, shared_memory_descriptor, 0); 41 | if (orders == (void *) -1) error_exit("Cannot map shared memory", "function add_order (receiver)"); 42 | 43 | 44 | int index = (get_value(1) - 1) % MAX_ORDERS; 45 | orders -> values[index] = rand_int(); 46 | 47 | int orders_to_send = get_value(SEND_NUMBER); 48 | int orders_to_prepare = get_value(PACK_NUMBER) + 1; 49 | 50 | printf("[%d %ld] RECEIVER: Received number: %d. Number of orders to prepare: %d. Number of orders to send: %d.\n", 51 | getpid(), time(NULL), orders -> values[index], orders_to_prepare, orders_to_send); 52 | 53 | if (munmap(orders, sizeof(orders)) < 0) error_exit("Cannot unmap shared memory", "function add_order (receiver)"); 54 | 55 | sem_post(semaphores[FREE_ARRAY]); 56 | sem_post(semaphores[PACK_NUMBER]); 57 | } 58 | 59 | int main(){ 60 | srand(time(NULL)); 61 | 62 | signal(SIGINT, sigint_handle); 63 | 64 | // init semaphores 65 | for (int i = 0; i < SEMAPHORES_NUMBER; i ++){ 66 | semaphores[i] = sem_open(SEMAPHORES_NAMES[i], O_RDWR); 67 | if (semaphores[i] < 0) error_exit("Cannot access semaphore", "receiver"); 68 | } 69 | 70 | // init shared memory 71 | shared_memory_descriptor = shm_open(SHARED_MEMORY, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); 72 | if (shared_memory_descriptor < 0) error_exit("Cannot access shared memory", "receiver"); 73 | 74 | while(1){ 75 | usleep(rand_time()); 76 | if (get_value(PACK_NUMBER) + get_value(SEND_NUMBER) < MAX_ORDERS){ 77 | add_order(); 78 | } 79 | } 80 | return 0; 81 | } -------------------------------------------------------------------------------- /cw07/zad2/packer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "common.h" 16 | 17 | sem_t* semaphores[SEMAPHORES_NUMBER]; 18 | int shared_memory_descriptor; 19 | const char* SEMAPHORES_NAMES[6] = {"/FREE_ARRAY", "/FREE_INDEX", "/PACK_INDEX", "/PACK_NUMBER", "/SEND_INDEX", "/SEND_NUMBER"}; 20 | 21 | void sigint_handle(int signum){ 22 | for (int i = 0; i < SEMAPHORES_NUMBER; i ++){ 23 | if (sem_close(semaphores[i]) < 0) { 24 | error_exit("Cannot close semaphore", "packer"); 25 | } 26 | } 27 | exit(EXIT_SUCCESS); 28 | } 29 | 30 | int get_value(int index){ 31 | int val; 32 | sem_getvalue(semaphores[index], &val); 33 | return val; 34 | } 35 | 36 | void pack_order(){ 37 | sem_wait(semaphores[FREE_ARRAY]); 38 | sem_post(semaphores[PACK_INDEX]); 39 | sem_wait(semaphores[PACK_NUMBER]); 40 | 41 | orders *orders = mmap(NULL, sizeof(orders), PROT_READ | PROT_WRITE, MAP_SHARED, shared_memory_descriptor, 0); 42 | if (orders == (void*) -1) error_exit("Cannot map shared memory", "function pack_order (packer)"); 43 | 44 | int index = (get_value(PACK_INDEX) - 1) % MAX_ORDERS; 45 | orders -> values[index] *= 2; 46 | 47 | int orders_to_send = get_value(SEND_NUMBER) + 1; 48 | int orders_to_prepare = get_value(PACK_NUMBER); 49 | 50 | printf("[%d %ld] PACKER: Prepared order at size: %d. Number of orders to prepare: %d. Number of orders to send: %d.\n", 51 | getpid(), time(NULL), orders -> values[index], orders_to_prepare, orders_to_send); 52 | 53 | if (munmap(orders, sizeof(orders)) < 0) error_exit("Cannot unmap shared memory", "function pack_order (packer)"); 54 | 55 | sem_post(semaphores[FREE_ARRAY]); 56 | sem_post(semaphores[SEND_NUMBER]); 57 | 58 | } 59 | 60 | int main(){ 61 | srand(time(NULL)); 62 | 63 | signal(SIGINT, sigint_handle); 64 | 65 | // init semaphores 66 | for (int i = 0; i < SEMAPHORES_NUMBER; i ++){ 67 | semaphores[i] = sem_open(SEMAPHORES_NAMES[i], O_RDWR); 68 | if (semaphores[i] < 0) error_exit("Cannot access semaphore", "packer"); 69 | } 70 | 71 | // init shared memory 72 | shared_memory_descriptor = shm_open(SHARED_MEMORY, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); 73 | if (shared_memory_descriptor < 0) error_exit("Cannot access shared memory", "packer"); 74 | 75 | while(1){ 76 | usleep(rand_time()); 77 | if (get_value(PACK_NUMBER) > 0){ 78 | pack_order(); 79 | } 80 | } 81 | return 0; 82 | } -------------------------------------------------------------------------------- /cw07/zad2/sender.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "common.h" 16 | 17 | sem_t* semaphores[SEMAPHORES_NUMBER]; 18 | int shared_memory_descriptor; 19 | const char* SEMAPHORES_NAMES[6] = {"/FREE_ARRAY", "/FREE_INDEX", "/PACK_INDEX", "/PACK_NUMBER", "/SEND_INDEX", "/SEND_NUMBER"}; 20 | 21 | void sigint_handle(int signum){ 22 | for (int i = 0; i < SEMAPHORES_NUMBER; i ++){ 23 | if (sem_close(semaphores[i]) < 0) { 24 | error_exit("Cannot close semaphore", "receiver"); 25 | } 26 | } 27 | exit(EXIT_SUCCESS); 28 | } 29 | 30 | int get_value(int index){ 31 | int val; 32 | sem_getvalue(semaphores[index], &val); 33 | return val; 34 | } 35 | 36 | void send_order(){ 37 | sem_wait(semaphores[FREE_ARRAY]); 38 | sem_post(semaphores[SEND_INDEX]); 39 | sem_wait(semaphores[SEND_NUMBER]); 40 | 41 | orders *orders = mmap(NULL, sizeof(orders), PROT_READ | PROT_WRITE, MAP_SHARED, shared_memory_descriptor, 0); 42 | if (orders == (void*) -1) error_exit("Cannot map shared memory", "function send_order (sender)"); 43 | 44 | int index = (get_value(SEND_INDEX) - 1) % MAX_ORDERS; 45 | orders -> values[index] *= 3; 46 | 47 | int orders_to_send = get_value(SEND_NUMBER); 48 | int orders_to_prepare = get_value(PACK_NUMBER); 49 | 50 | 51 | printf("[%d %ld] SENDER: Send order at size: %d. Number of orders to prepare: %d. Number of orders to send: %d.\n", 52 | getpid(), time(NULL), orders -> values[index], orders_to_prepare, orders_to_send); 53 | 54 | orders -> values[index] = 0; 55 | 56 | if (munmap(orders, sizeof(orders)) < 0) error_exit("Cannot unmap shared memory", "function send_order (sender)"); 57 | sem_post(semaphores[FREE_ARRAY]); 58 | 59 | } 60 | 61 | int main(){ 62 | srand(time(NULL)); 63 | 64 | signal(SIGINT, sigint_handle); 65 | 66 | // init semaphores 67 | for (int i = 0; i < SEMAPHORES_NUMBER; i ++){ 68 | semaphores[i] = sem_open(SEMAPHORES_NAMES[i], O_RDWR); 69 | if (semaphores[i] < 0) error_exit("Cannot access semaphore", "sender"); 70 | } 71 | 72 | // init shared memory 73 | shared_memory_descriptor = shm_open(SHARED_MEMORY, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); 74 | if (shared_memory_descriptor < 0) error_exit("Cannot access shared memory", "sender"); 75 | 76 | while(1){ 77 | usleep(rand_time()); 78 | if (get_value(SEND_NUMBER) > 0){ 79 | send_order(); 80 | } 81 | } 82 | return 0; 83 | } -------------------------------------------------------------------------------- /cw01/zad2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "library.h" 9 | 10 | clock_t startTime, endTime; 11 | struct tms startCpu, endCpu; 12 | 13 | FILE *resultFile; 14 | 15 | void startTimer(){ 16 | startTime = times(&startCpu); 17 | } 18 | void endTimer(){ 19 | endTime = times(&endCpu); 20 | } 21 | 22 | void writeResultToFile(FILE* file, char* name){ 23 | endTimer(); 24 | double realTime = (double) (endTime - startTime) / sysconf(_SC_CLK_TCK); 25 | double userTime = (double) (endCpu.tms_utime - startCpu.tms_utime) / sysconf(_SC_CLK_TCK); 26 | double systemTime = (double)(endCpu.tms_stime - startCpu.tms_stime) / sysconf(_SC_CLK_TCK); 27 | fprintf(file, "Operation: %s\n", name); 28 | fprintf(file, "Real time: %f\n", realTime); 29 | fprintf(file, "User time: %f\n", userTime); 30 | fprintf(file, "System time: %f\n\n", systemTime); 31 | 32 | printf("Operation: %s\n", name); 33 | printf("Real time: %f\n", realTime); 34 | printf("User time: %f\n", userTime); 35 | printf("System time: %f\n\n", systemTime); 36 | } 37 | 38 | 39 | 40 | int main(int argc, char**argv) { 41 | if (argc < 3){ 42 | printf("Number of argument must be at least 3"); 43 | return -1; 44 | } 45 | if(strcmp(argv[1], "create_table") !=0 ){ 46 | printf("First argument has to be create_table"); 47 | return -1; 48 | } 49 | 50 | resultFile = fopen("raport.txt", "a"); 51 | 52 | int numberOfBlocks = atoi(argv[2]); 53 | struct MainArray* mainArray = createArray(numberOfBlocks); 54 | int i = 3; 55 | char* operation; 56 | while (i < argc){ 57 | startTimer(); 58 | 59 | if (!strcmp(argv[i], "compare_pairs")){ 60 | comparePairs(argv[i+1], mainArray); 61 | i += 2; 62 | operation = "compare_pairs"; 63 | } 64 | else if (!strcmp(argv[i], "remove_operation")){ 65 | int indexOfBlock = atoi(argv[i + 1]); 66 | int indexOfOperation = atoi(argv[i + 2]); 67 | deleteOperation(mainArray, indexOfBlock, indexOfOperation); 68 | i += 3; 69 | operation = "remove_operation"; 70 | } 71 | else if (!strcmp(argv[i], "remove_block")){ 72 | int indexOfBlock = atoi(argv[i + 1]); 73 | deleteBlock(mainArray, indexOfBlock); 74 | i += 2; 75 | operation = "remove_block"; 76 | } 77 | else{ 78 | operation = "wrong operation"; 79 | i ++; 80 | } 81 | writeResultToFile(resultFile, operation); 82 | } 83 | deleteArray(mainArray); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /cw01/zad3a/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "library.h" 9 | 10 | clock_t startTime, endTime; 11 | struct tms startCpu, endCpu; 12 | 13 | FILE *resultFile; 14 | 15 | void startTimer(){ 16 | startTime = times(&startCpu); 17 | } 18 | void endTimer(){ 19 | endTime = times(&endCpu); 20 | } 21 | 22 | void writeResultToFile(FILE* file, char* name){ 23 | endTimer(); 24 | double realTime = (double) (endTime - startTime) / sysconf(_SC_CLK_TCK); 25 | double userTime = (double) (endCpu.tms_utime - startCpu.tms_utime) / sysconf(_SC_CLK_TCK); 26 | double systemTime = (double)(endCpu.tms_stime - startCpu.tms_stime) / sysconf(_SC_CLK_TCK); 27 | fprintf(file, "Operation: %s\n", name); 28 | fprintf(file, "Real time: %f\n", realTime); 29 | fprintf(file, "User time: %f\n", userTime); 30 | fprintf(file, "System time: %f\n\n", systemTime); 31 | 32 | printf("Operation: %s\n", name); 33 | printf("Real time: %f\n", realTime); 34 | printf("User time: %f\n", userTime); 35 | printf("System time: %f\n\n", systemTime); 36 | } 37 | 38 | 39 | 40 | int main(int argc, char**argv) { 41 | if (argc < 3){ 42 | printf("Number of argument must be at least 3"); 43 | return -1; 44 | } 45 | if(strcmp(argv[1], "create_table") !=0 ){ 46 | printf("First argument has to be create_table"); 47 | return -1; 48 | } 49 | 50 | resultFile = fopen("raport.txt", "a"); 51 | 52 | int numberOfBlocks = atoi(argv[2]); 53 | struct MainArray* mainArray = createArray(numberOfBlocks); 54 | int i = 3; 55 | char* operation; 56 | while (i < argc){ 57 | startTimer(); 58 | 59 | if (!strcmp(argv[i], "compare_pairs")){ 60 | comparePairs(argv[i+1], mainArray); 61 | i += 2; 62 | operation = "compare_pairs"; 63 | } 64 | else if (!strcmp(argv[i], "remove_operation")){ 65 | int indexOfBlock = atoi(argv[i + 1]); 66 | int indexOfOperation = atoi(argv[i + 2]); 67 | deleteOperation(mainArray, indexOfBlock, indexOfOperation); 68 | i += 3; 69 | operation = "remove_operation"; 70 | } 71 | else if (!strcmp(argv[i], "remove_block")){ 72 | int indexOfBlock = atoi(argv[i + 1]); 73 | deleteBlock(mainArray, indexOfBlock); 74 | i += 2; 75 | operation = "remove_block"; 76 | } 77 | else{ 78 | operation = "wrong operation"; 79 | i ++; 80 | } 81 | writeResultToFile(resultFile, operation); 82 | } 83 | deleteArray(mainArray); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /cw01/zad3b/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "library.h" 9 | 10 | clock_t startTime, endTime; 11 | struct tms startCpu, endCpu; 12 | 13 | FILE *resultFile; 14 | 15 | void startTimer(){ 16 | startTime = times(&startCpu); 17 | } 18 | void endTimer(){ 19 | endTime = times(&endCpu); 20 | } 21 | 22 | void writeResultToFile(FILE* file, char* name){ 23 | endTimer(); 24 | double realTime = (double) (endTime - startTime) / sysconf(_SC_CLK_TCK); 25 | double userTime = (double) (endCpu.tms_utime - startCpu.tms_utime) / sysconf(_SC_CLK_TCK); 26 | double systemTime = (double)(endCpu.tms_stime - startCpu.tms_stime) / sysconf(_SC_CLK_TCK); 27 | fprintf(file, "Operation: %s\n", name); 28 | fprintf(file, "Real time: %f\n", realTime); 29 | fprintf(file, "User time: %f\n", userTime); 30 | fprintf(file, "System time: %f\n\n", systemTime); 31 | 32 | printf("Operation: %s\n", name); 33 | printf("Real time: %f\n", realTime); 34 | printf("User time: %f\n", userTime); 35 | printf("System time: %f\n\n", systemTime); 36 | } 37 | 38 | 39 | 40 | int main(int argc, char**argv) { 41 | if (argc < 3){ 42 | printf("Number of argument must be at least 3"); 43 | return -1; 44 | } 45 | if(strcmp(argv[1], "create_table") !=0 ){ 46 | printf("First argument has to be create_table"); 47 | return -1; 48 | } 49 | 50 | resultFile = fopen("raport.txt", "a"); 51 | 52 | int numberOfBlocks = atoi(argv[2]); 53 | struct MainArray* mainArray = createArray(numberOfBlocks); 54 | int i = 3; 55 | char* operation; 56 | while (i < argc){ 57 | startTimer(); 58 | 59 | if (!strcmp(argv[i], "compare_pairs")){ 60 | comparePairs(argv[i+1], mainArray); 61 | i += 2; 62 | operation = "compare_pairs"; 63 | } 64 | else if (!strcmp(argv[i], "remove_operation")){ 65 | int indexOfBlock = atoi(argv[i + 1]); 66 | int indexOfOperation = atoi(argv[i + 2]); 67 | deleteOperation(mainArray, indexOfBlock, indexOfOperation); 68 | i += 3; 69 | operation = "remove_operation"; 70 | } 71 | else if (!strcmp(argv[i], "remove_block")){ 72 | int indexOfBlock = atoi(argv[i + 1]); 73 | deleteBlock(mainArray, indexOfBlock); 74 | i += 2; 75 | operation = "remove_block"; 76 | } 77 | else{ 78 | operation = "wrong operation"; 79 | i ++; 80 | } 81 | writeResultToFile(resultFile, operation); 82 | } 83 | deleteArray(mainArray); 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /cw01/zad3b/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | LIB_NAME = lib_diff 4 | LIB_PATH = ../zad1 5 | TEST_PATH = ../zad2 6 | TEST_SOURCE_NAME = main.c 7 | REPORT_FILE = raport3b.txt 8 | O = O1 9 | 10 | static: 11 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -I$(LIB_PATH) $(LIB_PATH)/$(LIB_NAME).a 12 | 13 | staticO: 14 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -$O -I$(LIB_PATH) $(LIB_PATH)/$(LIB_NAME).a 15 | 16 | shared: 17 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -I$(LIB_PATH) -L$(LIB_PATH) -l_diff 18 | 19 | sharedO: 20 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -$O -I$(LIB_PATH) -L$(LIB_PATH) -l_diff 21 | 22 | dynamic_main: main_dyn.c 23 | make shared 24 | $(CC) $(FLAGS) main_dyn.c -ldl -o main_dyn -I . 25 | 26 | dynamic_mainO: 27 | make CC="gcc -$O" dynamic_main 28 | 29 | clean_all: 30 | make clean 31 | rm -rf main raport3b.txt 32 | rm -f main_dyn 33 | 34 | test: 35 | LD_LIBRARY_PATH=$(LIB_PATH) ./main $(shell cat args.txt) 36 | 37 | test_dyn: 38 | LD_LIBRARY_PATH=$(LIB_PATH) ./main_dyn $(shell cat args.txt) 39 | 40 | testStatic: 41 | printf "static:\n" > raport.txt 42 | make static 43 | make test 44 | mv raport.txt $(REPORT_FILE) 45 | 46 | testShared: 47 | printf "shared:\n" >> raport.txt 48 | make shared 49 | make test 50 | mv raport.txt $(REPORT_FILE) 51 | 52 | testDynamic: 53 | printf "dynamic:\n" >> raport.txt 54 | make dynamic_main 55 | make test_dyn 56 | mv raport.txt $(REPORT_FILE) 57 | 58 | test_all: 59 | printf "static:\n" > raport.txt 60 | make static 61 | make test 62 | printf "shared:\n" >> raport.txt 63 | make shared 64 | make test 65 | printf "dynamic:\n" >> raport.txt 66 | make dynamic_main 67 | make test_dyn 68 | mv raport.txt $(REPORT_FILE) 69 | 70 | test_allO: 71 | printf "static O1:\n" > raport.txt 72 | make staticO O=O1 73 | make test 74 | printf "shared: O1\n" >> raport.txt 75 | make sharedO O=O1 76 | make test 77 | printf "dynamic: O1\n" >> raport.txt 78 | make dynamic_mainO O=O1 79 | make test_dyn 80 | printf "static O2:\n" >> raport.txt 81 | make staticO O=O2 82 | make test 83 | printf "shared: O2\n" >> raport.txt 84 | make sharedO O=O2 85 | make test 86 | printf "dynamic: O2\n" >> raport.txt 87 | make dynamic_mainO O=O2 88 | make test_dyn 89 | printf "static: Ofast\n" >> raport.txt 90 | make staticO O=Ofast 91 | make test 92 | printf "static: Os\n" >> raport.txt 93 | make staticO O=Os 94 | make test 95 | printf "static: O0\n" >> raport.txt 96 | make staticO O=O0 97 | make test 98 | printf "shared: O0\n" >> raport.txt 99 | make sharedO O=O0 100 | make test 101 | printf "dynamic: O0\n" >> raport.txt 102 | make dynamic_mainO O=O0 103 | make test_dyn 104 | mv raport.txt $(REPORT_FILE) 105 | -------------------------------------------------------------------------------- /cw03/zad2/generator.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int MIN = -100; 7 | int MAX = 100; 8 | 9 | int randomNumber(int minValue, int maxValue){ 10 | return rand() % (maxValue - minValue + 1) + minValue; 11 | } 12 | 13 | void generate(int numberOfPairs, int minValue, int maxValue){ 14 | srand(time(NULL)); 15 | FILE *lista = fopen("lista", "w+"); 16 | if (lista == NULL) return; 17 | char* file = (char*) calloc(100, sizeof(char)); 18 | 19 | for (int i = 0; i < numberOfPairs; i++){ 20 | char number[3]; 21 | sprintf(number, "%d", i); 22 | 23 | strcpy(file, "macierze/"); 24 | strcat(file, "A"); 25 | strcat(file, number); 26 | FILE *A = fopen(file, "w+"); 27 | fprintf(lista, "%s ", file); 28 | 29 | strcpy(file, "macierze/"); 30 | strcat(file, "B"); 31 | strcat(file, number); 32 | FILE *B = fopen(file, "w+"); 33 | fprintf(lista, "%s ", file); 34 | 35 | strcpy(file, "macierze/"); 36 | strcat(file, "C"); 37 | strcat(file, number); 38 | fprintf(lista, "%s\n", file); 39 | 40 | int rowsA = randomNumber(minValue, maxValue); 41 | int colsA = randomNumber(minValue, maxValue); 42 | int colsB = randomNumber(minValue, maxValue); 43 | 44 | for (int row = 0; row < rowsA; row ++){ 45 | for (int col = 0; col < colsA; col ++){ 46 | fprintf(A, "%d", randomNumber(MIN, MAX)); 47 | if (col != colsA - 1){ 48 | fprintf(A, " "); 49 | } 50 | } 51 | fprintf(A, "\n"); 52 | } 53 | 54 | for (int row = 0; row < colsA; row ++){ 55 | for (int col = 0; col < colsB; col ++){ 56 | fprintf(B, "%d", randomNumber(MIN, MAX)); 57 | if (col != colsB - 1){ 58 | fprintf(B, " "); 59 | } 60 | } 61 | fprintf(B, "\n"); 62 | } 63 | 64 | fclose(A); 65 | fclose(B); 66 | } 67 | } 68 | 69 | int main(int argc, char **argv){ 70 | if (argc != 4){ 71 | printf("Wrong number of arguments.\nExpected: ./generator [number of pairs] [min value] [max value]\n"); 72 | exit(EXIT_FAILURE); 73 | } 74 | int numberOfPairs = atoi(argv[1]); 75 | int minValue = atoi(argv[2]); 76 | int maxValue = atoi(argv[3]); 77 | 78 | if (numberOfPairs <= 0 || minValue <= 0 || maxValue <= 0){ 79 | printf("Argument must be positive\n"); 80 | exit(EXIT_FAILURE); 81 | } 82 | 83 | if (minValue > maxValue){ 84 | int tmp = maxValue; 85 | maxValue = minValue; 86 | minValue = tmp; 87 | } 88 | 89 | generate(numberOfPairs, minValue, maxValue); 90 | return 0; 91 | } -------------------------------------------------------------------------------- /cw03/zad3/generator.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int MIN = -100; 7 | int MAX = 100; 8 | 9 | int randomNumber(int minValue, int maxValue){ 10 | return rand() % (maxValue - minValue + 1) + minValue; 11 | } 12 | 13 | void generate(int numberOfPairs, int minValue, int maxValue){ 14 | srand(time(NULL)); 15 | FILE *lista = fopen("lista", "w+"); 16 | if (lista == NULL) return; 17 | char* file = (char*) calloc(100, sizeof(char)); 18 | 19 | for (int i = 0; i < numberOfPairs; i++){ 20 | char number[3]; 21 | sprintf(number, "%d", i); 22 | 23 | strcpy(file, "macierze/"); 24 | strcat(file, "A"); 25 | strcat(file, number); 26 | FILE *A = fopen(file, "w+"); 27 | fprintf(lista, "%s ", file); 28 | 29 | strcpy(file, "macierze/"); 30 | strcat(file, "B"); 31 | strcat(file, number); 32 | FILE *B = fopen(file, "w+"); 33 | fprintf(lista, "%s ", file); 34 | 35 | strcpy(file, "macierze/"); 36 | strcat(file, "C"); 37 | strcat(file, number); 38 | fprintf(lista, "%s\n", file); 39 | 40 | int rowsA = randomNumber(minValue, maxValue); 41 | int colsA = randomNumber(minValue, maxValue); 42 | int colsB = randomNumber(minValue, maxValue); 43 | 44 | for (int row = 0; row < rowsA; row ++){ 45 | for (int col = 0; col < colsA; col ++){ 46 | fprintf(A, "%d", randomNumber(MIN, MAX)); 47 | if (col != colsA - 1){ 48 | fprintf(A, " "); 49 | } 50 | } 51 | fprintf(A, "\n"); 52 | } 53 | 54 | for (int row = 0; row < colsA; row ++){ 55 | for (int col = 0; col < colsB; col ++){ 56 | fprintf(B, "%d", randomNumber(MIN, MAX)); 57 | if (col != colsB - 1){ 58 | fprintf(B, " "); 59 | } 60 | } 61 | fprintf(B, "\n"); 62 | } 63 | 64 | fclose(A); 65 | fclose(B); 66 | } 67 | } 68 | 69 | int main(int argc, char **argv){ 70 | if (argc != 4){ 71 | printf("Wrong number of arguments.\nExpected: ./generator [number of pairs] [min value] [max value]\n"); 72 | exit(EXIT_FAILURE); 73 | } 74 | int numberOfPairs = atoi(argv[1]); 75 | int minValue = atoi(argv[2]); 76 | int maxValue = atoi(argv[3]); 77 | 78 | if (numberOfPairs <= 0 || minValue <= 0 || maxValue <= 0){ 79 | printf("Argument must be positive\n"); 80 | exit(EXIT_FAILURE); 81 | } 82 | 83 | if (minValue > maxValue){ 84 | int tmp = maxValue; 85 | maxValue = minValue; 86 | minValue = tmp; 87 | } 88 | 89 | generate(numberOfPairs, minValue, maxValue); 90 | return 0; 91 | } -------------------------------------------------------------------------------- /cw04/zad4b/catcher.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int COUNT_SIGNAL; 11 | int END_SIGNAL; 12 | char* MODE; 13 | 14 | int receivedSignals = 0; 15 | 16 | union sigval val; 17 | 18 | void signalsHandle(int sig, siginfo_t *info, void *uncontext){ 19 | if (sig == COUNT_SIGNAL){ 20 | receivedSignals ++; 21 | 22 | if (!strcmp("kill", MODE) || !strcmp("sigrt", MODE)){ 23 | // send COUNT_SIGNAL to a process 24 | kill(info -> si_pid, COUNT_SIGNAL); 25 | } 26 | else{ 27 | // send COUNT_SIGNAL to a process with given value 28 | sigqueue(info -> si_pid, COUNT_SIGNAL, val); 29 | } 30 | } 31 | else if (sig == END_SIGNAL){ 32 | if (!strcmp("kill", MODE) || !strcmp("sigrt", MODE)){ 33 | // send END_SIGNAL to a process 34 | kill(info -> si_pid, END_SIGNAL); 35 | } 36 | else{ 37 | // send END_SIGNAL to a process with given value 38 | sigqueue(info -> si_pid, END_SIGNAL, val); 39 | } 40 | printf("Catcher received: %d signals\n", receivedSignals); 41 | exit(0); 42 | } 43 | } 44 | 45 | int main(int argc, char **argv){ 46 | if (argc != 2){ 47 | printf("Wrong number of arguments. Expected: [mode: kill / queue / sigrt]\n"); 48 | exit(EXIT_FAILURE); 49 | } 50 | 51 | MODE = argv[1]; 52 | 53 | if (!strcmp("kill", MODE)){ 54 | COUNT_SIGNAL = SIGUSR1; 55 | END_SIGNAL = SIGUSR2; 56 | } 57 | else if(!strcmp("queue", MODE)){ 58 | COUNT_SIGNAL = SIGUSR1; 59 | END_SIGNAL = SIGUSR2; 60 | } 61 | else if (!strcmp("sigrt", MODE)){ 62 | COUNT_SIGNAL = SIGRTMIN + 1; 63 | END_SIGNAL = SIGRTMIN + 2; 64 | } 65 | else{ 66 | printf("Wrong mode. Expected: [kill / queue / sigrt]\n"); 67 | exit(EXIT_FAILURE); 68 | } 69 | 70 | val.sival_int = 0; 71 | 72 | sigset_t mask; 73 | sigfillset(&mask); 74 | sigdelset(&mask, COUNT_SIGNAL); 75 | sigdelset(&mask, END_SIGNAL); 76 | 77 | if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0){ 78 | printf("Cannot block signals\n"); 79 | exit(EXIT_FAILURE); 80 | } 81 | 82 | struct sigaction act; 83 | act.sa_flags = SA_SIGINFO; 84 | act.sa_sigaction = signalsHandle; 85 | 86 | sigemptyset(&act.sa_mask); 87 | sigaddset(&act.sa_mask, COUNT_SIGNAL); 88 | sigaddset(&act.sa_mask, END_SIGNAL); 89 | 90 | sigaction(COUNT_SIGNAL, &act, NULL); 91 | sigaction(END_SIGNAL, &act, NULL); 92 | 93 | printf("Created catcher with PID: %d\n", getpid()); 94 | 95 | while (1){ 96 | usleep(100); 97 | } 98 | return 0; 99 | } -------------------------------------------------------------------------------- /cw07/zad1/sender.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "common.h" 14 | 15 | void send_order(int semaphore_id, int shared_memory_id){ 16 | sembuf *sops = (sembuf *) calloc(4, sizeof(sembuf)); 17 | 18 | sops[0].sem_num = FREE_ARRAY; 19 | sops[0].sem_op = 0; 20 | 21 | sops[1].sem_num = FREE_ARRAY; 22 | sops[1].sem_op = 1; 23 | 24 | sops[2].sem_num = SEND_INDEX; 25 | sops[2].sem_op = 1; 26 | 27 | sops[3].sem_num = SEND_NUMBER; 28 | sops[3].sem_op = -1; 29 | 30 | for (int i = 0; i < 4; i ++){ 31 | sops[i].sem_flg = 0; 32 | } 33 | 34 | if (semop(semaphore_id, sops, 4) < 0) error_exit("Cannot excecute operations on semaphores", "function send_order (sender)"); 35 | 36 | 37 | orders* orders = shmat(shared_memory_id, NULL, 0); 38 | if (orders == (void *) -1) error_exit("Cannot access shared memory", "function send_order (sender)"); 39 | 40 | int index = semctl(semaphore_id, SEND_INDEX, GETVAL, NULL); 41 | if (index == -1) error_exit("Cannot get index", "send_order (sender)"); 42 | index = (index - 1) % MAX_ORDERS; 43 | 44 | orders -> values[index] *= 3; 45 | 46 | int orders_to_send = semctl(semaphore_id, SEND_NUMBER, GETVAL, NULL); 47 | if (orders_to_send == -1) error_exit("Cannot take number of orders to send", "function send_order (sender)"); 48 | 49 | int orders_to_prepare = semctl(semaphore_id, PACK_NUMBER, GETVAL, NULL); 50 | if (orders_to_prepare == -1) error_exit("Cannot take number of orders to prepare", "function send_order (sender)"); 51 | 52 | printf("[%d %ld] SENDER: Send order at size: %d. Number of orders to prepare: %d. Number of orders to send: %d.\n", 53 | getpid(), time(NULL), orders -> values[index], orders_to_prepare, orders_to_send); 54 | 55 | orders -> values[index] = 0; 56 | 57 | if (shmdt(orders) == -1) error_exit("Cannot detach the shared memory segment", "function send_order (sender)"); 58 | 59 | 60 | sembuf *finalize = calloc(1, sizeof(sembuf)); 61 | 62 | finalize[0].sem_num = FREE_ARRAY; 63 | finalize[0].sem_op = -1; 64 | finalize[0].sem_flg = 0; 65 | 66 | if (semop(semaphore_id, finalize, 1) < 0) error_exit("Cannot excecute operations on semaphores", "function send_order (sender)"); 67 | 68 | } 69 | 70 | int main(){ 71 | srand(time(NULL)); 72 | 73 | int semaphore_id = get_semaphore_id(); 74 | int shared_memory_id = get_shared_memory_id(); 75 | 76 | while(1){ 77 | usleep(rand_time()); 78 | if (semctl(semaphore_id, 5, GETVAL, NULL) > 0){ 79 | send_order(semaphore_id, shared_memory_id); 80 | } 81 | } 82 | return 0; 83 | } -------------------------------------------------------------------------------- /cw07/zad1/receiver.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "common.h" 14 | 15 | void add_order(int semaphore_id, int shared_memory_id){ 16 | sembuf *sops = (sembuf *) calloc(3, sizeof(sembuf)); 17 | 18 | sops[0].sem_num = FREE_ARRAY; 19 | sops[0].sem_op = 0; 20 | 21 | sops[1].sem_num = FREE_ARRAY; 22 | sops[1].sem_op = 1; 23 | 24 | sops[2].sem_num = FREE_INDEX; 25 | sops[2].sem_op = 1; 26 | 27 | for (int i = 0; i < 3; i ++){ 28 | sops[i].sem_flg = 0; 29 | } 30 | 31 | if (semop(semaphore_id, sops, 3) < 0) error_exit("Cannot excecute operations on semaphores", "function add_order (receiver)"); 32 | 33 | 34 | orders* orders = shmat(shared_memory_id, NULL, 0); 35 | if (orders == (void *) -1) error_exit("Cannot access shared memory", "function add_order (receiver)"); 36 | 37 | int index = semctl(semaphore_id, FREE_INDEX, GETVAL, NULL); 38 | if (index == -1) error_exit("Cannot get index", "add_order (receiver)"); 39 | index = (index - 1) % MAX_ORDERS; 40 | 41 | orders -> values[index] = rand_int(); 42 | 43 | int orders_to_send = semctl(semaphore_id, SEND_NUMBER, GETVAL, NULL); 44 | if (orders_to_send == -1) error_exit("Cannot take number of orders to send", "function add_order (receiver)"); 45 | 46 | int orders_to_prepare = semctl(semaphore_id, PACK_NUMBER, GETVAL, NULL) + 1; 47 | if (orders_to_prepare - 1 == -1) error_exit("Cannot take number of orders to prepare", "function add_order (receiver)"); 48 | 49 | printf("[%d %ld] RECEIVER: Received number: %d. Number of orders to prepare: %d. Number of orders to send: %d.\n", 50 | getpid(), time(NULL), orders -> values[index], orders_to_prepare, orders_to_send); 51 | 52 | if (shmdt(orders) == -1) error_exit("Cannot detach the shared memory segment", "function add_order (receiver)"); 53 | 54 | 55 | sembuf *finalize = calloc(2, sizeof(sembuf)); 56 | 57 | finalize[0].sem_num = FREE_ARRAY; 58 | finalize[0].sem_op = -1; 59 | 60 | finalize[1].sem_num = PACK_NUMBER; 61 | finalize[1].sem_op = 1; 62 | 63 | for (int i = 0; i < 2; i ++){ 64 | finalize[i].sem_flg = 0; 65 | } 66 | 67 | if (semop(semaphore_id, finalize, 2) < 0) error_exit("Cannot excecute operations on semaphores", "function add_order (receiver)"); 68 | 69 | } 70 | 71 | int main(){ 72 | srand(time(NULL)); 73 | 74 | int semaphore_id = get_semaphore_id(); 75 | int shared_memory_id = get_shared_memory_id(); 76 | 77 | while(1){ 78 | usleep(rand_time()); 79 | if (semctl(semaphore_id, PACK_NUMBER, GETVAL, NULL) + semctl(semaphore_id, SEND_NUMBER, GETVAL, NULL) < MAX_ORDERS){ 80 | add_order(semaphore_id, shared_memory_id); 81 | } 82 | } 83 | return 0; 84 | } -------------------------------------------------------------------------------- /cw07/zad1/packer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "common.h" 14 | 15 | void pack_order(int semaphore_id, int shared_memory_id){ 16 | sembuf *sops = (sembuf *) calloc(4, sizeof(sembuf)); 17 | 18 | sops[0].sem_num = FREE_ARRAY; 19 | sops[0].sem_op = 0; 20 | 21 | sops[1].sem_num = FREE_ARRAY; 22 | sops[1].sem_op = 1; 23 | 24 | sops[2].sem_num = PACK_INDEX; 25 | sops[2].sem_op = 1; 26 | 27 | sops[3].sem_num = PACK_NUMBER; 28 | sops[3].sem_op = -1; 29 | 30 | for (int i = 0; i < 4; i ++){ 31 | sops[i].sem_flg = 0; 32 | } 33 | 34 | if (semop(semaphore_id, sops, 4) < 0) error_exit("Cannot excecute operations on semaphores", "function pack_order (packer)"); 35 | 36 | 37 | orders* orders = shmat(shared_memory_id, NULL, 0); 38 | if (orders == (void *) -1) error_exit("Cannot access shared memory", "function pack_order (packer)"); 39 | 40 | int index = semctl(semaphore_id, PACK_INDEX, GETVAL, NULL); 41 | if (index == -1) error_exit("Cannot get index", "pack_order (packer)"); 42 | index = (index - 1) % MAX_ORDERS; 43 | 44 | orders -> values[index] *= 2; 45 | 46 | int orders_to_send = semctl(semaphore_id, SEND_NUMBER, GETVAL, NULL) + 1; 47 | if (orders_to_send - 1 == -1) error_exit("Cannot take number of orders to send", "function pack_order (packer)"); 48 | 49 | int orders_to_prepare = semctl(semaphore_id, PACK_NUMBER, GETVAL, NULL); 50 | if (orders_to_prepare == -1) error_exit("Cannot take number of orders to prepare", "function pack_order (packer)"); 51 | 52 | printf("[%d %ld] PACKER: Prepared order at size: %d. Number of orders to prepare: %d. Number of orders to send: %d.\n", 53 | getpid(), time(NULL), orders -> values[index], orders_to_prepare, orders_to_send); 54 | 55 | if (shmdt(orders) == -1) error_exit("Cannot detach the shared memory segment", "function pack_order (packer)"); 56 | 57 | 58 | sembuf *finalize = calloc(2, sizeof(sembuf)); 59 | 60 | finalize[0].sem_num = FREE_ARRAY; 61 | finalize[0].sem_op = -1; 62 | 63 | finalize[1].sem_num = SEND_NUMBER; 64 | finalize[1].sem_op = 1; 65 | 66 | for (int i = 0; i < 2; i ++){ 67 | finalize[i].sem_flg = 0; 68 | } 69 | 70 | if (semop(semaphore_id, finalize, 2) < 0) error_exit("Cannot excecute operations on semaphores", "function pack_order (packer)"); 71 | 72 | } 73 | 74 | int main(){ 75 | srand(time(NULL)); 76 | 77 | int semaphore_id = get_semaphore_id(); 78 | int shared_memory_id = get_shared_memory_id(); 79 | 80 | while(1){ 81 | usleep(rand_time()); 82 | if (semctl(semaphore_id, PACK_NUMBER, GETVAL, NULL) > 0){ 83 | pack_order(semaphore_id, shared_memory_id); 84 | } 85 | } 86 | return 0; 87 | } -------------------------------------------------------------------------------- /cw07/zad1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "common.h" 14 | 15 | int semaphore_id; 16 | int shared_memory_id; 17 | pid_t child_pids[ALL_WORKERS]; 18 | 19 | void clear_before_exit(){ 20 | semctl(semaphore_id, 0, IPC_RMID, NULL); 21 | shmctl(shared_memory_id, IPC_RMID, NULL); 22 | } 23 | 24 | void sigint_handle(int signum){ 25 | printf("\nExit\n"); 26 | for (int i = 0; i < ALL_WORKERS; i ++){ 27 | kill(child_pids[i], SIGINT); 28 | } 29 | clear_before_exit(); 30 | exit(EXIT_SUCCESS); 31 | } 32 | 33 | void create_semaphore(){ 34 | key_t semaphore_key = ftok(getenv("HOME"), 0); 35 | semaphore_id = semget(semaphore_key, SEMAPHORES, IPC_CREAT | 0666); 36 | if (semaphore_id < 0) error_exit("Cannot create semaphore", "function create_semaphore (main)"); 37 | 38 | union semun arg; 39 | arg.val = 0; 40 | 41 | semctl(semaphore_id, FREE_ARRAY, SETVAL, arg); 42 | semctl(semaphore_id, FREE_INDEX, SETVAL, arg); 43 | semctl(semaphore_id, PACK_INDEX, SETVAL, arg); 44 | semctl(semaphore_id, PACK_NUMBER, SETVAL, arg); 45 | semctl(semaphore_id, SEND_INDEX, SETVAL, arg); 46 | semctl(semaphore_id, SEND_NUMBER, SETVAL, arg); 47 | } 48 | 49 | void run_receivers(){ 50 | for (int i = 0; i < RECEIVERS; i ++){ 51 | pid_t child_pid = fork(); 52 | if (child_pid == 0){ 53 | execlp("./receiver", "receiver", NULL); 54 | } 55 | child_pids[i] = child_pid; 56 | } 57 | } 58 | 59 | void run_packers(){ 60 | for (int i = 0; i < PACKERS; i ++){ 61 | pid_t child_pid = fork(); 62 | if (child_pid == 0){ 63 | execlp("./packer", "packer", NULL); 64 | } 65 | child_pids[i + RECEIVERS] = child_pid; 66 | } 67 | } 68 | 69 | void run_senders(){ 70 | for (int i = 0; i < SENDERS; i ++){ 71 | pid_t child_pid = fork(); 72 | if (child_pid == 0){ 73 | execlp("./sender", "sender", NULL); 74 | } 75 | child_pids[i + RECEIVERS + PACKERS] = child_pid; 76 | } 77 | 78 | for (int i = 0; i < ALL_WORKERS; i++){ 79 | wait(NULL); 80 | } 81 | } 82 | 83 | void create_shared_memory(){ 84 | key_t key = ftok(getenv("HOME"), 1); 85 | shared_memory_id = shmget(key, sizeof(orders), IPC_CREAT | 0666); 86 | if (shared_memory_id < 0) error_exit("Cannot create shared memory", "function create_shared_memory (main)"); 87 | } 88 | 89 | int main(){ 90 | 91 | signal(SIGINT, sigint_handle); 92 | 93 | create_semaphore(); 94 | create_shared_memory(); 95 | 96 | run_receivers(); 97 | run_packers(); 98 | run_senders(); 99 | 100 | clear_before_exit(); 101 | return 0; 102 | } -------------------------------------------------------------------------------- /cw04/zad2/main.c: -------------------------------------------------------------------------------- 1 | #define _POSIX_C_SOURCE 1 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef enum Mode{ 11 | IGNORE, 12 | HANDLER, 13 | MASK, 14 | PENDING 15 | } Mode; 16 | 17 | void signalHandle(int sig){ 18 | printf("Signal received\n"); 19 | } 20 | 21 | int main(int argc, char **argv){ 22 | if (argc != 3){ 23 | printf("Wrong number of arguments. Expected: ./main [ignore / handler / mask / pending] [fork / exec]\n"); 24 | return -1; 25 | } 26 | 27 | Mode mode; 28 | 29 | if (!strcmp("ignore", argv[1])){ 30 | mode = IGNORE; 31 | printf("IGNORE\n"); 32 | signal(SIGUSR1, SIG_IGN); 33 | } 34 | else if (!strcmp("handler", argv[1])){ 35 | mode = HANDLER; 36 | printf("HANDLER\n"); 37 | signal(SIGUSR1, signalHandle); 38 | } 39 | else if (!strcmp("mask", argv[1]) || !strcmp("pending", argv[1])){ 40 | if (!strcmp("mask", argv[1])) { 41 | mode = MASK; 42 | printf("MASK\n"); 43 | } 44 | else { 45 | mode = PENDING; 46 | printf("PENDING\n"); 47 | } 48 | 49 | sigset_t mask; // set of signals blocked during operate current process 50 | sigemptyset (&mask); 51 | sigaddset(&mask, SIGUSR1); 52 | 53 | // set mask for current process 54 | if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0){ 55 | printf("Cannot block signals\n"); 56 | exit(EXIT_FAILURE); 57 | } 58 | 59 | } 60 | else{ 61 | printf("Wrong argument. There isn't option like: %s\n", argv[1]); 62 | return -1; 63 | } 64 | 65 | sigset_t mask; 66 | 67 | raise(SIGUSR1); 68 | 69 | if (mode == MASK || mode == PENDING){ 70 | sigpending(&mask); // returns the set of signals that are pending for delivery to the calling thread 71 | 72 | if (sigismember(&mask, SIGUSR1)){ // check if SIGUSR1 is in given set 73 | printf("Signal pending in parent.\n"); 74 | } 75 | } 76 | 77 | if (!strcmp(argv[2], "fork")){ 78 | pid_t childPid = fork(); 79 | 80 | if (childPid == 0){ 81 | if (mode != PENDING) raise(SIGUSR1); // send a signal to the calling process = kill(getpid(), SIGUSR1) 82 | 83 | if (mode == MASK || mode == PENDING){ 84 | sigpending(&mask); 85 | 86 | if (sigismember(&mask, SIGUSR1)){ 87 | printf("Signal pending in child.\n\n"); 88 | } 89 | else{ 90 | printf("Signal not pending in child.\n\n"); 91 | } 92 | } 93 | } 94 | } 95 | else if(!strcmp(argv[2], "exec") && mode != HANDLER){ 96 | execl("./exec", "./exec", argv[1], NULL); 97 | } 98 | 99 | wait(0); 100 | 101 | return 0; 102 | } -------------------------------------------------------------------------------- /cw04/zad4a/sender.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int COUNT_SIGNAL; 11 | int END_SIGNAL; 12 | char* MODE; 13 | 14 | int signalsToSend; 15 | int receivedSignals; 16 | 17 | void signalsHandle(int sig, siginfo_t *info, void *uncontext){ 18 | if (sig == COUNT_SIGNAL){ 19 | receivedSignals ++; 20 | if (!strcmp("queue", MODE)){ 21 | printf("Already received: %d signals, catcher index: %d\n", receivedSignals, info -> si_value.sival_int); 22 | } 23 | } 24 | else if (sig == END_SIGNAL){ 25 | printf("Sender received: %d signals, expected: %d\n", receivedSignals, signalsToSend); 26 | exit(0); 27 | } 28 | } 29 | 30 | int main(int argc, char **argv){ 31 | // argv[1] = catcher's PID 32 | // argv[2] = number of signals to send 33 | // argv[3] = mode of sending signal 34 | 35 | if (argc != 4){ 36 | printf("Wrong number of arguments. Expected: [catcher's PID] [number of signals to send] [mode: kill / queue / sigrt]\n"); 37 | exit(EXIT_FAILURE); 38 | } 39 | int catcherPID = atoi(argv[1]); 40 | signalsToSend = atoi(argv[2]); 41 | MODE = argv[3]; 42 | 43 | if (!strcmp("kill", MODE)){ 44 | COUNT_SIGNAL = SIGUSR1; 45 | END_SIGNAL = SIGUSR2; 46 | } 47 | else if (!strcmp("queue", MODE)){ 48 | COUNT_SIGNAL = SIGUSR1; 49 | END_SIGNAL = SIGUSR2; 50 | } 51 | else if (!strcmp("sigrt", MODE)){ 52 | COUNT_SIGNAL = SIGRTMIN + 1; 53 | END_SIGNAL = SIGRTMIN + 2; 54 | } 55 | else{ 56 | printf("Wrong mode. Expected: [kill / queue / sigrt]\n"); 57 | exit(EXIT_FAILURE); 58 | } 59 | 60 | sigset_t mask; 61 | sigfillset(&mask); 62 | sigdelset(&mask, COUNT_SIGNAL); 63 | sigdelset(&mask, END_SIGNAL); 64 | 65 | if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0){ 66 | printf("Cannot block signals\n"); 67 | exit(EXIT_FAILURE); 68 | } 69 | 70 | struct sigaction act; 71 | act.sa_flags = SA_SIGINFO; 72 | act.sa_sigaction = signalsHandle; 73 | 74 | sigemptyset(&act.sa_mask); 75 | sigaddset(&act.sa_mask, COUNT_SIGNAL); 76 | sigaddset(&act.sa_mask, END_SIGNAL); 77 | 78 | sigaction(COUNT_SIGNAL, &act, NULL); 79 | sigaction(END_SIGNAL, &act, NULL); 80 | 81 | printf("Created sender with PID: %d\n", getpid()); 82 | 83 | if (!strcmp("kill", MODE) || !strcmp("sigrt", MODE)){ 84 | for (int i = 0; i < signalsToSend; ++i){ 85 | // send COUNT_SIGNAL to a process with catcherPID 86 | kill(catcherPID, COUNT_SIGNAL); 87 | } 88 | // send END_SIGNAL to a process with catcherPID 89 | kill(catcherPID, END_SIGNAL); 90 | } 91 | else{ 92 | union sigval val; 93 | val.sival_int = 0; 94 | for (int i = 0; i < signalsToSend; ++i){ 95 | sigqueue(catcherPID, COUNT_SIGNAL, val); 96 | } 97 | sigqueue(catcherPID, END_SIGNAL, val); 98 | } 99 | while (1){ 100 | usleep(100); 101 | } 102 | return 0; 103 | 104 | } -------------------------------------------------------------------------------- /cw04/zad4a/catcher.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int COUNT_SIGNAL; 11 | int END_SIGNAL; 12 | char* MODE; 13 | 14 | int receivedSignals = 0; 15 | 16 | void signalsHandle(int sig, siginfo_t *info, void *uncontext){ 17 | if (sig == COUNT_SIGNAL){ 18 | receivedSignals ++; 19 | } 20 | else if (sig == END_SIGNAL){ 21 | if (!strcmp("kill", MODE) || !strcmp("sigrt", MODE)){ 22 | for (int i = 0; i < receivedSignals; ++i){ 23 | // send COUNT_SIGNAL to a process 24 | kill(info -> si_pid, COUNT_SIGNAL); 25 | } 26 | // send END_SIGNAL to a process 27 | kill(info -> si_pid, END_SIGNAL); 28 | } 29 | else{ 30 | union sigval val; 31 | for (int i = 0; i < receivedSignals; ++i){ 32 | val.sival_int = i; 33 | // send COUNT_SIGNAL to a process with given value 34 | sigqueue(info -> si_pid, COUNT_SIGNAL, val); 35 | } 36 | // send END_SIGNAL to a process with given value 37 | sigqueue(info -> si_pid, END_SIGNAL, val); 38 | } 39 | printf("Catcher received: %d signals\n", receivedSignals); 40 | exit(0); 41 | } 42 | } 43 | 44 | int main(int argc, char **argv){ 45 | if (argc != 2){ 46 | printf("Wrong number of arguments. Expected: [mode: kill / queue / sigrt]\n"); 47 | exit(EXIT_FAILURE); 48 | } 49 | 50 | MODE = argv[1]; 51 | 52 | if (!strcmp("kill", MODE)){ 53 | COUNT_SIGNAL = SIGUSR1; 54 | END_SIGNAL = SIGUSR2; 55 | } 56 | else if(!strcmp("queue", MODE)){ 57 | COUNT_SIGNAL = SIGUSR1; 58 | END_SIGNAL = SIGUSR2; 59 | } 60 | else if (!strcmp("sigrt", MODE)){ //real-time signals 61 | COUNT_SIGNAL = SIGRTMIN + 1; 62 | END_SIGNAL = SIGRTMIN + 2; 63 | } 64 | else{ 65 | printf("Wrong mode. Expected: [kill / queue / sigrt]\n"); 66 | exit(EXIT_FAILURE); 67 | } 68 | 69 | sigset_t mask; // set of signals blocked during operate current process 70 | sigfillset(&mask); // initialize set to full, including all signals 71 | sigdelset(&mask, COUNT_SIGNAL); // delete COUNT_SIGNAL and END_SIGNAL from set 72 | sigdelset(&mask, END_SIGNAL); 73 | 74 | // set mask for current process 75 | // SIG_BLOCK - the set of blocked signals is the union of the current set and the second argument set 76 | if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0){ 77 | printf("Cannot block signals\n"); 78 | exit(EXIT_FAILURE); 79 | } 80 | struct sigaction act; 81 | act.sa_flags = SA_SIGINFO; 82 | act.sa_sigaction = signalsHandle; 83 | 84 | sigemptyset(&act.sa_mask); 85 | sigaddset(&act.sa_mask, COUNT_SIGNAL); 86 | sigaddset(&act.sa_mask, END_SIGNAL); 87 | 88 | // change the action taken by a process on receipt of COUNT_SIGNAL AND END_SIGNAL 89 | sigaction(COUNT_SIGNAL, &act, NULL); 90 | sigaction(END_SIGNAL, &act, NULL); 91 | 92 | printf("Created catcher with PID: %d\n", getpid()); 93 | 94 | while (1){ 95 | usleep(100); // suspend execution of the calling thread for at least 100 microseconds 96 | } 97 | return 0; 98 | } -------------------------------------------------------------------------------- /cw05/zad1/main.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | const int MAX_LINE_LEN = 10000; 12 | const int MAX_COMMANDS = 20; 13 | const int MAX_ARGS = 10; 14 | 15 | void error(char *msg){ 16 | printf("%s\n", msg); 17 | exit(EXIT_FAILURE); 18 | } 19 | 20 | // separate words in given command and save them to array 21 | void separate_words(char **row, char*command){ 22 | char* cmd_tmp = command; 23 | char*arg = strtok_r(command, " ", &cmd_tmp); 24 | int i = 0; 25 | while(arg != NULL && arg[0] != EOF){ 26 | row[i] = arg; 27 | i ++; 28 | arg = strtok_r(NULL, " ", &cmd_tmp); 29 | } 30 | } 31 | 32 | 33 | int main(int argc, char **argv){ 34 | if (argc != 2){ 35 | error("Wrong number of arguments. Expected: [path]"); 36 | } 37 | 38 | FILE *file = fopen(argv[1], "r"); 39 | if (file == NULL){ 40 | error("Cannot open file"); 41 | } 42 | 43 | char *line = malloc(MAX_LINE_LEN); 44 | 45 | while(fgets(line, MAX_LINE_LEN, file) != NULL){ 46 | 47 | if (line[strlen(line) - 1] == '\n'){ 48 | line[strlen(line) - 1] = '\0'; 49 | } 50 | printf("%s\n", line); 51 | 52 | char* commands [MAX_COMMANDS][MAX_ARGS]; 53 | 54 | for (int i = 0; i < MAX_COMMANDS; i ++){ 55 | for (int j = 0; j < MAX_ARGS; j++){ 56 | commands[i][j] = NULL; 57 | } 58 | } 59 | 60 | char *cmd_tmp = line; 61 | char *cmd = strtok_r(line, "|", &cmd_tmp); 62 | int command_count = 0; 63 | 64 | while(cmd != NULL){ 65 | separate_words(commands[command_count], cmd); 66 | command_count ++; 67 | cmd = strtok_r(NULL, "|", &cmd_tmp); 68 | } 69 | 70 | int pipes[MAX_COMMANDS][2]; 71 | 72 | for (int i = 0; i < command_count - 1; i ++){ 73 | if (pipe(pipes[i]) < 0){ 74 | error("Cannot make pipes."); 75 | } 76 | } 77 | 78 | for (int i = 0; i < command_count; i++){ 79 | pid_t pid = fork(); 80 | 81 | if (pid < 0){ 82 | error("Cannot fork."); 83 | } 84 | else if (pid == 0){ 85 | if (i > 0){ 86 | dup2(pipes[i-1][0], STDIN_FILENO); 87 | } 88 | if (i < command_count - 1){ 89 | dup2(pipes[i][1], STDOUT_FILENO); 90 | } 91 | 92 | for (int j = 0; j < command_count - 1; j ++){ 93 | close(pipes[j][0]); 94 | close(pipes[j][1]); 95 | } 96 | 97 | execvp(commands[i][0], commands[i]); 98 | exit(0); 99 | } 100 | } 101 | 102 | for (int j = 0; j < command_count - 1; j ++){ 103 | close(pipes[j][0]); 104 | close(pipes[j][1]); 105 | } 106 | 107 | for (int j = 0; j < command_count; j ++){ 108 | wait(0); 109 | } 110 | } 111 | 112 | free(line); 113 | fclose(file); 114 | 115 | return 0; 116 | } -------------------------------------------------------------------------------- /cw04/zad4b/sender.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int COUNT_SIGNAL; 11 | int END_SIGNAL; 12 | char* MODE; 13 | 14 | int catcherPID; 15 | int signalsToSend; 16 | int receivedSignals; 17 | 18 | union sigval val; 19 | int signalsSent = 0; 20 | 21 | void sendNextSignal(){ 22 | signalsSent ++; 23 | if (!strcmp("kill", MODE) || !strcmp("sigrt", MODE)){ 24 | // send COUNT_SIGNAL to a process with catcherPID 25 | kill(catcherPID, COUNT_SIGNAL); 26 | } 27 | else{ 28 | // send COUNT_SIGNAL to a process with catcherPID with given value 29 | sigqueue(catcherPID, COUNT_SIGNAL, val); 30 | } 31 | } 32 | 33 | void sendEndSignal(){ 34 | if (!strcmp("kill", MODE) || !strcmp("sigrt", MODE)){ 35 | // send END_SIGNAL to a process with catcherPID 36 | kill(catcherPID, END_SIGNAL); 37 | } 38 | else{ 39 | // send END_SIGNAL to a process with catcherPID with given value 40 | sigqueue(catcherPID, END_SIGNAL, val); 41 | } 42 | } 43 | 44 | void signalsHandle(int sig, siginfo_t *info, void *uncontext){ 45 | if (sig == COUNT_SIGNAL){ 46 | receivedSignals ++; 47 | if (signalsSent < signalsToSend){ 48 | sendNextSignal(); 49 | } 50 | else{ 51 | sendEndSignal(); 52 | } 53 | } 54 | else if (sig == END_SIGNAL){ 55 | printf("Sender received: %d signals, expected: %d\n", receivedSignals, signalsToSend); 56 | exit(0); 57 | } 58 | } 59 | 60 | int main(int argc, char **argv){ 61 | // argv[1] = catcher's PID 62 | // argv[2] = number of signals to send 63 | // argv[3] = mode of sending signal 64 | 65 | if (argc != 4){ 66 | printf("Wrong number of arguments. Expected: [catcher's PID] [number of signals to send] [mode: kill / queue / sigrt]\n"); 67 | exit(EXIT_FAILURE); 68 | } 69 | catcherPID = atoi(argv[1]); 70 | signalsToSend = atoi(argv[2]); 71 | MODE = argv[3]; 72 | 73 | if (!strcmp("kill", MODE)){ 74 | COUNT_SIGNAL = SIGUSR1; 75 | END_SIGNAL = SIGUSR2; 76 | } 77 | else if (!strcmp("queue", MODE)){ 78 | COUNT_SIGNAL = SIGUSR1; 79 | END_SIGNAL = SIGUSR2; 80 | } 81 | else if (!strcmp("sigrt", MODE)){ 82 | COUNT_SIGNAL = SIGRTMIN + 1; 83 | END_SIGNAL = SIGRTMIN + 2; 84 | } 85 | else{ 86 | printf("Wrong mode. Expected: [kill / queue / sigrt]\n"); 87 | exit(EXIT_FAILURE); 88 | } 89 | 90 | sigset_t mask; 91 | sigfillset(&mask); 92 | sigdelset(&mask, COUNT_SIGNAL); 93 | sigdelset(&mask, END_SIGNAL); 94 | 95 | if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0){ 96 | printf("Cannot block signals\n"); 97 | exit(EXIT_FAILURE); 98 | } 99 | 100 | struct sigaction act; 101 | act.sa_flags = SA_SIGINFO; 102 | act.sa_sigaction = signalsHandle; 103 | 104 | sigemptyset(&act.sa_mask); 105 | sigaddset(&act.sa_mask, COUNT_SIGNAL); 106 | sigaddset(&act.sa_mask, END_SIGNAL); 107 | 108 | sigaction(COUNT_SIGNAL, &act, NULL); 109 | sigaction(END_SIGNAL, &act, NULL); 110 | 111 | printf("Created sender with PID: %d\n", getpid()); 112 | 113 | sendNextSignal(); 114 | 115 | while (1){ 116 | usleep(100); 117 | } 118 | return 0; 119 | 120 | } -------------------------------------------------------------------------------- /cw01/zad3a/main_dyn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | clock_t startTime, endTime; 11 | struct tms startCpu, endCpu; 12 | 13 | FILE *resultFile; 14 | void* handle; 15 | 16 | void startTimer(){ 17 | startTime = times(&startCpu); 18 | } 19 | void endTimer(){ 20 | endTime = times(&endCpu); 21 | } 22 | 23 | void writeResultToFile(FILE* file, char* name){ 24 | endTimer(); 25 | double realTime = (double) (endTime - startTime) / sysconf(_SC_CLK_TCK); 26 | double userTime = (double) (endCpu.tms_utime - startCpu.tms_utime) / sysconf(_SC_CLK_TCK); 27 | double systemTime = (double)(endCpu.tms_stime - startCpu.tms_stime) / sysconf(_SC_CLK_TCK); 28 | fprintf(file, "Operation: %s\n", name); 29 | fprintf(file, "Real time: %f\n", realTime); 30 | fprintf(file, "User time: %f\n", userTime); 31 | fprintf(file, "System time: %f\n\n", systemTime); 32 | 33 | printf("Operation: %s\n", name); 34 | printf("Real time: %f\n", realTime); 35 | printf("User time: %f\n", userTime); 36 | printf("System time: %f\n\n", systemTime); 37 | } 38 | 39 | 40 | 41 | int main(int argc, char**argv) { 42 | handle = dlopen("../zad1/lib_diff.so", RTLD_LAZY); 43 | if (!handle){ 44 | printf("Cannot find lib_diff.so"); 45 | exit(EXIT_FAILURE); 46 | } 47 | 48 | struct MainArray* (*createArray)(); 49 | void (*deleteBlock)(); 50 | void (*deleteOperation)(); 51 | void (*deleteArray)(); 52 | void (*comparePairs)(); 53 | 54 | createArray = dlsym(handle, "createArray"); 55 | deleteBlock = dlsym(handle, "deleteBlock"); 56 | deleteOperation = dlsym(handle, "deleteOperation"); 57 | deleteArray = dlsym(handle, "deleteArray"); 58 | comparePairs = dlsym(handle, "comparePairs"); 59 | 60 | if (argc < 3){ 61 | printf("Number of argument must be at least 3"); 62 | return -1; 63 | } 64 | if(strcmp(argv[1], "create_table") !=0 ){ 65 | printf("First argument has to be create_table"); 66 | return -1; 67 | } 68 | 69 | resultFile = fopen("raport.txt", "a"); 70 | 71 | int numberOfBlocks = atoi(argv[2]); 72 | struct MainArray* mainArray = createArray(numberOfBlocks); 73 | int i = 3; 74 | char* operation; 75 | while (i < argc){ 76 | startTimer(); 77 | 78 | if (!strcmp(argv[i], "compare_pairs")){ 79 | comparePairs(argv[i+1], mainArray); 80 | i += 2; 81 | operation = "compare_pairs"; 82 | } 83 | else if (!strcmp(argv[i], "remove_operation")){ 84 | int indexOfBlock = atoi(argv[i + 1]); 85 | int indexOfOperation = atoi(argv[i + 2]); 86 | deleteOperation(mainArray, indexOfBlock, indexOfOperation); 87 | i += 3; 88 | operation = "remove_operation"; 89 | } 90 | else if (!strcmp(argv[i], "remove_block")){ 91 | int indexOfBlock = atoi(argv[i + 1]); 92 | deleteBlock(mainArray, indexOfBlock); 93 | i += 2; 94 | operation = "remove_block"; 95 | } 96 | else{ 97 | operation = "wrong operation"; 98 | i ++; 99 | } 100 | writeResultToFile(resultFile, operation); 101 | } 102 | deleteArray(mainArray); 103 | dlclose(handle); 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /cw01/zad3b/main_dyn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | clock_t startTime, endTime; 11 | struct tms startCpu, endCpu; 12 | 13 | FILE *resultFile; 14 | void* handle; 15 | 16 | void startTimer(){ 17 | startTime = times(&startCpu); 18 | } 19 | void endTimer(){ 20 | endTime = times(&endCpu); 21 | } 22 | 23 | void writeResultToFile(FILE* file, char* name){ 24 | endTimer(); 25 | double realTime = (double) (endTime - startTime) / sysconf(_SC_CLK_TCK); 26 | double userTime = (double) (endCpu.tms_utime - startCpu.tms_utime) / sysconf(_SC_CLK_TCK); 27 | double systemTime = (double)(endCpu.tms_stime - startCpu.tms_stime) / sysconf(_SC_CLK_TCK); 28 | fprintf(file, "Operation: %s\n", name); 29 | fprintf(file, "Real time: %f\n", realTime); 30 | fprintf(file, "User time: %f\n", userTime); 31 | fprintf(file, "System time: %f\n\n", systemTime); 32 | 33 | printf("Operation: %s\n", name); 34 | printf("Real time: %f\n", realTime); 35 | printf("User time: %f\n", userTime); 36 | printf("System time: %f\n\n", systemTime); 37 | } 38 | 39 | 40 | 41 | int main(int argc, char**argv) { 42 | handle = dlopen("../zad1/lib_diff.so", RTLD_LAZY); 43 | if (!handle){ 44 | printf("Cannot find lib_diff.so"); 45 | exit(EXIT_FAILURE); 46 | } 47 | 48 | struct MainArray* (*createArray)(); 49 | void (*deleteBlock)(); 50 | void (*deleteOperation)(); 51 | void (*deleteArray)(); 52 | void (*comparePairs)(); 53 | 54 | createArray = dlsym(handle, "createArray"); 55 | deleteBlock = dlsym(handle, "deleteBlock"); 56 | deleteOperation = dlsym(handle, "deleteOperation"); 57 | deleteArray = dlsym(handle, "deleteArray"); 58 | comparePairs = dlsym(handle, "comparePairs"); 59 | 60 | if (argc < 3){ 61 | printf("Number of argument must be at least 3"); 62 | return -1; 63 | } 64 | if(strcmp(argv[1], "create_table") !=0 ){ 65 | printf("First argument has to be create_table"); 66 | return -1; 67 | } 68 | 69 | resultFile = fopen("raport.txt", "a"); 70 | 71 | int numberOfBlocks = atoi(argv[2]); 72 | struct MainArray* mainArray = createArray(numberOfBlocks); 73 | int i = 3; 74 | char* operation; 75 | while (i < argc){ 76 | startTimer(); 77 | 78 | if (!strcmp(argv[i], "compare_pairs")){ 79 | comparePairs(argv[i+1], mainArray); 80 | i += 2; 81 | operation = "compare_pairs"; 82 | } 83 | else if (!strcmp(argv[i], "remove_operation")){ 84 | int indexOfBlock = atoi(argv[i + 1]); 85 | int indexOfOperation = atoi(argv[i + 2]); 86 | deleteOperation(mainArray, indexOfBlock, indexOfOperation); 87 | i += 3; 88 | operation = "remove_operation"; 89 | } 90 | else if (!strcmp(argv[i], "remove_block")){ 91 | int indexOfBlock = atoi(argv[i + 1]); 92 | deleteBlock(mainArray, indexOfBlock); 93 | i += 2; 94 | operation = "remove_block"; 95 | } 96 | else{ 97 | operation = "wrong operation"; 98 | i ++; 99 | } 100 | writeResultToFile(resultFile, operation); 101 | } 102 | deleteArray(mainArray); 103 | dlclose(handle); 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /cw08/README.md: -------------------------------------------------------------------------------- 1 | # Wątki - podstawy 2 | ## Zadanie 1. 3 | 4 | Napisz program współbieżnie wyliczający histogram dla obrazu o wymiarze nxm przy użyciu wątków, zakładając, że obraz jest macierzą reprezentującą obraz. Dla uproszczenia rozważamy jedynie obrazy w 256 odcieniach szarości. Każdy element macierzy jest więc liczbą całkowitą z zakresu 0 do 255. Program należy zaimplementować w różnych wariantach: 5 | 6 | **Wariant 1**: Podział zadania na podzadania odbywa się na zasadzie dekompozycji w dziedzinie problemu, gdzie dziedziną jest zbiór liczb - każdy wątek zlicza wystąpienia dla określonego zestawu liczb. Zbiór liczb dla wątku można przydzielić w dowolny sposób, ale taki, by każdy wątek dostał inne liczby i zadanie było podzielone równo na wszystkie wątki. (30%) 7 | 8 | **Wariant 2**: Podział dokonywany w dziedzinie problemu dotyczącego obrazu, a nie znaków. 9 | 10 | * Podział blokowy – k-ty wątek zlicza wartości pikseli w pionowym pasku o współrzędnych x-owych w przedziale od `(k−1)∗ceil(N/m)` do `k∗ceil(N/m)−1`, gdzie `N` to szerokość wyjściowego obrazu a `m` to liczba stworzonych wątków. (35%) 11 | * Podział cykliczny – k-ty wątek zlicza wartości pikseli, których współrzędne x-owe to: k−1, k−1+m, k−1+2∗m, k−1+3∗m, itd. (ponownie, m to liczba stworzonych wątków). (35%) 12 | 13 | Program przyjmuje następujące argumenty: 14 | 15 | 1. liczbę wątków, 16 | 2. sposób podziału obrazu pomiędzy wątki, t.j. jedną z trzech opcji: `sign / block / interleaved`, 17 | 3. nazwę pliku z wejściowym obrazem, 18 | 4. nazwę pliku wynikowego. 19 | 20 | Po wczytaniu danych (wejściowy obraz) wątek główny tworzy tyle nowych wątków, ile zażądano w argumencie wywołania. Utworzone wątki równolegle tworzą histogram obrazu. Każdy stworzony wątek odpowiada za wygenerowanie części histogramu obrazu. Po wykonaniu obliczeń wątek kończy pracę i zwraca jako wynik (patrz `pthread_exit`) czas rzeczywisty spędzony na tworzeniu przydzielonej mu części wyjściowego obrazu. Czas ten należy zmierzyć z dokładnością do mikrosekund. 21 | 22 | Wątek główny czeka na zakończenie pracy przez wątki wykonujące podzadania. Po zakończeniu każdego wątku, wątek główny odczytuje wynik jego działania i wypisuje na ekranie informację o czasie, jaki zakończony wątek poświęcił na zliczanie (wraz z identyfikatorem zakończonego wątku). Dodatkowo, po zakończeniu pracy przez wszystkie stworzone wątki, wątek główny zapisuje powstały histogram (w formie linii zawierających zliczany odcień oraz liczbę jego wystąpień) do pliku wynikowego i wypisuje na ekranie czas rzeczywisty spędzony na wykonaniu zadania (z dokładnością do mikrosekund). W czasie całkowitym należy uwzględnić narzut związany z utworzeniem i zakończeniem wątków (ale bez czasu operacji wejścia/wyjścia). 23 | 24 | Wykonaj pomiary czasu operacji dla obrazu o rozmiarze kilkaset na kilkaset pikseli. Eksperymenty wykonaj dla wszystkich trzech wariantów podziału obrazu pomiędzy wątki. Testy przeprowadź dla 1, 2, 4, i 8 wątków. Wyniki (czasy dla każdego wątku oraz całkowity czas wykonania zadania w zależności od wariantu) zamieść w pliku Times.txt i dołącz do archiwum z rozwiązaniem zadania. 25 | 26 | ## Format wejścia-wyjścia 27 | Program powinien odczytywać i zapisywać obrazy w formacie ASCII PGM (Portable Gray Map). Pliki w tym formacie mają nagłówek postaci: 28 | 29 | P2 30 | 31 | W H 32 | 33 | M 34 | 35 | ... 36 | 37 | gdzie: W to szerokość obrazu w pikselach, H to wysokość obrazu w pikselach a M to maksymalna wartość piksela. Zakładamy, że obsługujemy jedynie obrazy w 256 odcieniach szarości: od 0 do 255 (a więc **M=255**). Po nagłówku, w pliku powinno być zapisanych W*H liczb całkowitych reprezentujących wartości kolejnych pikseli. Liczby rozdzielone są białymi znakami (np. spacją). Piksele odczytywane są wierszami, w kolejności od lewego górnego do prawego dolnego rogu obrazu. -------------------------------------------------------------------------------- /cw05/README.md: -------------------------------------------------------------------------------- 1 | # Potoki nazwane i nienazwane 2 | ## Zadanie 1 (50%) 3 | Napisz interpreter poleceń przechowywanych w pliku. Ścieżka do pliku to pierwszy argument wywołania programu. 4 | 5 | Polecenia w pliku przechowywane są w kolejnych liniach w postaci: 6 | 7 | prog1 arg1 ... argn1 | prog2 arg1 ... argn2 | ... | progN arg1 ... argnN 8 | 9 | - Interpreter powinien uruchomić wszystkie N poleceń w osobnych procesach, zapewniając przy użyciu potoków nienazwanych oraz funkcji dup2, by wyjście standardowe procesu k było przekierowane do wejścia standardowego procesu (k+1) 10 | - Można założyć ograniczenie górne na ilość obsługiwanych argumentów oraz ilość połączonych komend w pojedynczym poleceniu (co najmniej 3). 11 | - Po uruchomieniu ciągu programów składających się na pojedyncze polecenie (linijkę) interpreter powinien oczekiwać na zakończenie wszystkich tych programów. 12 | 13 | Program należy zaimplementować w dwóch wariantach: 14 | - Korzystając z funkcji pipe/fork/exec (50%) 15 | - Korzystając z popen (10%) 16 | ## Zadanie 2 (10%) 17 | Napisać program przyjmujący jeden argument - ścieżkę do pliku tekstowego zawierających kilka linii tekstu (dowolne znaki). Wykorzystując popen oraz komendę sort posortować linie podanego pliku tekstowego (posortowane linie mają być wypisane na ekran). 18 | ## Zadanie 3 (40%) 19 | W problemie producenta i konsumenta występują dwa rodzaje procesów, które dzielą wspólny bufor dla produkowanych i konsumowanych jednostek. Zadaniem producenta jest wytworzenie surowca, umieszczenie go w buforze i rozpoczęcie pracy od nowa. Konsument pobiera surowiec z bufora i wykorzystuje go. 20 | 21 | Przy pomocy potoków nazwanych zaimplementować problem Producenta i Konsumenta. Napisać dwa niezależne programy - Producent oraz Konsument, które będą komunikować się poprzez potok nazwany (kolejkę FIFO). Do potoku pisać będzie wiele procesów wykonujących program Producenta, a czytał będzie z niej jeden proces Konsumenta. Dla zademonstrowania, że nie doszło do utraty ani zwielokrotnienia towaru surowiec będzie pobierany z pliku przez Producenta i umieszczany w innym pliku przez Konsumenta. 22 | 23 | Producent: 24 | 25 | - przyjmuje trzy argumenty: ścieżka do potoku nazwanego, ścieżka do pliku tekstowego z dowolną zawartością, N - liczba znaków odczytywanych jednorazowo z pliku 26 | - otwiera potok nazwany 27 | - wielokrotnie (aż do odczytania całego pliku): 28 | - odczekuje losową ilość czasu (np. 1-2 sekund) 29 | - zapisuje do potoku nazwanego linię zawierającą swój PID oraz odczytany fragment pliku w następującej formie: #PID#(N odczytanych znaków) 30 | 31 | Konsument: 32 | 33 | - przyjmuje trzy argumenty: ścieżka do potoku nazwanego, ścieżka do pliku tekstowego (do którego będzie zapisywany odczytany tekst), N - liczba znaków odczytywanych jednorazowo z pliku 34 | - otwiera potok nazwany 35 | - wielokrotnie: 36 | - czyta kolejnych N znaków potoku nazwanego 37 | - umieszcza odczytane znaki w pliku tekstowym (różnym od plików, z których korzystają producenci) 38 | 39 | Pliki tekstowe powinny być krótkie (na 5-10 odczytów) i umożliwiać sprawdzenie poprawności działania (brak utraty, zwielokrotnienia surowca). W szczególności każdy Producent powinien otrzymać wygenerowany w dowolny sposób plik tekstowy z dowolną zawartością, ale w istotny sposób różniącą się od zawartości plików innych Producentów. Na przykład jeden producent może otrzymać plik zawierający tylko konkretną literę, inny tylko liczby itd. 40 | 41 | Sprawdzić, że potoki nazwane działają dla niezależnych procesów - utworzyć potok z linii komend, a następnie uruchomić Producenta i Konsumenta w różnych terminalach. Dodatkowo należy napisać program, który tworzy potok nazwany, a następnie uruchamia program Konsumenta i pięciu Producentów (z różnymi argumentami). 42 | -------------------------------------------------------------------------------- /cw03/zad1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #define __USE_XOPEN_EXTENDED 1 13 | #include 14 | #include 15 | 16 | void find_dir(char *path){ 17 | 18 | if (path == NULL) return; 19 | DIR* dir = opendir(path); 20 | if (dir == NULL){ 21 | printf("Cannot open directory\n"); 22 | exit(EXIT_FAILURE); 23 | } 24 | 25 | struct stat buffer; 26 | lstat(path, &buffer); 27 | if (S_ISDIR(buffer.st_mode)){ 28 | pid_t pid_fork = fork(); 29 | 30 | if (pid_fork < 0){ 31 | printf("Cannot fork\n"); 32 | exit(EXIT_FAILURE); 33 | } 34 | 35 | else if(pid_fork == 0){ 36 | 37 | // get process ID (PID) of the calling process 38 | printf("DIRECTORY: %s, PID: %d\n", path, getpid()); 39 | 40 | // replace the current process image with a new process image 41 | int exec_status = execlp("ls", "ls", "-l", path, NULL); 42 | if (exec_status != 0){ 43 | printf("Exec failed"); 44 | exit(EXIT_FAILURE); 45 | } 46 | exit(exec_status); 47 | } 48 | 49 | else{ 50 | wait(0); 51 | } 52 | } 53 | 54 | 55 | struct dirent *file; 56 | char new_path[256]; 57 | while ((file = readdir(dir)) != NULL){ 58 | strcpy(new_path, path); 59 | strcat(new_path, "/"); 60 | strcat(new_path, file -> d_name); 61 | 62 | // check information about a file 63 | if (lstat(new_path, &buffer) < 0){ 64 | printf("Cannot lstat file %s: ", new_path); 65 | exit(EXIT_FAILURE); 66 | } 67 | 68 | // check if file is a directory 69 | if (S_ISDIR(buffer.st_mode)){ 70 | 71 | if (strcmp(file -> d_name, ".") == 0 || strcmp(file -> d_name, "..") == 0){ 72 | continue; 73 | } 74 | find_dir(new_path); 75 | } 76 | } 77 | closedir(dir); 78 | } 79 | 80 | static int find_nftw(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf){ 81 | if (S_ISDIR(sb -> st_mode)){ 82 | pid_t pid_fork = fork(); 83 | 84 | if (pid_fork < 0){ 85 | printf("Cannot fork\n"); 86 | exit(EXIT_FAILURE); 87 | } 88 | 89 | else if(pid_fork == 0){ 90 | 91 | // get process ID (PID) of the calling process 92 | printf("DIRECTORY: %s, PID: %d\n", fpath, getpid()); 93 | 94 | // replace the current process image with a new process image 95 | int exec_status = execlp("ls", "ls", "-l", fpath, NULL); 96 | if (exec_status != 0){ 97 | printf("Exec failed"); 98 | exit(EXIT_FAILURE); 99 | } 100 | exit(exec_status); 101 | } 102 | 103 | else{ 104 | wait(0); 105 | } 106 | } 107 | return 0; 108 | } 109 | 110 | int main(int argc, char** argv){ 111 | if (argc < 2){ 112 | printf("Wrong number of arguments\n"); 113 | exit(EXIT_FAILURE); 114 | } 115 | 116 | char* path = argv[1]; 117 | int is_nftw = 0; 118 | 119 | if (argc == 3 && !strcmp(argv[2], "nftw")){ 120 | is_nftw = 1; 121 | } 122 | 123 | if (is_nftw == 1) { 124 | nftw(path, find_nftw, 10, FTW_PHYS); 125 | } 126 | else { 127 | find_dir(path); 128 | } 129 | 130 | return 0; 131 | } -------------------------------------------------------------------------------- /cw02/README.md: -------------------------------------------------------------------------------- 1 | # Pliki 2 | ## Zadanie 1. Porównanie wydajności systemowych i bibliotecznych funkcji We/Wy (55%) 3 | 4 | * (30%) Celem zadania jest napisanie programu porównującego wydajność systemowych oraz bibliotecznych funkcji wejścia/wyjścia. Program operował będzie na przechowywanej w pliku tablicy napisów (rekordów). Dla uproszczenia pojedynczy napis będzie miał stałą wielkość. Nazwa pliku, wielkość oraz liczba i długość napisów stanowić będą argumenty wywołania programu. 5 | 6 | Program udostępniać powinien operacje: 7 | 8 | * generate - tworzenie pliku z rekordami wypełnionego wygenerowaną losową zawartością (można wykorzystać wirtualny generator/dev/random) lub w wersji uproszczonej funkcję rand() 9 | * sort - sortuje rekordy w pliku (w porządku leksykograficznym), używając sortowania szybkiego. Kluczem do sortowania niech będzie wartość pierwszego napisu / rekordu. Podczas sortowania w pamięci powinny być przechowywane jednocześnie najwyżej dwa rekordy (porównywanie dwóch rekordów). 10 | * copy - kopiuje plik1 do pliku2. Kopiowanie powinno odbywać się za pomocą bufora o zadanej wielkości rekordu. 11 | 12 | Sortowanie i kopiowanie powinno być zaimplementowane w dwóch wariantach: 13 | 14 | * sys - przy użyciu funkcji systemowych: read i write 15 | * lib - przy użyciu funkcji biblioteki C: fread i fwrite 16 | 17 | Rodzaj operacji oraz sposób dostępu do plików ma być wybierany na podstawie argumentu wywołania, np.: 18 | 19 | ./program generate dane 100 512 powinno losowo generować 100 rekordów o długości 512 bajtów (znaków) 20 | do pliku dane, 21 | 22 | ./program sort dane 100 512 sys powinien sortować rekordy w pliku dane przy użyciu funkcji systemowych, 23 | zakładając że zawiera on 100 rekordów wielkości 512 bajtów 24 | 25 | ./program copy plik1 plik2 100 512 lib powinno skopiować 100 rekordów pliku 1 do pliku 2 za pomocą funkcji 26 | bibliotecznych z wykorzystaniem bufora 512 bajtów 27 | 28 | * (25%) Dla obu wariantów implementacji przeprowadź pomiary czasu użytkownika i czasu systemowego operacji sortowania i kopiowania. Testy wykonaj dla następujących rozmiarów rekordu: 1, 4, 512, 1024, 4096 i 8192 bajty. Dla każdego rozmiaru rekordu wykonaj dwa testy różniące się liczbą rekordów w sortowanym pliku. Liczby rekordów dobierz tak, by czas sortowania mieścił się w przedziale od kilku do kilkudziesięciu sekund. Porównując dwa warianty implementacji, należy korzystać z identycznego pliku do sortowania (po wygenerowaniu, a przed sortowaniem, utwórz jego kopię). Zmierzone czasy zestaw w pliku wyniki.txt. Do pliku dodaj komentarz podsumowujący wnioski z testów. 29 | 30 | ## Zadanie 2. Operacje na strukturze katalogów (45%) 31 | 32 | Napisz prosty odpowiednik programu find — program powinien implementować następujące opcje: '-mtime', '-atime' oraz '-maxdepth'. W przypadku dwóch pierwszych, podobnie jak w przypadku find, argumentem może być: liczba (bezwzględna), liczba poprzedzonej znakiem '+' lub liczba poprzedzona znakiem '-'. Program ma wypisać na standardowe wyjście następujące informacje o znalezionych plikach: 33 | 34 | * ścieżka bezwzględna pliku, 35 | * liczbę dowiązań 36 | * rodzaj pliku (zwykły plik - file, katalog - dir, urządzenie znakowe - char dev, urządzenie blokowe - block dev, potok nazwany - fifo, link symboliczny - slink, soket - sock) 37 | * rozmiar w bajtach, 38 | * datę ostatniego dostępu, 39 | * datę ostatniej modyfikacji. 40 | 41 | Ścieżka podana jako argument wywołania może być względna lub bezwzględna. Program nie powinien podążać za dowiązaniami symbolicznymi do katalogów. 42 | 43 | Program należy zaimplementować w dwóch wariantach: 44 | 45 | 1. Korzystając z funkcji opendir(), readdir() oraz funkcji z rodziny stat (25%) 46 | 2. Korzystając z funkcji nftw() (20%) 47 | 48 | W ramach testowania funkcji utwórz w badanej strukturze katalogów jakieś dowiązania symboliczne, zwykłe pliki i katalogi. 49 | -------------------------------------------------------------------------------- /cw10/zad1/common.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSOPY_COMMON_H 2 | #define SYSOPY_COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define MAX_CLIENTS 13 24 | #define MSG_SIZE 20 25 | #define NAME_LEN 8 26 | 27 | #define PING_INTERVAL 10 28 | #define PING_WAIT 5 29 | 30 | enum connection_type{ 31 | LOCAL, 32 | INET 33 | }; typedef enum connection_type connection_type; 34 | 35 | enum message_type{ 36 | CONNECT, 37 | CONNECT_FAILED, 38 | PING, 39 | WAIT, 40 | GAME_FOUND, 41 | MOVE, 42 | GAME_FINISHED, 43 | DISCONNECT, 44 | EMPTY 45 | }; typedef enum message_type message_type; 46 | 47 | struct game{ 48 | char board[9]; 49 | char turn; 50 | char winner; // -/O/X/D 51 | }; typedef struct game game; 52 | 53 | struct message{ 54 | message_type message_type; 55 | game game; 56 | char name[NAME_LEN]; 57 | }; typedef struct message message; 58 | 59 | struct client{ 60 | int fd; 61 | char* name; 62 | game* game; 63 | int active; 64 | int opponent_idx; 65 | char symbol; // O/X 66 | }; typedef struct client client; 67 | 68 | void error_exit(char* message){ 69 | printf("ERROR: %s\n", message); 70 | exit(EXIT_FAILURE); 71 | } 72 | 73 | void new_board(game* game){ 74 | for(int i = 0; i < 9; i++) game->board[i] = '-'; 75 | game->turn = 'O'; 76 | game->winner = '-'; 77 | } 78 | 79 | void send_message(int fd, message_type type, game* game, char* name){ 80 | char* message = calloc(MSG_SIZE, sizeof(char)); 81 | if(type == CONNECT) sprintf(message, "%d %s", (int) type, name); 82 | else if(game == NULL) sprintf(message, "%d", (int) type); 83 | else sprintf(message, "%d %s %c %c", (int) type, game->board, game->turn, game->winner); 84 | 85 | if(write(fd, message, MSG_SIZE) < 0) error_exit("Cannot send message."); 86 | free(message); 87 | } 88 | 89 | message receive_message(int fd, int nonblocking){ 90 | 91 | message msg; 92 | int count; // number of bytes received 93 | char* buffer = calloc(MSG_SIZE, sizeof(char)); 94 | 95 | if (nonblocking && (count = recv(fd, buffer, MSG_SIZE, MSG_DONTWAIT)) < 0){ // revceive message from socket 96 | msg.message_type = EMPTY; 97 | free(buffer); 98 | return msg; 99 | } 100 | else if(!nonblocking && (count = read(fd, buffer, MSG_SIZE)) < 0) error_exit("Cannot receive message."); 101 | if(count == 0){ 102 | msg.message_type = DISCONNECT; 103 | free(buffer); 104 | return msg; 105 | } 106 | 107 | char* token; 108 | char* rest = buffer; 109 | strcpy(msg.name, ""); 110 | new_board(&msg.game); 111 | token = strtok_r(rest, " ", &rest); 112 | 113 | if (nonblocking) { 114 | char* p; 115 | msg.message_type = (message_type) strtol(token, &p, 10); 116 | } 117 | else msg.message_type = (message_type) atoi(token); 118 | 119 | if (msg.message_type == CONNECT){ 120 | token = strtok_r(rest, " ", &rest); 121 | strcpy(msg.name, token); 122 | } 123 | else if (!nonblocking && (msg.message_type == PING || msg.message_type == DISCONNECT || msg.message_type == WAIT)){ 124 | free(buffer); 125 | return msg; 126 | } 127 | else if (msg.message_type == MOVE || msg.message_type == GAME_FINISHED || msg.message_type == GAME_FOUND){ 128 | token = strtok_r(rest, " ", &rest); 129 | strcpy(msg.game.board, token); 130 | token = strtok_r(rest, " ", &rest); 131 | msg.game.turn = token[0]; 132 | token = strtok_r(rest, " ", &rest); 133 | msg.game.winner = token[0]; 134 | } 135 | 136 | free(buffer); 137 | return msg; 138 | } 139 | 140 | #endif //SYSOPY_COMMON_H -------------------------------------------------------------------------------- /cw08/zad1/Times.txt: -------------------------------------------------------------------------------- 1 | 2 | ______ sign => 1 threads ______ 3 | Thread: 1, time: 0 seconds 1 miliseconds 580 microseconds 4 | Full time: 0 seconds 3 miliseconds 149 microseconds 5 | 6 | ______ block => 1 threads ______ 7 | Thread: 1, time: 0 seconds 0 miliseconds 842 microseconds 8 | Full time: 0 seconds 1 miliseconds 451 microseconds 9 | 10 | ______ interleaved => 1 threads ______ 11 | Thread: 1, time: 0 seconds 0 miliseconds 964 microseconds 12 | Full time: 0 seconds 1 miliseconds 500 microseconds 13 | 14 | ______ sign => 2 threads ______ 15 | Thread: 1, time: 0 seconds 1 miliseconds 501 microseconds 16 | Thread: 2, time: 0 seconds 1 miliseconds 463 microseconds 17 | Full time: 0 seconds 6 miliseconds 564 microseconds 18 | 19 | ______ block => 2 threads ______ 20 | Thread: 1, time: 0 seconds 0 miliseconds 443 microseconds 21 | Thread: 2, time: 0 seconds 0 miliseconds 485 microseconds 22 | Full time: 0 seconds 1 miliseconds 114 microseconds 23 | 24 | ______ interleaved => 2 threads ______ 25 | Thread: 1, time: 0 seconds 0 miliseconds 766 microseconds 26 | Thread: 2, time: 0 seconds 0 miliseconds 817 microseconds 27 | Full time: 0 seconds 1 miliseconds 809 microseconds 28 | 29 | ______ sign => 4 threads ______ 30 | Thread: 1, time: 0 seconds 1 miliseconds 174 microseconds 31 | Thread: 2, time: 0 seconds 1 miliseconds 594 microseconds 32 | Thread: 3, time: 0 seconds 1 miliseconds 603 microseconds 33 | Thread: 4, time: 0 seconds 1 miliseconds 732 microseconds 34 | Full time: 0 seconds 16 miliseconds 264 microseconds 35 | 36 | ______ block => 4 threads ______ 37 | Thread: 1, time: 0 seconds 0 miliseconds 269 microseconds 38 | Thread: 2, time: 0 seconds 0 miliseconds 267 microseconds 39 | Thread: 3, time: 0 seconds 0 miliseconds 238 microseconds 40 | Thread: 4, time: 0 seconds 0 miliseconds 277 microseconds 41 | Full time: 0 seconds 3 miliseconds 894 microseconds 42 | 43 | ______ interleaved => 4 threads ______ 44 | Thread: 1, time: 0 seconds 0 miliseconds 218 microseconds 45 | Thread: 2, time: 0 seconds 0 miliseconds 218 microseconds 46 | Thread: 3, time: 0 seconds 0 miliseconds 252 microseconds 47 | Thread: 4, time: 0 seconds 0 miliseconds 254 microseconds 48 | Full time: 0 seconds 3 miliseconds 888 microseconds 49 | 50 | ______ sign => 8 threads ______ 51 | Thread: 1, time: 0 seconds 0 miliseconds 981 microseconds 52 | Thread: 2, time: 0 seconds 1 miliseconds 319 microseconds 53 | Thread: 3, time: 0 seconds 1 miliseconds 452 microseconds 54 | Thread: 4, time: 0 seconds 10 miliseconds 249 microseconds 55 | Thread: 5, time: 0 seconds 1 miliseconds 528 microseconds 56 | Thread: 6, time: 0 seconds 1 miliseconds 321 microseconds 57 | Thread: 7, time: 0 seconds 1 miliseconds 138 microseconds 58 | Thread: 8, time: 0 seconds 1 miliseconds 362 microseconds 59 | Full time: 0 seconds 21 miliseconds 449 microseconds 60 | 61 | ______ block => 8 threads ______ 62 | Thread: 1, time: 0 seconds 0 miliseconds 139 microseconds 63 | Thread: 2, time: 0 seconds 0 miliseconds 141 microseconds 64 | Thread: 3, time: 0 seconds 0 miliseconds 177 microseconds 65 | Thread: 4, time: 0 seconds 0 miliseconds 185 microseconds 66 | Thread: 5, time: 0 seconds 0 miliseconds 208 microseconds 67 | Thread: 6, time: 0 seconds 0 miliseconds 215 microseconds 68 | Thread: 7, time: 0 seconds 0 miliseconds 272 microseconds 69 | Thread: 8, time: 0 seconds 0 miliseconds 216 microseconds 70 | Full time: 0 seconds 7 miliseconds 382 microseconds 71 | 72 | ______ interleaved => 8 threads ______ 73 | Thread: 1, time: 0 seconds 0 miliseconds 120 microseconds 74 | Thread: 2, time: 0 seconds 0 miliseconds 111 microseconds 75 | Thread: 3, time: 0 seconds 0 miliseconds 114 microseconds 76 | Thread: 4, time: 0 seconds 0 miliseconds 114 microseconds 77 | Thread: 5, time: 0 seconds 0 miliseconds 119 microseconds 78 | Thread: 6, time: 0 seconds 0 miliseconds 181 microseconds 79 | Thread: 7, time: 0 seconds 0 miliseconds 245 microseconds 80 | Thread: 8, time: 0 seconds 0 miliseconds 160 microseconds 81 | Full time: 0 seconds 4 miliseconds 186 microseconds 82 | -------------------------------------------------------------------------------- /cw01/zad2/n.txt: -------------------------------------------------------------------------------- 1 | inventions 2 | inventive 3 | inventively 4 | inventiveness 5 | inventor 6 | inventoriable 7 | inventoried 8 | inventories 9 | inventors 10 | inventory 11 | invents 12 | inveraray 13 | invergordon 14 | inverness 15 | inverse 16 | inversely 17 | inverses 18 | inversion 19 | inversions 20 | invert 21 | invertebrate 22 | invertebrates 23 | inverted 24 | inverter 25 | inverters 26 | inverting 27 | inverts 28 | invest 29 | invested 30 | investigate 31 | investigated 32 | investigates 33 | investigating 34 | investigation 35 | investigations 36 | investigative 37 | investigator 38 | investigators 39 | investigatory 40 | investing 41 | investitive 42 | investiture 43 | investitures 44 | investment 45 | hypertext 46 | hyperthermia 47 | hyperthyroid 48 | coercion 49 | coercive 50 | coercively 51 | coeval 52 | coevals 53 | coexist 54 | coexisted 55 | coexistence 56 | hyperthyroidism 57 | investments 58 | investor 59 | investors 60 | invests 61 | inveteracy 62 | inveterate 63 | blaster 64 | blasting 65 | blastoffs 66 | inveterately 67 | blatancy 68 | blatant 69 | bighorn 70 | bighorns 71 | bight 72 | bights 73 | bigness 74 | bigot 75 | bigoted 76 | bigotry 77 | bigots 78 | bigwig 79 | bigwigs 80 | bijou 81 | bijoux 82 | bike 83 | biked 84 | biker 85 | bikers 86 | bikes 87 | bikeway 88 | bikeways 89 | biking 90 | bikini 91 | bikinis 92 | bilabial 93 | bilabials 94 | bilan 95 | bilateral 96 | bilberries 97 | bilberry 98 | bilbo 99 | bilboes 100 | bile 101 | bilge 102 | bilges 103 | bilharzia 104 | bilinear 105 | bilingual 106 | bilingualism 107 | bilious 108 | bilk 109 | bilked 110 | bilking 111 | bilks 112 | billets 113 | billfold 114 | billfolds 115 | billhook 116 | billhooks 117 | billiard 118 | billiards 119 | billing 120 | billingham 121 | billings 122 | billingsgate 123 | billion 124 | billionaire 125 | billionaires 126 | billions 127 | billionth 128 | zigzagging 129 | zigzags 130 | zilch 131 | zilches 132 | zillion 133 | zillions 134 | zillionth 135 | zillionths 136 | zimbabwe 137 | zimbabwean 138 | zimbabweans 139 | billionths 140 | billow 141 | billowed 142 | billowing 143 | billows 144 | billowy 145 | billposter 146 | billposters 147 | bimetallists 148 | bimodal 149 | bimolecular 150 | bimonthly 151 | bin 152 | binaries 153 | binary 154 | binaural 155 | bind 156 | binder 157 | binderies 158 | binders 159 | bindery 160 | binding 161 | bindings 162 | bindle 163 | bindles 164 | binds 165 | bindweed 166 | binge 167 | binged 168 | bingeing 169 | binges 170 | bingley 171 | bingo 172 | binnacle 173 | binnacles 174 | binned 175 | binocular 176 | binoculars 177 | binomial 178 | binomials 179 | bins 180 | binuclear 181 | bioassay 182 | biochemical 183 | biochemist 184 | biochemistry 185 | biochemists 186 | biodegradable 187 | bioengineering 188 | biofeedback 189 | biogenesis 190 | biograph 191 | biographer 192 | biographers 193 | biographic 194 | biographical 195 | biographically 196 | biographies 197 | biography 198 | biohazard 199 | biohazards 200 | biologic 201 | biological 202 | biologically 203 | biologist 204 | biologists 205 | biology 206 | bioluminescence 207 | bioluminescent 208 | biomass 209 | biome 210 | biomedical 211 | biomedicine 212 | biomes 213 | biometric 214 | biometrics 215 | biometry 216 | bionic 217 | bionics 218 | biophysical 219 | biophysicist 220 | biophysicists 221 | biophysics 222 | biopic 223 | biopics 224 | biopsies 225 | biopsy 226 | biorhythm 227 | biorhythmic 228 | biorhythms 229 | bios 230 | bioscopy 231 | biosphere 232 | biosynthesis 233 | biosynthesise 234 | biosynthesised 235 | biosynthesize 236 | biosynthesized 237 | biosynthetic 238 | biota 239 | biotechnological 240 | biotechnology 241 | biotic 242 | biotin 243 | bipartisan 244 | bipartite 245 | biped 246 | bipedal 247 | bipeds 248 | biphenyl 249 | biplane 250 | biplanes 251 | bipolar 252 | birch 253 | birches 254 | bird 255 | birdbath 256 | birdbaths 257 | birdbrain 258 | birdbrains 259 | birdcage 260 | birdcages 261 | birdcall 262 | birdcalls 263 | birder 264 | birders 265 | birdhouse 266 | birdhouses 267 | birdie 268 | birdied 269 | birdies 270 | birdlike 271 | birds 272 | birdseed 273 | birdseeds 274 | birdsong 275 | birdying 276 | birefringence 277 | abandonment 278 | birthplace 279 | birthplaces 280 | -------------------------------------------------------------------------------- /cw03/README.md: -------------------------------------------------------------------------------- 1 | # Tworzenie procesów. Środowisko procesu, sterowanie procesami 2 | ## Zadanie 1. Drzewo procesów (15%) 3 | 4 | Modyfikując zadanie 2 z poprzedniego zestawu, napisz program, który dla każdego z podkatalogów utworzy proces potomny i wywoła polecenie ```ls -l```. Wynik ls poprzedź wypisaniem ścieżki względnej od katalogu podanego jako argument oraz numeru PID procesu odpowiedzialnego za przeglądanie określonego poziomu. 5 | ## Zadanie 2. Równoległe mnożenie macierzy (50%) 6 | 7 | Napisz program macierz do równoległego mnożenia macierzy — zawartość każdej z macierzy (wejściowej lub wynikowej) znajduje się w osobnych plikach. Argumenty operacji mnożenia są treścią pliku lista, będącego pierwszym argumentem wywołania programu. Plik lista zawiera, w pojedynczej linii: 8 | 9 | * Nazwę pliku z pierwszą macierzą wejściową. 10 | * Nazwę pliku z drugą macierzą wejściową. 11 | * Nazwę pliku z macierzą wyjściową. 12 | 13 | Na samym początku program (Manager Process) tworzy podaną (w drugim argumencie programu) liczbę procesów potomnych (Worker Process). 14 | 15 | 16 | Dla każdego wpisu z pliku lista proces potomny mnoży odpowiednie wiersze macierzy A przez odpowiednie kolumny macierzy B, a wynik zapisuje w odpowiednie miejsce macierzy C — każdy z procesów potomnych korzysta z całej macierzy A, a w przypadku macierzy B, tylko z określonych jej kolumn. 17 | 18 | Przykładowo, dla dwóch procesów potomnych, pierwszy z nich mnoży odpowiednie wiersze macierzy A przez kolumny macierzy B oznaczone kolorem zielonym; drugi proces potomny, mnoży odpowiednie wiersze macierzy A przez kolumny macierzy B oznaczone kolorem niebieskim. 19 | Czas działania procesu potomnego nie może przekroczyć podanej liczby sekund — trzeci argument programu. Po upłynięciu tego czasu każdy z procesów potomnych kończy swoje działanie, zwracając do procesu macierzystego poprzez kod wyjścia procesu liczbę wykonanych mnożeń — wymnożenie fragmentu macierzy A przez fragment macierzy B traktujemy jako jedno mnożenie. Proces, który zakończył mnożenie fragmentów, nie kończy działania — może być użyty do kolejnej operacji mnożenia. Program macierzysty pobiera statusy procesów potomnych, wypisuje raport: "Proces PID wykonał n mnożeń macierzy" i kończy swoje działanie. UWAGA! Nie używamy sygnałów, które są tematem następnych zajęć. Ponadto zakładamy, że jedynym dostępnym sposobem komunikacji procesów jest, w tym momencie, komunikacja poprzez plik — właściwe sposoby komunikacji procesów poznamy na dalszych ćwiczeniach. 20 | 21 | Tworzenie pliku wynikowego może się odbywać na dwa sposoby — czwarty argument programu: 22 | 23 | 1. Procesy potomne zapisują wynik mnożenia w odpowiednie miejsce **wspólnego** pliku wynikowego — pamiętaj o odpowiednim użyciu blokady FLOCK. 24 | 2. Procesy potomne zapisują wynik mnożenia do **odrębnych** plików; osobny proces wywołuje jedną z funkcji rodziny `exec*()` w celu wykonania komendy `paste` — połączenie zawartości plików. 25 | 26 | 27 | Napisz pomocniczy program, który: 28 | 29 | * Tworzy określoną liczbę plików z treścią macierzy. Rozmiar tworzonych macierzy, dla odrębnych par macierzy, jest losowy ∈ [Min, Max], gdzie: Min, Max są argumentami programu, przy czym należy zadbać, aby (dla danej pary) liczba kolumn macierzy A była równa liczbie wierszy macierzy B. 30 | * Umożliwia sprawdzenie poprawności otrzymanych wyników mnożenia — implementacja własna lub przy wykorzystaniu dowolnej biblioteki do wykonywania testów jednostkowych 31 | 32 | ## Zadanie 3. Zasoby procesów (35%) 33 | 34 | Zmodyfikuj program z Zadania 2 tak, aby każdy proces (mnożący) miał nałożone pewne **twarde** ograniczenie na dostępny czas procesora oraz rozmiar pamięci wirtualnej. Wartości tych ograniczeń (odpowiednio w sekundach i megabajtach) powinny być przekazywane jako dwa ostatnie argumenty wywołania programu macierz. Ograniczenia powinny być nakładane przez proces potomny, w tym celu należy użyć funkcji `setrlimit()`. Zakładamy, że wartości nakładanych ograniczeń są dużo niższe (t.j. bardziej restrykcyjne) niż ograniczenia, które system operacyjny narzuca na użytkownika uruchamiającego macierz. 35 | 36 | Zaimplementuj w macierz raportowanie zużycia zasobów systemowych dla każdego procesu potomnego, w tym czas użytkownika i czas systemowy. Realizując tę część zadania, zwróć uwagę na funkcję `getrusage()` i flagę RUSAGE_CHILDREN. 37 | -------------------------------------------------------------------------------- /cw07/zad2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "common.h" 16 | 17 | pid_t child_pids[ALL_WORKERS]; 18 | const char* SEMAPHORES_NAMES[6] = {"/FREE_ARRAY", "/FREE_INDEX", "/PACK_INDEX", "/PACK_NUMBER", "/SEND_INDEX", "/SEND_NUMBER"}; 19 | 20 | void clear_before_exit(){ 21 | for (int i = 0; i < SEMAPHORES_NUMBER; i ++){ 22 | if (sem_unlink(SEMAPHORES_NAMES[i]) < 0) error_exit("Cannot delete semaphore", "function clear_before_exit (main)"); 23 | } 24 | if (shm_unlink(SHARED_MEMORY)) error_exit("Cannot delete shared memory", "function clear_before_exit (main)"); 25 | } 26 | 27 | void sigint_handle(int signum){ 28 | printf("\nExit\n"); 29 | for (int i = 0; i < ALL_WORKERS; i ++){ 30 | kill(child_pids[i], SIGINT); 31 | } 32 | clear_before_exit(); 33 | exit(0); 34 | } 35 | 36 | void create_semaphore(){ 37 | sem_t *sem = sem_open(SEMAPHORES_NAMES[FREE_ARRAY], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 1); 38 | if (sem == SEM_FAILED) error_exit("Cannot create semaphore FREE_ARRAY", "function create_semaphore (main)"); 39 | sem_close(sem); 40 | 41 | sem = sem_open(SEMAPHORES_NAMES[FREE_INDEX], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 0); 42 | if (sem == SEM_FAILED) error_exit("Cannot create semaphore FREE_INDEX", "function create_semaphore (main)"); 43 | sem_close(sem); 44 | 45 | sem = sem_open(SEMAPHORES_NAMES[PACK_INDEX], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 0); 46 | if (sem == SEM_FAILED) error_exit("Cannot create semaphore PACK_INDEX", "function create_semaphore (main)"); 47 | sem_close(sem); 48 | 49 | sem = sem_open(SEMAPHORES_NAMES[PACK_NUMBER], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 0); 50 | if (sem == SEM_FAILED) error_exit("Cannot create semaphore PACK_NUMBER", "function create_semaphore (main)"); 51 | sem_close(sem); 52 | 53 | sem = sem_open(SEMAPHORES_NAMES[SEND_INDEX], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 0); 54 | if (sem == SEM_FAILED) error_exit("Cannot create semaphore SEND_INDEX", "function create_semaphore (main)"); 55 | sem_close(sem); 56 | 57 | sem = sem_open(SEMAPHORES_NAMES[SEND_NUMBER], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 0); 58 | if (sem == SEM_FAILED) error_exit("Cannot create semaphore SEND_NUMBER", "function create_semaphore (main)"); 59 | sem_close(sem); 60 | } 61 | 62 | void run_receivers(){ 63 | for (int i = 0; i < RECEIVERS; i ++){ 64 | pid_t child_pid = fork(); 65 | if (child_pid == 0){ 66 | execlp("./receiver", "receiver", NULL); 67 | } 68 | child_pids[i] = child_pid; 69 | } 70 | } 71 | 72 | void run_packers(){ 73 | for (int i = 0; i < PACKERS; i ++){ 74 | pid_t child_pid = fork(); 75 | if (child_pid == 0){ 76 | execlp("./packer", "packer", NULL); 77 | } 78 | child_pids[i + RECEIVERS] = child_pid; 79 | } 80 | } 81 | 82 | void run_senders(){ 83 | for (int i = 0; i < SENDERS; i ++){ 84 | pid_t child_pid = fork(); 85 | if (child_pid == 0){ 86 | execlp("./sender", "sender", NULL); 87 | } 88 | child_pids[i + RECEIVERS + PACKERS] = child_pid; 89 | } 90 | 91 | for (int i = 0; i < ALL_WORKERS; i++){ 92 | wait(NULL); 93 | } 94 | } 95 | 96 | void create_shared_memory(){ 97 | int shared_memory = shm_open(SHARED_MEMORY, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO); 98 | if (shared_memory < 0) error_exit("Cannot create shared memory", "function create_shared_memory (main)"); 99 | if (ftruncate(shared_memory, sizeof(orders)) < 0) error_exit("Cannot set memory size", "function create_shared_memory (main)"); 100 | } 101 | 102 | int main(){ 103 | 104 | signal(SIGINT, sigint_handle); 105 | 106 | create_semaphore(); 107 | create_shared_memory(); 108 | 109 | run_receivers(); 110 | run_packers(); 111 | run_senders(); 112 | 113 | clear_before_exit(); 114 | return 0; 115 | } -------------------------------------------------------------------------------- /cw03/zad2/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct Matrix{ 7 | int **val; 8 | int col; 9 | int row; 10 | } Matrix; 11 | 12 | Matrix * readMatrix(char *path){ 13 | FILE *file = fopen(path, "r"); 14 | char *row = (char*)calloc(1000, sizeof(char)); 15 | Matrix *m = (Matrix*)malloc(sizeof(Matrix)); 16 | m -> val = (int**) calloc(1000, sizeof(int *)); 17 | int i = 0, j; 18 | 19 | while(fgets(row, 1000, file) != NULL){ 20 | m -> val[i] = (int*)calloc(1000, sizeof(int)); 21 | j = 0; 22 | char*number = strtok(row, " \n"); 23 | while(number!=NULL){ 24 | m -> val[i][j ++] = atoi(number); 25 | number = strtok(NULL, " \n"); 26 | } 27 | i++; 28 | } 29 | m -> row = i; 30 | m -> col = j; 31 | free(row); 32 | fclose(file); 33 | return m; 34 | } 35 | 36 | Matrix* readMatrixC(char*path) { 37 | Matrix* M = malloc(sizeof(Matrix)); 38 | FILE *file = fopen(path, "r"); 39 | if (file == NULL){ 40 | printf("Cannot open file %s\n", path); 41 | exit(EXIT_FAILURE); 42 | } 43 | char input[1024]; 44 | char* val; 45 | char limit[] = " \t\n"; 46 | int rows = 1; 47 | int cols = 1; 48 | 49 | if(fgets(input, sizeof input, file)){ 50 | strtok(input, limit); 51 | while (strtok(NULL, limit) != NULL) cols++; 52 | } 53 | while (fgets(input, sizeof input, file)) rows++; 54 | rewind(file); 55 | 56 | M -> row = rows; 57 | M -> col = cols; 58 | M -> val = calloc(rows, sizeof(int*)); 59 | 60 | for(int r = 0; rval[r] = calloc(cols, sizeof(int)); 61 | int r = 0; 62 | 63 | while (fgets(input, sizeof input, file)) { 64 | int c = 0; 65 | val = strtok(input, limit); 66 | M -> val[r][c] = atoi(val); 67 | while (val != NULL && c < cols) { 68 | M ->val[r][c] = atoi(val); 69 | val = strtok(NULL, limit); 70 | c++; 71 | } 72 | r++; 73 | } 74 | fclose(file); 75 | return M; 76 | } 77 | 78 | void printMatrix(Matrix *m){ 79 | for (int r = 0; r < m -> row; r ++){ 80 | for (int c = 0; c < m -> col; c ++){ 81 | printf("%d ", m->val[r][c]); 82 | } 83 | printf("\n"); 84 | } 85 | printf("\n"); 86 | } 87 | 88 | Matrix *multiplyMatrices(Matrix *A, Matrix *B){ 89 | Matrix *C = (Matrix *) malloc(sizeof(Matrix)); 90 | C -> col = B -> col; 91 | C -> row = A -> row; 92 | C -> val = (int **)calloc(C -> row, sizeof(int *)); 93 | for (int i = 0; i < C -> row; i ++){ 94 | C -> val[i] = (int *)calloc(C -> col, sizeof(int)); 95 | } 96 | for (int r = 0; r < C -> row; r ++){ 97 | for (int c = 0; c < C -> col; c ++){ 98 | C -> val[r][c] = 0; 99 | for (int k = 0; k < A -> col; k ++){ 100 | C -> val[r][c] += A -> val[r][k] * B -> val[k][c]; 101 | } 102 | } 103 | } 104 | return C; 105 | } 106 | 107 | bool checkMatrices(Matrix *C1, Matrix * C2){ 108 | if (C1 -> col != C2 -> col || C1 -> row != C2 -> row) return false; 109 | 110 | for (int r = 0; r < C1 -> row; r ++){ 111 | for (int c = 0; c < C1 -> col; c ++){ 112 | if (C1 -> val[r][c] != C2 -> val[r][c]) return false; 113 | } 114 | } 115 | return true; 116 | } 117 | 118 | void removeMatrix(Matrix *m){ 119 | for (int r = 0; r < m -> row; r++) free(m -> val[r]); 120 | free(m -> val); 121 | free(m); 122 | } 123 | 124 | int main(int argc, char**argv){ 125 | if (argc < 2){ 126 | printf("Wrong number of arguments. Expected: [path to list]\n"); 127 | exit(EXIT_FAILURE); 128 | } 129 | 130 | FILE *lista = fopen(argv[1], "r"); 131 | if (lista == NULL){ 132 | printf("Cannot open file: %s\n", argv[1]); 133 | exit(EXIT_FAILURE); 134 | } 135 | 136 | char file[1000]; 137 | int i = 0; 138 | Matrix *A, *B, *C; 139 | 140 | while(fscanf(lista, "%s", file) != EOF){ 141 | if (i % 3 == 0){ 142 | A = readMatrixC(file); 143 | } 144 | else if (i % 3 == 1){ 145 | B = readMatrixC(file); 146 | } 147 | else { 148 | C = readMatrixC(file); 149 | int correct = checkMatrices(multiplyMatrices(A, B), C); 150 | printf("Test nr %d: %s\n", i / 3, correct ? "PASS" : "FAIL"); 151 | free(A); 152 | free(B); 153 | free(C); 154 | } 155 | i++; 156 | } 157 | return 0; 158 | 159 | } -------------------------------------------------------------------------------- /cw03/zad3/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef struct Matrix{ 7 | int **val; 8 | int col; 9 | int row; 10 | } Matrix; 11 | 12 | Matrix * readMatrix(char *path){ 13 | FILE *file = fopen(path, "r"); 14 | char *row = (char*)calloc(1000, sizeof(char)); 15 | Matrix *m = (Matrix*)malloc(sizeof(Matrix)); 16 | m -> val = (int**) calloc(1000, sizeof(int *)); 17 | int i = 0, j; 18 | 19 | while(fgets(row, 1000, file) != NULL){ 20 | m -> val[i] = (int*)calloc(1000, sizeof(int)); 21 | j = 0; 22 | char*number = strtok(row, " \n"); 23 | while(number!=NULL){ 24 | m -> val[i][j ++] = atoi(number); 25 | number = strtok(NULL, " \n"); 26 | } 27 | i++; 28 | } 29 | m -> row = i; 30 | m -> col = j; 31 | free(row); 32 | fclose(file); 33 | return m; 34 | } 35 | 36 | Matrix* readMatrixC(char*path) { 37 | Matrix* M = malloc(sizeof(Matrix)); 38 | FILE *file = fopen(path, "r"); 39 | if (file == NULL){ 40 | printf("Cannot open file %s\n", path); 41 | exit(EXIT_FAILURE); 42 | } 43 | char input[1024]; 44 | char* val; 45 | char limit[] = " \t\n"; 46 | int rows = 1; 47 | int cols = 1; 48 | 49 | if(fgets(input, sizeof input, file)){ 50 | strtok(input, limit); 51 | while (strtok(NULL, limit) != NULL) cols++; 52 | } 53 | while (fgets(input, sizeof input, file)) rows++; 54 | rewind(file); 55 | 56 | M -> row = rows; 57 | M -> col = cols; 58 | M -> val = calloc(rows, sizeof(int*)); 59 | 60 | for(int r = 0; rval[r] = calloc(cols, sizeof(int)); 61 | int r = 0; 62 | 63 | while (fgets(input, sizeof input, file)) { 64 | int c = 0; 65 | val = strtok(input, limit); 66 | M -> val[r][c] = atoi(val); 67 | while (val != NULL && c < cols) { 68 | M ->val[r][c] = atoi(val); 69 | val = strtok(NULL, limit); 70 | c++; 71 | } 72 | r++; 73 | } 74 | fclose(file); 75 | return M; 76 | } 77 | 78 | void printMatrix(Matrix *m){ 79 | for (int r = 0; r < m -> row; r ++){ 80 | for (int c = 0; c < m -> col; c ++){ 81 | printf("%d ", m->val[r][c]); 82 | } 83 | printf("\n"); 84 | } 85 | printf("\n"); 86 | } 87 | 88 | Matrix *multiplyMatrices(Matrix *A, Matrix *B){ 89 | Matrix *C = (Matrix *) malloc(sizeof(Matrix)); 90 | C -> col = B -> col; 91 | C -> row = A -> row; 92 | C -> val = (int **)calloc(C -> row, sizeof(int *)); 93 | for (int i = 0; i < C -> row; i ++){ 94 | C -> val[i] = (int *)calloc(C -> col, sizeof(int)); 95 | } 96 | for (int r = 0; r < C -> row; r ++){ 97 | for (int c = 0; c < C -> col; c ++){ 98 | C -> val[r][c] = 0; 99 | for (int k = 0; k < A -> col; k ++){ 100 | C -> val[r][c] += A -> val[r][k] * B -> val[k][c]; 101 | } 102 | } 103 | } 104 | return C; 105 | } 106 | 107 | bool checkMatrices(Matrix *C1, Matrix * C2){ 108 | if (C1 -> col != C2 -> col || C1 -> row != C2 -> row) return false; 109 | 110 | for (int r = 0; r < C1 -> row; r ++){ 111 | for (int c = 0; c < C1 -> col; c ++){ 112 | if (C1 -> val[r][c] != C2 -> val[r][c]) return false; 113 | } 114 | } 115 | return true; 116 | } 117 | 118 | void removeMatrix(Matrix *m){ 119 | for (int r = 0; r < m -> row; r++) free(m -> val[r]); 120 | free(m -> val); 121 | free(m); 122 | } 123 | 124 | int main(int argc, char**argv){ 125 | if (argc < 2){ 126 | printf("Wrong number of arguments. Expected: [path to list]\n"); 127 | exit(EXIT_FAILURE); 128 | } 129 | 130 | FILE *lista = fopen(argv[1], "r"); 131 | if (lista == NULL){ 132 | printf("Cannot open file: %s\n", argv[1]); 133 | exit(EXIT_FAILURE); 134 | } 135 | 136 | char file[1000]; 137 | int i = 0; 138 | Matrix *A, *B, *C; 139 | 140 | while(fscanf(lista, "%s", file) != EOF){ 141 | if (i % 3 == 0){ 142 | A = readMatrixC(file); 143 | } 144 | else if (i % 3 == 1){ 145 | B = readMatrixC(file); 146 | } 147 | else { 148 | C = readMatrixC(file); 149 | int correct = checkMatrices(multiplyMatrices(A, B), C); 150 | printf("Test nr %d: %s\n", i / 3, correct ? "PASS" : "FAIL"); 151 | free(A); 152 | free(B); 153 | free(C); 154 | } 155 | i++; 156 | } 157 | return 0; 158 | 159 | } -------------------------------------------------------------------------------- /cw04/README.md: -------------------------------------------------------------------------------- 1 | # Sygnały 2 | ## Zadanie 1 (10%) 3 | 4 | Napisz program wypisujący w pętli nieskończonej zawartość bieżącego katalogu. Po odebraniu sygnału SIGTSTP (CTRL+Z) program zatrzymuje się, wypisując komunikat "Oczekuję na CTRL+Z - kontynuacja albo CTR+C - zakończenie programu". Po ponownym wysłaniu SIGTSTP program powraca do pierwotnego wypisywania. 5 | Program powinien również obsługiwać sygnał SIGINT. Po jego odebraniu program wypisuje komunikat "Odebrano sygnał SIGINT" i kończy działanie. W kodzie programu, do przechwycenia sygnałów użyj zarówno funkcji signal, jak i sigaction (np. SIGINT odbierz za pomocą signal, a SIGTSTP za pomocą sigaction). 6 | ## Zadanie 2 (30%) 7 | 8 | Napisz program demonstrujący, czy ustawienia dyspozycji dla sygnałów są dziedziczone po wykonaniu funkcji fork oraz exec. 9 | W szczególności eksperymenty proszę wykonać dla sygnału SIGUSR1 w następujący sposób: 10 | 11 | * Dziedziczenie ustawień sygnałów po wykonaniu funkcji fork. Proszę napisać program, który w zależności od wartości argumentu z linii poleceń, może on przyjmować wartości ignore, handler, mask lub pending, odpowiednio w procesie przodka ustawia ignorowanie, instaluje handler obsługujący sygnał wypisujący komunikat o jego otrzymaniu, maskuje ten sygnał oraz sprawdza (przy zamaskowaniu tego sygnału) czy wiszący/oczekujący sygnał jest widoczny w procesie, a następnie przy pomocy funkcji raise wysyła sygnał do samego siebie oraz wykonuje odpowiednie dla danej opcji działania, po czym tworzy potomka funkcją fork i ponownie przy pomocy funkcji raise potomek wysyła sygnał do samego siebie (z wyjątkiem opcji pending, gdzie testowane jest sprawdzenie, czy sygnał czekający w przodku jest widoczny w potomku). 12 | * Dziedziczenie ustawień sygnałów po wykonaniu funkcji exec. W podobny sposób sprawdź jaki wpływ na ustawienia sygnałów ma wywołanie funkcji exec. Rozpatrz opcje: ignore, mask i pending. 13 | * Przygotuj plik raport2.txt w którym nastąpi podsumowanie z wnioskami z wykonanych powyższych eksperymentów 14 | 15 | ## Zadanie 3 (15%) 16 | 17 | Przetestuj działanie flagi SA_SIGINFO w funkcji sigaction. Zainstaluj w ten sposób procedurę obsługi sygnału (handler) dla odpowiednio dobranych sygnałów stosując składnie procedury handlera z trzema argumentami. Wypisz i skomentuj (przygotowując odpowiednie scenariusze) trzy różne informacje (pomijając numer sygnału oraz identyfikator PID procesu wysyłającego) dostarczane w strukturze siginfo_t przekazywanej jako drugi argument funkcji handlera. 18 | ## Zadanie 4 (45%) 19 | 20 | Napisz dwa programy: sender program wysyłający sygnały SIGUSR1 i catcher - program zliczający ilość odebranych sygnałów. Ilość sygnałów SIGUSR1 wysyłanych przez pierwszy program powinna być określana w parametrze wywołania tego programu. Program catcher jest uruchamiany najpierw, wypisuje swój numer PID i czeka na sygnały SIGUSR1 i SIGUSR2. Wszystkie pozostałe sygnały są blokowane. Program sender przyjmuje trzy parametry: PID procesu catcher, ilość sygnałów do wysłania i tryb wysłania sygnałów. 21 | 22 | Po transmisji wszystkich sygnałów SIGUSR1 sender powinien wysłać sygnał SIGUSR2, po otrzymaniu którego catcher wysyła do sendera tyle sygnałów SIGUSR1, ile sam ich otrzymał a „transmisję” kończy wysłaniem sygnału SIGUSR2, wypisaniem liczby odebranych sygnałów i zakończeniem działania. PID sendera catcher pobiera ze struktury siginfo_t po przechwyceniu od niego sygnału. Program sender po otrzymaniu sygnału SIGUSR2 wyświetla komunikat o ilości otrzymanych sygnałów SIGUSR1 oraz o tym, ile powinien ich otrzymać i kończy działanie. 23 | 24 | UWAGA! W żaden sposób nie opóźniamy wysyłania sygnałów, wszelkie "gubienie" sygnałów jest zjawiskiem naturalnym. 25 | 26 | a) Wysyłanie sygnałów w obu programach należy wykonać w następujących trybach: (30%) 27 | 28 | * KILL - za pomocą funkcji kill 29 | * SIGQUEUE - za pomocą funkcji sigqueue - wraz z przesłanym sygnałem catcher wysyła numer kolejnego odsyłanego sygnału, dzięki czemu sender wie, ile dokładnie catcher odebrał, a tym samym wysłał do niego sygnałów. Wypisz tę dodatkową informację w senderze. 30 | * SIGRT - zastępując SIGUSR1 i SIGUSR2 dwoma dowolnymi sygnałami czasu rzeczywistego wysyłanymi za pomocą kill. Jaka liczba sygnałów będzie teraz odebrana? 31 | 32 | b) Zmodyfikuj powyższe programy, dodając potwierdzenie odbioru sygnału po każdorazowym ich odebraniu przez program catcher. W tym celu, catcher wysyła do sendera sygnał SIGUSR1 informujący o odbiorze sygnału. Sender powinien wysłać kolejny sygnał dopiero po uzyskaniu tego potwierdzenia. Zapewnij rozwiązanie, w którym ilość sygnałów odebranych jest zgodna z ilością sygnałów wysłanych, i w którym nie dochodzi do zakleszczenia. (15%) 33 | -------------------------------------------------------------------------------- /cw06/README.md: -------------------------------------------------------------------------------- 1 | # IPC - kolejki komunikatów 2 | ## Zadanie 1. Prosty chat - System V (50%) 3 | 4 | Napisz prosty program typu klient-serwer, w którym komunikacja zrealizowana jest za pomocą kolejek komunikatów. 5 | 6 | Serwer po uruchomieniu tworzy nową kolejkę komunikatów systemu V. Za pomocą tej kolejki klienci będą wysyłać komunikaty do serwera. Wysyłane zlecenia mają zawierać rodzaj zlecenia jako rodzaj komunikatu oraz informację od którego klienta zostały wysłane (ID klienta), w odpowiedzi rodzajem komunikatu ma być informacja identyfikująca czekającego na nią klienta. 7 | 8 | Klient bezpośrednio po uruchomieniu tworzy kolejkę z unikalnym kluczem IPC i wysyła jej klucz komunikatem do serwera (komunikat INIT). Po otrzymaniu takiego komunikatu, serwer otwiera kolejkę klienta, przydziela klientowi identyfikator (np. numer w kolejności zgłoszeń) i odsyła ten identyfikator do klienta (komunikacja w kierunku serwer->klient odbywa się za pomocą kolejki klienta). Po otrzymaniu identyfikatora, klient może wysłać zlecenie do serwera(zlecenia są czytane ze standardowego wyjścia w postaci typ_komunikatu). 9 | 10 | Serwer ma umożliwiać łączenie klientów w pary - klienci przechodząc do trybu chatu będą mogli wysyłać sobie bezpośrednio wiadomości bez udziału serwera. 11 | 12 | Rodzaje zleceń 13 | * LIST: 14 | 15 | Zlecenie wypisania listy wszystkich aktywnych klientów wraz z informacja czy są dostępni do połączenia. 16 | * CONNECT id_klienta: 17 | 18 | Zlecenie połączenia się z konkretnym klientem. Zleceniodawca wysyła do serwera id_klienta z listy aktywnych klientów. Serwer wysyła mu klucz kolejki klienta z którym chce się połączyć. Następnie serwer wysyła klucz kolejki zleceniodawcy do wybranego klienta. Obaj klienci przechodzą w tryb chatu - wysyłają sobie wiadomości bezpośrednio(bez udziału serwera). Serwer oznacza ich jako niedostępnych do połączenia dla innych klientów. (Należy umożliwić zerwanie połączenia - co skutkuje wysłaniem DISCONNECT do serwera). 19 | * DISCONNECT: 20 | 21 | Zlecenie ustawienia klienta jako dostępnego do połączenia. 22 | * STOP: 23 | 24 | Zgłoszenie zakończenia pracy klienta. Klient wysyła ten komunikat, kiedy kończy pracę, aby serwer mógł usunąć z listy jego kolejkę. Następnie kończy pracę, usuwając swoją kolejkę. Komunikat ten wysyłany jest również, gdy po stronie klienta zostanie wysłany sygnał SIGINT. 25 | 26 | Zlecenia powinny być obsługiwane zgodnie z priorytetami, najwyższy priorytet ma STOP, potem DISCONNECT oraz LIST i reszta. Można tego dokonać poprzez sterowanie parametrem MTYPE w funkcji msgsnd. 27 | 28 | Poszczególne rodzaje komunikatów należy identyfikować za pomocą typów komunikatów systemu V. Klucze dla kolejek mają być generowane na podstawie ścieżki $HOME. Małe liczby do wygenerowania kluczy oraz rodzaje komunikatów mają być zdefiniowane we wspólnym pliku nagłówkowym. Dla uproszczenia można założyć, że długość komunikatu jest ograniczona pewną stałą (jej definicja powinna znaleźć się w pliku nagłówkowym). 29 | 30 | Klient i serwer należy napisać w postaci osobnych programów (nie korzystamy z funkcji fork). Serwer musi być w stanie pracować z wieloma klientami naraz. Przed zakończeniem pracy każdy proces powinien usunąć kolejkę którą utworzył (patrz IPC_RMID oraz funkcja atexit). Dla uproszczenia można przyjąć, że serwer przechowuje informacje o klientach w statycznej tablicy (rozmiar tablicy ogranicza liczbę klientów, którzy mogą się zgłosić do serwera). 31 | 32 | Serwer może wysłać do klientów komunikaty: 33 | * inicjujący pracę klienta w trybie chatu (kolejka klientów) 34 | * wysyłający odpowiedzi do klientów (kolejki klientów) 35 | * informujący klientów o zakończeniu pracy serwera - po wysłaniu takiego sygnału i odebraniu wiadomości STOP od wszystkich klientów serwer usuwa swoją kolejkę i kończy pracę. (kolejki klientów) 36 | 37 | Należy obsłużyć przerwanie działania serwera lub klienta za pomocą CTRL+C. Po stronie klienta obsługa tego sygnału jest równoważna z wysłaniem komunikatu STOP. 38 | 39 | ## Zadanie 2. Prosty chat - POSIX (50%) 40 | 41 | Zrealizuj zadanie analogiczne do Zadania 1, wykorzystując kolejki komunikatów POSIX. Kolejka klienta powinna mieć losową nazwę zgodną z wymaganiami stawianymi przez POSIX. Na typ komunikatu można zarezerwować pierwszy bajt jego treści. Obsługa zamykania kolejek analogiczna jak w zadaniu 1, z tym, że aby można było usunąć kolejkę, wszystkie procesy powinny najpierw ją zamknąć. Przed zakończeniem pracy klient wysyła do serwera komunikat informujący, że serwer powinien zamknąć po swojej stronie kolejkę klienta. Następnie klient zamyka i usuwa swoją kolejkę. Serwer przed zakończeniem pracy zamyka wszystkie otwarte kolejki, informuje klientów, aby usunęli swoje kolejki oraz zamknęli kolejkę serwera i usuwa kolejkę, którą utworzył. -------------------------------------------------------------------------------- /cw01/zad3a/raport3a.txt: -------------------------------------------------------------------------------- 1 | static: 2 | Operation: compare_pairs 3 | Real time: 0.200000 4 | User time: 0.000000 5 | System time: 0.000000 6 | 7 | Operation: remove_block 8 | Real time: 0.000000 9 | User time: 0.000000 10 | System time: 0.000000 11 | 12 | Operation: remove_block 13 | Real time: 0.000000 14 | User time: 0.000000 15 | System time: 0.000000 16 | 17 | Operation: compare_pairs 18 | Real time: 0.030000 19 | User time: 0.000000 20 | System time: 0.000000 21 | 22 | Operation: remove_operation 23 | Real time: 0.000000 24 | User time: 0.000000 25 | System time: 0.000000 26 | 27 | Operation: remove_block 28 | Real time: 0.000000 29 | User time: 0.000000 30 | System time: 0.000000 31 | 32 | Operation: remove_operation 33 | Real time: 0.000000 34 | User time: 0.000000 35 | System time: 0.000000 36 | 37 | Operation: compare_pairs 38 | Real time: 0.050000 39 | User time: 0.000000 40 | System time: 0.000000 41 | 42 | Operation: remove_operation 43 | Real time: 0.000000 44 | User time: 0.000000 45 | System time: 0.000000 46 | 47 | Operation: remove_block 48 | Real time: 0.000000 49 | User time: 0.000000 50 | System time: 0.000000 51 | 52 | Operation: remove_block 53 | Real time: 0.000000 54 | User time: 0.000000 55 | System time: 0.000000 56 | 57 | Operation: compare_pairs 58 | Real time: 0.010000 59 | User time: 0.000000 60 | System time: 0.000000 61 | 62 | Operation: remove_operation 63 | Real time: 0.000000 64 | User time: 0.000000 65 | System time: 0.000000 66 | 67 | Operation: remove_block 68 | Real time: 0.000000 69 | User time: 0.000000 70 | System time: 0.000000 71 | 72 | Operation: remove_block 73 | Real time: 0.000000 74 | User time: 0.000000 75 | System time: 0.000000 76 | 77 | shared: 78 | Operation: compare_pairs 79 | Real time: 0.190000 80 | User time: 0.000000 81 | System time: 0.000000 82 | 83 | Operation: remove_block 84 | Real time: 0.000000 85 | User time: 0.000000 86 | System time: 0.000000 87 | 88 | Operation: remove_block 89 | Real time: 0.000000 90 | User time: 0.000000 91 | System time: 0.000000 92 | 93 | Operation: compare_pairs 94 | Real time: 0.040000 95 | User time: 0.000000 96 | System time: 0.000000 97 | 98 | Operation: remove_operation 99 | Real time: 0.000000 100 | User time: 0.000000 101 | System time: 0.000000 102 | 103 | Operation: remove_block 104 | Real time: 0.000000 105 | User time: 0.000000 106 | System time: 0.000000 107 | 108 | Operation: remove_operation 109 | Real time: 0.000000 110 | User time: 0.000000 111 | System time: 0.000000 112 | 113 | Operation: compare_pairs 114 | Real time: 0.050000 115 | User time: 0.000000 116 | System time: 0.000000 117 | 118 | Operation: remove_operation 119 | Real time: 0.000000 120 | User time: 0.000000 121 | System time: 0.000000 122 | 123 | Operation: remove_block 124 | Real time: 0.000000 125 | User time: 0.000000 126 | System time: 0.000000 127 | 128 | Operation: remove_block 129 | Real time: 0.000000 130 | User time: 0.000000 131 | System time: 0.000000 132 | 133 | Operation: compare_pairs 134 | Real time: 0.010000 135 | User time: 0.000000 136 | System time: 0.000000 137 | 138 | Operation: remove_operation 139 | Real time: 0.000000 140 | User time: 0.000000 141 | System time: 0.000000 142 | 143 | Operation: remove_block 144 | Real time: 0.000000 145 | User time: 0.000000 146 | System time: 0.000000 147 | 148 | Operation: remove_block 149 | Real time: 0.000000 150 | User time: 0.000000 151 | System time: 0.000000 152 | 153 | dynamic: 154 | Operation: compare_pairs 155 | Real time: 0.180000 156 | User time: 0.000000 157 | System time: 0.000000 158 | 159 | Operation: remove_block 160 | Real time: 0.000000 161 | User time: 0.000000 162 | System time: 0.000000 163 | 164 | Operation: remove_block 165 | Real time: 0.000000 166 | User time: 0.000000 167 | System time: 0.000000 168 | 169 | Operation: compare_pairs 170 | Real time: 0.050000 171 | User time: 0.000000 172 | System time: 0.000000 173 | 174 | Operation: remove_operation 175 | Real time: 0.000000 176 | User time: 0.000000 177 | System time: 0.000000 178 | 179 | Operation: remove_block 180 | Real time: 0.000000 181 | User time: 0.000000 182 | System time: 0.000000 183 | 184 | Operation: remove_operation 185 | Real time: 0.000000 186 | User time: 0.000000 187 | System time: 0.000000 188 | 189 | Operation: compare_pairs 190 | Real time: 0.050000 191 | User time: 0.000000 192 | System time: 0.000000 193 | 194 | Operation: remove_operation 195 | Real time: 0.000000 196 | User time: 0.000000 197 | System time: 0.000000 198 | 199 | Operation: remove_block 200 | Real time: 0.000000 201 | User time: 0.000000 202 | System time: 0.000000 203 | 204 | Operation: remove_block 205 | Real time: 0.000000 206 | User time: 0.000000 207 | System time: 0.000000 208 | 209 | Operation: compare_pairs 210 | Real time: 0.010000 211 | User time: 0.000000 212 | System time: 0.000000 213 | 214 | Operation: remove_operation 215 | Real time: 0.000000 216 | User time: 0.000000 217 | System time: 0.000000 218 | 219 | Operation: remove_block 220 | Real time: 0.000000 221 | User time: 0.000000 222 | System time: 0.000000 223 | 224 | Operation: remove_block 225 | Real time: 0.000000 226 | User time: 0.000000 227 | System time: 0.000000 228 | -------------------------------------------------------------------------------- /cw09/zad1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define BARBER_TIME 5 10 | #define WAITING_TIME 5 11 | #define CLIENT_CREATION_TIME 3 12 | 13 | int number_of_clients; 14 | int number_of_chairs; 15 | int clients_in_waiting_room = 0; 16 | int shaved_clients = 0; 17 | int is_barber_sleeping = 0; 18 | 19 | pthread_t client_on_barber_chair; 20 | pthread_t* chairs; 21 | int next_free_chair = 0; 22 | int next_client_chair = 0; 23 | 24 | pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 25 | pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 26 | 27 | void error_exit(char* message) { 28 | printf("ERROR: %s\n", message); 29 | exit(EXIT_FAILURE); 30 | } 31 | 32 | int is_everyone_shaved(){ 33 | return shaved_clients == number_of_clients; 34 | } 35 | 36 | void barber_to_sleep(){ 37 | printf("Golibroda: ide spac\n"); 38 | is_barber_sleeping = 1; 39 | pthread_cond_wait(&cond, &mutex); 40 | is_barber_sleeping = 0; 41 | } 42 | 43 | void client_to_barber_chair(){ 44 | clients_in_waiting_room--; 45 | client_on_barber_chair = chairs[next_client_chair]; 46 | next_client_chair = (next_client_chair + 1) % number_of_chairs; 47 | } 48 | 49 | void shave_client(){ 50 | printf("Golibroda: czeka %d klientow, gole klienta %ld\n", clients_in_waiting_room, client_on_barber_chair); 51 | 52 | // unblock all threads currently blocked on the specified condition variable cond 53 | pthread_cond_broadcast(&cond); 54 | pthread_mutex_unlock(&mutex); 55 | 56 | sleep(rand() % BARBER_TIME + 1); 57 | 58 | pthread_mutex_lock(&mutex); 59 | 60 | // send a cancellation request to the thread client_on_barber_chair 61 | pthread_cancel(client_on_barber_chair); 62 | 63 | shaved_clients++; 64 | client_on_barber_chair = 0; 65 | } 66 | 67 | void* barber(void* arg) { 68 | while(!is_everyone_shaved()) { 69 | pthread_mutex_lock(&mutex); 70 | 71 | if(!clients_in_waiting_room) { 72 | barber_to_sleep(); 73 | } 74 | else { 75 | client_to_barber_chair(); 76 | } 77 | 78 | shave_client(); 79 | 80 | pthread_mutex_unlock(&mutex); 81 | } 82 | pthread_exit((void *) 0); 83 | } 84 | 85 | int is_free_place_in_waiting_room(){ 86 | return clients_in_waiting_room < number_of_chairs; 87 | } 88 | 89 | void wake_up_barber(pthread_t client_id){ 90 | printf("Klient: budze golibrode; %ld\n", client_id); 91 | client_on_barber_chair = client_id; 92 | // unblock barber thread 93 | pthread_cond_broadcast(&cond); 94 | pthread_mutex_unlock(&mutex); 95 | } 96 | 97 | void client_to_waiting_room(pthread_t client_id){ 98 | chairs[next_free_chair] = client_id; 99 | next_free_chair = (next_free_chair + 1) % number_of_chairs; 100 | clients_in_waiting_room++; 101 | printf("Klient: poczekalnia, wolne miejsca %d; %ld\n", number_of_chairs - clients_in_waiting_room, client_id); 102 | pthread_mutex_unlock(&mutex); 103 | } 104 | 105 | void wait_for_place_in_waiting_room(pthread_t client_id){ 106 | printf("Klient: zajete; %ld\n", client_id); 107 | pthread_mutex_unlock(&mutex); 108 | sleep(rand() % WAITING_TIME + 1); 109 | } 110 | 111 | void* client(void* arg) { 112 | // get id of calling thread 113 | pthread_t client_id = pthread_self(); 114 | 115 | while(1) { 116 | pthread_mutex_lock(&mutex); 117 | 118 | if(is_barber_sleeping) { 119 | wake_up_barber(client_id); 120 | break; 121 | } 122 | else if(is_free_place_in_waiting_room()) { 123 | client_to_waiting_room(client_id); 124 | break; 125 | } 126 | wait_for_place_in_waiting_room(client_id); 127 | 128 | } 129 | 130 | pthread_exit((void *) 0); 131 | } 132 | 133 | 134 | int main(int argc, char** argv) { 135 | if(argc != 3) error_exit("Wrong number of arguments. Expected: ./main [number of chairs] [number of clients]."); 136 | srand(time(NULL)); 137 | 138 | number_of_chairs = atoi(argv[1]); 139 | number_of_clients = atoi(argv[2]); 140 | 141 | if (number_of_chairs < 1) error_exit("Number of chairs must be positive."); 142 | if (number_of_clients < 1) error_exit("Number of clients must be positive"); 143 | 144 | // init mutex 145 | if(pthread_mutex_init(&mutex, NULL) != 0) error_exit("Cannot init mutex."); 146 | 147 | chairs = (pthread_t*) calloc(number_of_chairs, sizeof(pthread_t)); 148 | 149 | // create barber thread 150 | pthread_t barber_thread; 151 | pthread_create(&barber_thread, NULL, barber, NULL); 152 | 153 | // create clients threads 154 | pthread_t* client_threads = (pthread_t*) calloc(number_of_clients, sizeof(pthread_t)); 155 | for(int i = 0; i < number_of_clients; i++) { 156 | sleep(rand() % CLIENT_CREATION_TIME + 1); 157 | pthread_create(&client_threads[i], NULL, client, NULL); 158 | } 159 | 160 | // join threads 161 | for(int i = 0; i < number_of_clients; i++) { 162 | if(pthread_join(client_threads[i], NULL) > 0) { 163 | error_exit("Cannot join client's threads."); 164 | } 165 | } 166 | if (pthread_join(barber_thread, NULL) > 0){ 167 | error_exit("Cannot join barber's thread."); 168 | } 169 | 170 | // destroy mutex and cond 171 | pthread_mutex_destroy(&mutex); 172 | pthread_cond_destroy(&cond); 173 | 174 | return 0; 175 | } -------------------------------------------------------------------------------- /cw01/README.md: -------------------------------------------------------------------------------- 1 | # Zarządzanie pamięcią, biblioteki, pomiar czasu 2 | 3 | ## Zadanie 1. Alokacja tablicy ze wskaźnikami na bloki pamięci zawierające tablicę wskaźników (25%) 4 | 5 | Zaprojektuj i przygotuj zestaw funkcji (bibliotekę) do zarządzania tablicą bloków, w których to blokach pamięci zapisywane są rezultaty operacji porównywania plików wiersz po wierszu (poleceniem ```diff```) sekwencji par plików — sekwencja ich nazw jest parametrem funkcji. 6 | 7 | Biblioteka powinna umożliwiać: 8 | 9 | * Utworzenie tablicy wskaźników (tablicy głównej) — w tej tablicy będą przechowywane wskaźniki na bloki operacji edycyjnych — pierwszy element tablicy głównej zawiera wykaz operacji edycyjnych dla pierwszej pary plików, drugi element dla drugiej pary, itd. Pojedynczy blok operacji edycyjnych (element wskazywany z tablicy głównej), to tablica wskaźników na poszczególne operacje edycyjne 10 | * Definiowanie sekwencji par plików 11 | * Przeprowadzenie porównania (dla każdego elementu sekwencji) oraz zapisanie wyniku porównania do pliku tymczasowego 12 | * Utworzenie, na podstawie zawartość pliku tymczasowego, bloku operacji edycyjnych — tablicy wskaźników na operacje edycyjne, ustawienie w tablicy głównej (wskaźników) wskazania na ten blok; na końcu, funkcja powinna zwrócić indeks elementu tablicy (głównej), który zawiera wskazanie na utworzony blok — dla pokazanego (niżej) przykładu powinna więc zwrócić 0 13 | * Zwrócenie informacji o ilości operacji w danym bloku operacji edycyjnych — dla przykładu, pokazanego poniżej, zwracaną wartością powinno być 3 14 | * Usunięcie, z pamięci, bloku (operacji edycyjnych) o zadanym indeksie 15 | * Usunięcie, z pamięci, określonej operacji dla podanego bloku operacji edycyjnych 16 | 17 | **Przykład** — załóżmy, że sekwencja nazw plików zawiera tylko jedną parę ('a.txt', 'b.txt'). 18 | 19 | Zawartość pliku a.txt: 20 | 21 | aaa 22 | bbb ccc 23 | ddd 24 | eee 25 | hhh iii 26 | 27 | Zawartość pliku b.txt: 28 | 29 | jjj kkk 30 | aaa 31 | fff ccc 32 | eee 33 | bbb ggg 34 | 35 | Wynik wykonania ```diff a.txt b.txt```: 36 | 37 | 0a1 38 | > jjj kkk 39 | 2,3c3 40 | < bbb ccc 41 | < ddd 42 | --- 43 | > fff ccc 44 | 5c5 45 | < hhh iii 46 | --- 47 | > bbb ggg 48 | 49 | W tym przypadku tablica główna powinna zawierać tylko jeden wskaźnik na blok operacji edycyjnych (bo mamy tylko jedną parę plików). Blok operacji edycyjnych powinien być trzyelementową tablicą wskaźników na napisy z treścią operacji edycyjnych. 50 | 51 | 52 | Tablice / bloki powinny być alokowane przy pomocy funkcji calloc() (alokacja dynamiczna). 53 | 54 | Przygotuj plik Makefile, zawierający polecenia kompilujące pliki źródłowe biblioteki oraz tworzące biblioteki w dwóch wersjach: statyczną i współdzieloną. 55 | 56 | ## Zadanie 2. Program korzystający z biblioteki (25%) 57 | 58 | Napisz program testujący działanie funkcji z biblioteki z zadania 1. 59 | 60 | Jako argumenty przekaż liczbę elementów tablicy głównej (liczbę par plików) oraz listę zadań do wykonania. Zadania mogą stanowić zadania porównania wszystkich par w sekwencji lub zadania usunięcia bloku o podanym indeksie bądź usunięcia operacji o podanym indeksie. 61 | 62 | Operacje mogą być specyfikowane w linii poleceń na przykład jak poniżej: 63 | 64 | * create_table rozmiar — stworzenie tablicy o rozmiarze "rozmiar" 65 | * compare_pairs file1A.txt:file1B.txt file2A.txt:file2B.txt … — porównanie para plików: file1A.txt z file1B.txt, file2A.txt z file2B.txt, itd 66 | * remove_block index- usuń z tablicy bloków o indeksie index 67 | * remove_operation block_index operation_index — usuń z bloku o indeksie block_index operację o indeksie operation_index 68 | 69 | Program powinien stworzyć tablice bloków o zadanej liczbie elementów 70 | 71 | W programie zmierz, wypisz na konsolę i zapisz do pliku z raportem czasy realizacji podstawowych operacji: 72 | 73 | * Przeprowadzenie porównania par plików — różna ilość elementów w sekwencji par (mała (np. 1-5), średnia oraz duża ilość par) oraz różny stopień podobieństwa plików w parze (pliki bardzo podobne do siebie, pliki w średnim stopniu niepodobne do siebie, pliki w znacznym stopniu niepodobne do siebie) 74 | * Zapisanie, w pamięci, bloków o różnych rozmiarach (odpowiadających rozmiarom różnych przeprowadzonych porównań) 75 | * Usunięcie zaalokowanych bloków o różnych rozmiarach (odpowiadających rozmiarom różnych przeprowadzonych porównań) 76 | * Na przemian kilkakrotne dodanie i usunięcie zadanej liczby bloków 77 | 78 | Mierząc czasy poszczególnych operacji, zapisz trzy wartości: czas rzeczywisty, czas użytkownika i czas systemowy. Rezultaty umieść pliku raport2.txt i dołącz do archiwum zadania. 79 | ## Zadanie 3. Testy i pomiary (50%) 80 | 81 | 1. (25%) Przygotuj plik Makefile, zawierający polecenie uruchamiania testów oraz polecenia kompilacji programu z zad 2 na trzy sposoby: 82 | * Z wykorzystaniem bibliotek statycznych, 83 | * Z wykorzystaniem bibliotek dzielonych (dynamiczne, ładowane przy uruchomieniu programu), 84 | * Z wykorzystaniem bibliotek ładowanych dynamicznie (dynamiczne, ładowane przez program). 85 | 86 | Wyniki pomiarów zbierz w pliku results3a.txt. Otrzymane wyniki krótko skomentuj. 87 | 2. (25%) Rozszerz plik Makefile z punktu 3a) dodając możliwość skompilowania programu na trzech różnych poziomach optymalizacji — -O0…-Os. Przeprowadź ponownie pomiary, kompilując i uruchamiając program dla różnych poziomów optymalizacji. 88 | Wyniki pomiarów dodaj do pliku results3b.txt. Otrzymane wyniki krótko skomentuj. 89 | 90 | Wygenerowane pliki z raportami załącz jako element rozwiązania. 91 | 92 | **Uwaga**: Do odczytania pliku można użyć funkcji ```read() (man read)```, do wywołania zewnętrznego polecenia Unixa można użyć funkcji ```system() (man system)```. 93 | -------------------------------------------------------------------------------- /cw10/zad1/client.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | char* client_name; 4 | int server_fd; 5 | char sign; 6 | int move; 7 | pthread_mutex_t move_mutex; 8 | 9 | void disconnect_from_server(){ 10 | printf("Disconnecting from server...\n"); 11 | send_message(server_fd, DISCONNECT, NULL, NULL); 12 | if(shutdown(server_fd, SHUT_RDWR) < 0) error_exit("Cannot shutdown."); 13 | if(close(server_fd) < 0) error_exit("Cannot close server descriptor."); 14 | exit(EXIT_SUCCESS); 15 | } 16 | 17 | void sigint_handler_client(int signo){ 18 | disconnect_from_server(); 19 | } 20 | 21 | void connect_to_local_server(char* server){ 22 | struct sockaddr_un addr; 23 | addr.sun_family = AF_UNIX; 24 | strcpy(addr.sun_path, server); 25 | server_fd = socket(AF_UNIX, SOCK_STREAM, 0); 26 | 27 | if(server_fd < 0) error_exit("Socket to server failed."); 28 | if(connect(server_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) error_exit("Connect to server failed."); 29 | } 30 | 31 | void connect_to_inet_server(int port_number, char* server){ 32 | struct sockaddr_in addr; 33 | addr.sin_family = AF_INET; 34 | addr.sin_port = htons(port_number); 35 | addr.sin_addr.s_addr = inet_addr(server); 36 | server_fd = socket(AF_INET, SOCK_STREAM, 0); 37 | 38 | if(server_fd < 0) error_exit("Socket to server failed."); 39 | if(connect(server_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) error_exit("Connect to server failed."); 40 | } 41 | 42 | 43 | void print_board(game* game){ 44 | printf("BOARD\n"); 45 | printf("Your sign: %c\n\n", sign); 46 | for(int i = 0; i < 9; i++){ 47 | if (game -> board[i] == '-') printf("%d", i); 48 | else printf("%c", game->board[i]); 49 | 50 | if(i % 3 == 2) printf("\n"); 51 | else printf (" "); 52 | } 53 | printf("\n"); 54 | } 55 | 56 | void enemy_move(void* arg){ 57 | message* msg = (message*) arg; 58 | printf("Enter your move: "); 59 | 60 | int move_char = getchar(); 61 | move = move_char - '0'; 62 | 63 | while(move < 0 || move > 8 || msg->game.board[move] != '-'){ 64 | move_char = getchar(); 65 | move = move_char - '0'; 66 | } 67 | pthread_exit(0); 68 | } 69 | 70 | void disconnect(){ 71 | printf("Received DISCONNECT from server. Good bye!\n"); 72 | sigint_handler_client(SIGINT); 73 | exit(EXIT_SUCCESS); 74 | } 75 | 76 | void my_move(message *msg){ 77 | move = -1; 78 | pthread_t move_thread; 79 | pthread_create(&move_thread, NULL, (void*) enemy_move, msg); 80 | 81 | while(1) { 82 | if (move < 0 || move > 8 || msg->game.board[move] != '-') { 83 | message receive_msg = receive_message(server_fd, 1); 84 | 85 | if (receive_msg.message_type == PING) send_message(server_fd, PING, NULL, NULL); 86 | else if (receive_msg.message_type == DISCONNECT) disconnect(); 87 | } 88 | else break; 89 | } 90 | 91 | pthread_join(move_thread, NULL); 92 | msg->game.board[move] = sign; 93 | print_board(&msg->game); 94 | send_message(server_fd, MOVE, &msg->game, NULL); 95 | } 96 | 97 | 98 | void finish_game(game game){ 99 | print_board(&game); 100 | if(game.winner == sign) printf("YOU WON!\n"); 101 | else if(game.winner == 'D') printf("IT'S A DRAW!\n"); 102 | else printf("YOU LOST. REALLY?\n"); 103 | disconnect_from_server(); 104 | exit(EXIT_SUCCESS); 105 | } 106 | 107 | void start_game(message msg){ 108 | sign = msg.game.winner; 109 | printf("Game started. Your sign: %c\n", sign); 110 | print_board(&msg.game); 111 | if(sign == 'O') my_move(&msg); 112 | else printf("Waiting for enemy move\n"); 113 | } 114 | 115 | void make_move(message msg){ 116 | printf("MOVE!\n"); 117 | print_board(&msg.game); 118 | my_move(&msg); 119 | } 120 | 121 | void client_exec(){ 122 | while(1){ 123 | message msg = receive_message(server_fd, 0); 124 | if (msg.message_type == WAIT) printf("Waiting for an opponent.\n"); 125 | else if (msg.message_type == PING) send_message(server_fd, PING, NULL, NULL); 126 | else if (msg.message_type == DISCONNECT) disconnect(); 127 | else if (msg.message_type == GAME_FOUND) start_game(msg); 128 | else if (msg.message_type == MOVE) make_move(msg); 129 | else if (msg.message_type == GAME_FINISHED) finish_game(msg.game); 130 | else break; 131 | } 132 | } 133 | 134 | void connect_with_server(){ 135 | send_message(server_fd, CONNECT, NULL, client_name); 136 | 137 | message msg = receive_message(server_fd, 0); 138 | 139 | if(msg.message_type == CONNECT){ 140 | printf("You connected to server successfully\n"); 141 | client_exec(); 142 | } 143 | if(msg.message_type == CONNECT_FAILED){ 144 | printf("You didn't connect to server. %s\n",msg.name); 145 | if(shutdown(server_fd, SHUT_RDWR) < 0) error_exit("Cannot shutdown."); 146 | if(close(server_fd) < 0) error_exit("Cannot close server descriptor."); 147 | exit(EXIT_FAILURE); 148 | } 149 | 150 | printf("Something went wrong\n"); 151 | } 152 | 153 | 154 | int main(int argc, char** argv){ 155 | 156 | if(argc < 4) error_exit("Wrong number of arguments. Expected: [client name] [LOCAL / INET] [address of server]"); 157 | srand(time(NULL)); 158 | signal(SIGINT, sigint_handler_client); 159 | 160 | client_name = argv[1]; 161 | 162 | connection_type connection; 163 | if(strcmp(argv[2], "LOCAL") == 0) connection = LOCAL; 164 | else if(strcmp(argv[2], "INET") == 0) connection = INET; 165 | else error_exit("Wrong type of connections. Expected: LOCAL / INET"); 166 | 167 | 168 | char* server = argv[3]; 169 | if(connection == LOCAL){ 170 | connect_to_local_server(server); 171 | } 172 | else{ 173 | if(argc < 5) error_exit("Wrong arguments. Expected: [client name] [INET] [adress IP] [port number]"); 174 | printf("Server IP: %s port: %d\n",server, atoi(argv[4])); 175 | connect_to_inet_server(atoi(argv[4]), server); 176 | } 177 | 178 | printf("Welcome in game %s!\n", client_name); 179 | connect_with_server(); 180 | disconnect_from_server(); 181 | } -------------------------------------------------------------------------------- /cw10/zad2/client.c: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | connection_type connection; 4 | int port_number; 5 | char* server; 6 | char* name; 7 | int server_fd; 8 | char sign; 9 | int move; 10 | 11 | void connect_to_local_server(){ 12 | struct sockaddr_un addr; 13 | addr.sun_family = AF_UNIX; 14 | strcpy(addr.sun_path, server); 15 | 16 | server_fd = socket(AF_UNIX, SOCK_DGRAM, 0); // SOCK_DRGAM - supports datagrams (conntectionless, unreliable messages of a fixed max length) 17 | if(server_fd < 0) error_exit("Socket to server failed."); 18 | 19 | struct sockaddr_un c_addr; 20 | c_addr.sun_family = AF_UNIX; 21 | strcpy(c_addr.sun_path, name); 22 | 23 | if(bind(server_fd, (struct sockaddr*) &c_addr, sizeof(c_addr)) < 0) error_exit("Cannot bind"); 24 | if(connect(server_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) error_exit("Cannot connect to server"); 25 | } 26 | 27 | void connect_to_inet_server(){ 28 | struct sockaddr_in addr; 29 | addr.sin_family = AF_INET; 30 | addr.sin_port = htons(port_number); 31 | addr.sin_addr.s_addr = inet_addr(server); 32 | 33 | server_fd = socket(AF_INET, SOCK_DGRAM, 0); 34 | if(server_fd < 0) error_exit("Canot create socket"); 35 | 36 | struct sockaddr_in c_addr; 37 | c_addr.sin_family = AF_INET; 38 | c_addr.sin_port = 0; 39 | c_addr.sin_addr.s_addr = inet_addr(server); 40 | 41 | if(bind(server_fd, (struct sockaddr*) &c_addr, sizeof(c_addr)) < 0) error_exit("Cannot bind"); 42 | if(connect(server_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) error_exit("Cannot connect to server"); 43 | } 44 | 45 | void disconnect_from_server(){ 46 | printf("Disconnecting from server...\n"); 47 | send_message(server_fd, DISCONNECT, NULL, name); 48 | if(connection == LOCAL) unlink(name); 49 | } 50 | 51 | void sigint_handler_client(int signo){ 52 | exit(EXIT_SUCCESS); 53 | } 54 | 55 | void exit_fun(){ 56 | disconnect_from_server(); 57 | } 58 | 59 | void print_gameboard(game* game){ 60 | printf("BOARD\n"); 61 | printf("Your sign: %c\n\n", sign); 62 | 63 | for(int i = 0; i < 9; i++){ 64 | if (game -> board[i] == '-') printf("%d", i); 65 | else printf("%c",game->board[i]); 66 | 67 | if(i % 3 == 2) printf("\n"); 68 | else printf (" "); 69 | } 70 | 71 | printf("\n"); 72 | } 73 | 74 | void enemy_move(void* arg){ 75 | message* msg = (message*) arg; 76 | printf("Enter your move: "); 77 | 78 | int move_char = getchar(); 79 | move = move_char - '0'; 80 | 81 | while(move < 0 || move > 8 || msg->game.board[move] != '-'){ 82 | move_char = getchar(); 83 | move = move_char - '0'; 84 | } 85 | pthread_exit(0); 86 | } 87 | 88 | void make_move(message *msg){ 89 | move = -1; 90 | pthread_t move_thread; 91 | pthread_create(&move_thread, NULL, (void*) enemy_move, msg); 92 | 93 | while(1){ 94 | if(move < 0 || move > 8 || msg->game.board[move] != '-'){ 95 | message rec_msg = receive_message_nonblock(server_fd); 96 | 97 | if (rec_msg.message_type == DISCONNECT){ 98 | sigint_handler_client(SIGINT); 99 | exit(EXIT_SUCCESS); 100 | } 101 | 102 | else if (rec_msg.message_type == PING){ 103 | send_message(server_fd, PING, NULL, name); 104 | } 105 | } 106 | 107 | else{ 108 | break; 109 | } 110 | } 111 | 112 | pthread_join(move_thread, NULL); 113 | msg->game.board[move] = sign; 114 | print_gameboard(&msg->game); 115 | send_message(server_fd, MOVE, &msg->game, name); 116 | } 117 | 118 | void client_exec(){ 119 | while(1){ 120 | 121 | message msg = receive_message(server_fd); 122 | 123 | if (msg.message_type == WAIT) printf("Waiting for an enemy\n"); 124 | else if (msg.message_type == PING) send_message(server_fd, PING, NULL, name); 125 | else if (msg.message_type == DISCONNECT) exit(EXIT_SUCCESS); 126 | else if (msg.message_type == GAME_FOUND){ 127 | sign = msg.game.winner; 128 | printf("Game started. Your symbol: %c\n", sign); 129 | print_gameboard(&msg.game); 130 | if(sign == 'O') make_move(&msg); 131 | else printf("Waiting for enemy move\n"); 132 | } 133 | else if (msg.message_type == MOVE){ 134 | print_gameboard(&msg.game); 135 | make_move(&msg); 136 | } 137 | else if (msg.message_type == GAME_FINISHED){ 138 | print_gameboard(&msg.game); 139 | if(msg.game.winner == sign) printf("You won! Congratulations!\n"); 140 | else if(msg.game.winner == 'D') printf("It's draw\n"); 141 | else printf("You lost! Maybe next time will be better :)\n"); 142 | exit(EXIT_SUCCESS); 143 | } 144 | else break; 145 | } 146 | } 147 | 148 | int main(int argc, char** argv){ 149 | 150 | if(argc < 4) error_exit("Wrong number of arguments. Expected: [client name] [LOCAL / INET] [address of server]"); 151 | 152 | name = argv[1]; 153 | atexit(exit_fun); 154 | signal(SIGINT, sigint_handler_client); 155 | 156 | if(strcmp(argv[2], "LOCAL") == 0) connection = LOCAL; 157 | else if(strcmp(argv[2], "INET") == 0) connection = INET; 158 | else error_exit("Wrong type of connections. Expected: LOCAL / INET"); 159 | 160 | if(connection == LOCAL){ 161 | server = argv[3]; 162 | connect_to_local_server(); 163 | } 164 | else{ 165 | if(argc < 5) error_exit("Wrong arguments. Expected: [client name] [INET] [adress IP] [port number]"); 166 | server = argv[3]; 167 | port_number = atoi(argv[4]); 168 | printf("Server IP: %s port: %d\n",server, port_number); 169 | connect_to_inet_server(); 170 | } 171 | 172 | printf("Welcome in game %s!\n", name); 173 | send_message(server_fd, CONNECT, NULL, name); 174 | message msg = receive_message(server_fd); 175 | 176 | if(msg.message_type == CONNECT){ 177 | printf("Client is connected to server\n"); 178 | client_exec(); 179 | } 180 | if(msg.message_type == CONNECT_FAILED){ 181 | printf("Cannot connect %s\n",msg.name); 182 | if(shutdown(server_fd, SHUT_RDWR) < 0) 183 | error_exit("Cannot shutdown"); 184 | if(close(server_fd) < 0) 185 | error_exit("Cannot close server descriptor"); 186 | exit(EXIT_FAILURE); 187 | } 188 | 189 | disconnect_from_server(); 190 | } -------------------------------------------------------------------------------- /cw01/zad1/library.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "library.h" 5 | #include 6 | 7 | 8 | //create main array 9 | struct MainArray* createArray(int numberOfBlocks){ 10 | if (numberOfBlocks <= 0) return NULL; 11 | struct MainArray *mainArray= (struct MainArray*)calloc(1,sizeof(struct MainArray)); 12 | mainArray -> numberOfBlocks = numberOfBlocks; 13 | mainArray -> blocks = (struct Block**)calloc(numberOfBlocks, sizeof(struct Block*)); 14 | return mainArray; 15 | } 16 | 17 | //create Block 18 | struct Block *createBlock(int numberOfOperations){ 19 | if(numberOfOperations < 0) return NULL; 20 | struct Block * block=(struct Block*)calloc(1,sizeof(struct Block)); 21 | if (numberOfOperations == 0) block -> operations = NULL; 22 | else block -> operations=(char**)calloc(numberOfOperations,sizeof(char*)); 23 | block -> numberOfOperations = numberOfOperations; 24 | return block; 25 | } 26 | 27 | //delete block at index 28 | void deleteBlock(struct MainArray* mainArray, int index){ 29 | if(mainArray -> numberOfBlocks <= index || index < 0 || mainArray == NULL || mainArray -> blocks == NULL || mainArray -> blocks[index] == NULL) return; 30 | for(int i = 0; i < mainArray -> blocks[index] -> numberOfOperations; i++){ 31 | if (mainArray -> blocks[index] -> operations[i] != NULL){ 32 | free(mainArray -> blocks[index] -> operations[i]); 33 | mainArray -> blocks[index] -> operations[i] = NULL; 34 | } 35 | } 36 | if (mainArray -> blocks[index] != NULL){ 37 | free(mainArray -> blocks[index]); 38 | mainArray -> blocks[index] = NULL; 39 | } 40 | 41 | } 42 | 43 | //delete operation at index from block at index 44 | void deleteOperation(struct MainArray* mainArray, int block_index, int operation_index){ 45 | if (mainArray -> blocks[block_index] -> operations[operation_index] == NULL) return; 46 | free(mainArray -> blocks[block_index] -> operations[operation_index]); 47 | mainArray -> blocks[block_index] -> operations[operation_index] = NULL; 48 | } 49 | 50 | //delete main array 51 | void deleteArray(struct MainArray* mainArray){ 52 | if (mainArray == NULL) return; 53 | for (int i = 0; i < mainArray -> numberOfBlocks; i++){ 54 | deleteBlock(mainArray, i); 55 | } 56 | free(mainArray); 57 | } 58 | 59 | //compare two files with diff command 60 | void compareTwoFiles(char* file1, char*file2){ 61 | system("touch tmp.txt"); 62 | char tmp[50 + strlen(file1) + strlen(file2)]; 63 | strcpy(tmp, "diff "); 64 | strcat(tmp, file1); 65 | strcat(tmp, " "); 66 | strcat(tmp, file2); 67 | strcat(tmp, " >> tmp.txt"); 68 | system(tmp); 69 | } 70 | 71 | //count operations in block for two files 72 | int countOperationsInBlock(char *file1, char *file2){ 73 | char command[20 + strlen(file1) + strlen(file2)]; 74 | strcpy(command, "diff "); 75 | strcat(command, file1); 76 | strcat(command, " "); 77 | strcat(command, file2); 78 | strcat (command, " | grep -c ^[0-9]"); 79 | 80 | FILE *fp = popen(command,"r"); 81 | int counter; 82 | fscanf(fp,"%d", &counter); 83 | return counter; 84 | } 85 | 86 | //create block and operations for file tmp.txt 87 | struct Block* createBlockAndOperations(char *tmp, int numberOfOperations){ 88 | FILE *f = fopen(tmp, "r"); 89 | if(f == NULL) exit(0); 90 | char *line = NULL; 91 | size_t len = 0; 92 | 93 | struct Block * block = createBlock(numberOfOperations); 94 | if(numberOfOperations == 0) { 95 | block -> operations = NULL; 96 | fclose(f); 97 | return block; 98 | } 99 | char operation[100000]; 100 | strcpy(operation,""); 101 | int i = 0; 102 | while(getline(&line, &len, f) != -1){ 103 | if(line[0] >= '0' && line[0] <= '9'){ 104 | if(strcmp(operation, "") != 0){ 105 | block -> operations[i]=(char*)calloc(10000, sizeof(char)); 106 | strcpy(block -> operations[i], operation); 107 | i++; 108 | strcpy(operation ,""); 109 | } 110 | } 111 | strcat(operation, line); 112 | } 113 | 114 | if(strcmp(operation, "") != 0){ //last editing operation 115 | block -> operations[i]=(char*)calloc(10000, sizeof(char)); 116 | strcpy(block -> operations[i], operation); 117 | } 118 | 119 | fclose(f); 120 | if (line) free(line); 121 | return block; 122 | } 123 | 124 | //conversion string with files to array with files 125 | void definePairSequence(char* files, char**newFiles) // file1A.txt:file1B.txt file2A.txt:file2B.txt 126 | { 127 | 128 | if(files == NULL || strlen(files) == 0) exit (0); 129 | char *filesCpy = calloc(strlen(files), sizeof(char)); 130 | strcpy(filesCpy, files); 131 | char *ptr = strtok(filesCpy, ": "); 132 | char *file1, *file2; 133 | int index = 0; 134 | 135 | while (ptr != NULL) 136 | { 137 | file1 = ptr; 138 | ptr = strtok(NULL, ": "); 139 | newFiles[index] = file1; 140 | index ++; 141 | 142 | if(ptr == NULL) exit (-1); 143 | file2 = ptr; 144 | ptr = strtok(NULL, ": "); 145 | newFiles[index] = file2; 146 | index++; 147 | 148 | } 149 | } 150 | 151 | // count number of files in string 152 | int countNumberOfFiles(char* filesInString){ 153 | int numberOfFiles = 0; 154 | char*string = strdup(filesInString); 155 | char*token = strtok(string, " "); 156 | while(token!=NULL){ 157 | token = strtok(NULL, " "); 158 | numberOfFiles ++; 159 | } 160 | return 2 * numberOfFiles; 161 | } 162 | 163 | //compare every pair of files and create structures 164 | void comparePairs(char *filesInString, struct MainArray *mainArray){ 165 | int size = countNumberOfFiles(filesInString); 166 | if (size%2 != 0) exit(0); 167 | char** files = (char**)calloc(size, sizeof(char*)); 168 | definePairSequence(filesInString, files); 169 | 170 | for (int i = 0; i< size-1; i+=2){ 171 | compareTwoFiles(files[i], files[i+1]); 172 | int numberOfOperations = countOperationsInBlock(files[i], files[i+1]); 173 | struct Block* block = createBlockAndOperations("tmp.txt", numberOfOperations); 174 | 175 | system("rm tmp.txt"); 176 | 177 | for(int i =0 ; inumberOfBlocks;i++){ 178 | if(mainArray->blocks[i]==NULL){ 179 | mainArray -> blocks[i] = block; 180 | break; 181 | } 182 | } 183 | } 184 | } 185 | 186 | //number of operations for block at index 187 | int getNumberOfOperations(struct MainArray* mainArray, int indexOfBlock){ 188 | if (mainArray == NULL || mainArray -> blocks[indexOfBlock] == NULL) return 0; 189 | return mainArray -> blocks[indexOfBlock] -> numberOfOperations; 190 | } 191 | 192 | //operations at index from block at index 193 | char* getOperation(struct MainArray* mainArray, int indexOfBlock, int indexOfOperation){ 194 | return mainArray -> blocks[indexOfBlock] -> operations[indexOfOperation]; 195 | } 196 | -------------------------------------------------------------------------------- /cw10/zad2/common.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSOPY_COMMON_H 2 | #define SYSOPY_COMMON_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define MAX_CLIENTS 13 24 | #define MSG_SIZE 30 25 | #define NAME_LEN 8 26 | 27 | #define PING_INTERVAL 10 28 | #define PING_WAIT 5 29 | 30 | enum connection_type{ 31 | LOCAL, 32 | INET 33 | }; typedef enum connection_type connection_type; 34 | 35 | enum message_type{ 36 | CONNECT, 37 | CONNECT_FAILED, 38 | PING, 39 | WAIT, 40 | GAME_FOUND, 41 | MOVE, 42 | GAME_FINISHED, 43 | DISCONNECT, 44 | EMPTY 45 | }; typedef enum message_type message_type; 46 | 47 | struct game{ 48 | char board[9]; 49 | char turn; 50 | char winner; 51 | }; typedef struct game game; 52 | 53 | struct message{ 54 | message_type message_type; 55 | game game; //null for non game messages 56 | char name[NAME_LEN]; 57 | }; typedef struct message message; 58 | 59 | struct client{ 60 | int fd; 61 | struct sockaddr* addr; 62 | char* name; 63 | int active; 64 | int opponent_idx; 65 | game* game; 66 | char symbol; 67 | }; typedef struct client client; 68 | 69 | void new_board(game* game){ 70 | for(int i = 0; i < 9; i++) game->board[i] = '-'; 71 | game->turn = 'O'; 72 | game->winner = '-'; 73 | } 74 | 75 | 76 | void error_exit(char* message){ 77 | printf("ERROR: %s\n", message); 78 | exit(EXIT_FAILURE); 79 | } 80 | 81 | void send_message(int fd, message_type type, game* game, char* nick){ 82 | char* message = calloc(MSG_SIZE, sizeof(char)); 83 | if(game == NULL) sprintf(message, "%d %s", (int) type, nick); 84 | else sprintf(message, "%d %s %c %c %s", (int) type, game->board, game->turn, game->winner, nick); 85 | if(write(fd, message, MSG_SIZE) < 0) error_exit("Could not send message."); 86 | free(message); 87 | } 88 | 89 | void send_message_to(int fd, struct sockaddr* addr, message_type type, game* game, char* nick){ 90 | char* message = calloc(MSG_SIZE, sizeof(char)); 91 | if(game == NULL)sprintf(message, "%d %s", (int) type, nick); 92 | else sprintf(message, "%d %s %c %c %s", (int) type, game->board, game->turn, game->winner, nick); 93 | if(sendto(fd, message, MSG_SIZE, 0, addr, sizeof(struct sockaddr)) < 0) error_exit("Could not send message."); 94 | free(message); 95 | } 96 | 97 | message receive_message(int fd){ 98 | 99 | message msg; 100 | int count; 101 | char* msg_buf = calloc(MSG_SIZE, sizeof(char)); 102 | 103 | if((count = read(fd, msg_buf, MSG_SIZE)) < 0) error_exit("Could not receive message."); 104 | if(count == 0){ 105 | msg.message_type = DISCONNECT; 106 | free(msg_buf); 107 | return msg; 108 | } 109 | 110 | char* token; 111 | char* rest = msg_buf; 112 | strcpy(msg.name, ""); 113 | new_board(&msg.game); 114 | token = strtok_r(rest, " ", &rest); 115 | msg.message_type = (message_type) atoi(token); 116 | 117 | if (msg.message_type == CONNECT){ 118 | token = strtok_r(rest, " ", &rest); 119 | strcpy(msg.name, token); 120 | } 121 | else if (msg.message_type == DISCONNECT || msg.message_type == PING || msg.message_type == WAIT){ 122 | token = strtok_r(rest, " ", &rest); 123 | strcpy(msg.name, token); 124 | free(msg_buf); 125 | return msg; 126 | } 127 | else if (msg.message_type == MOVE || msg.message_type == GAME_FINISHED || msg.message_type == GAME_FOUND){ 128 | token = strtok_r(rest, " ", &rest); 129 | strcpy(msg.game.board, token); 130 | token = strtok_r(rest, " ", &rest); 131 | msg.game.turn = token[0]; 132 | token = strtok_r(rest, " ", &rest); 133 | msg.game.winner = token[0]; 134 | token = strtok_r(rest, " ", &rest); 135 | strcpy(msg.name, token); 136 | } 137 | 138 | free(msg_buf); 139 | 140 | return msg; 141 | 142 | } 143 | 144 | message receive_message_from(int fd, struct sockaddr* addr, socklen_t len){ 145 | 146 | message msg; 147 | int count; 148 | char* msg_buf = calloc(MSG_SIZE, sizeof(char)); 149 | 150 | if((count = recvfrom(fd, msg_buf, MSG_SIZE, 0, addr, &len)) < 0) // receive message from socket 151 | error_exit("Could not receive message."); 152 | 153 | if(count == 0){ 154 | msg.message_type=DISCONNECT; 155 | free(msg_buf); 156 | return msg; 157 | } 158 | 159 | char* token; 160 | char* rest = msg_buf; 161 | strcpy(msg.name, ""); 162 | new_board(&msg.game); 163 | token = strtok_r(rest, " ", &rest); 164 | msg.message_type = (message_type) atoi(token); 165 | 166 | switch(msg.message_type){ 167 | case CONNECT: 168 | token = strtok_r(rest, " ", &rest); 169 | strcpy(msg.name, token); 170 | break; 171 | case PING: case WAIT: case DISCONNECT: 172 | token = strtok_r(rest, " ", &rest); 173 | strcpy(msg.name, token); 174 | free(msg_buf); 175 | return msg; 176 | case MOVE: case GAME_FOUND: case GAME_FINISHED: 177 | token = strtok_r(rest, " ", &rest); 178 | strcpy(msg.game.board, token); 179 | token = strtok_r(rest, " ", &rest); 180 | msg.game.turn = token[0]; 181 | token = strtok_r(rest, " ", &rest); 182 | msg.game.winner = token[0]; 183 | break; 184 | default: 185 | break; 186 | } 187 | 188 | free(msg_buf); 189 | 190 | return msg; 191 | 192 | } 193 | 194 | message receive_message_nonblock(int fd){ 195 | 196 | message msg; 197 | char* msg_buf = calloc(MSG_SIZE, sizeof(char)); 198 | int count; 199 | 200 | if((count = recv(fd, msg_buf, MSG_SIZE, MSG_DONTWAIT)) < 0){ 201 | msg.message_type = EMPTY; 202 | free(msg_buf); 203 | return msg; 204 | } 205 | 206 | if(count == 0){ 207 | msg.message_type = DISCONNECT; 208 | free(msg_buf); 209 | return msg; 210 | } 211 | 212 | char *token; 213 | char *rest = msg_buf; 214 | 215 | char* p; 216 | 217 | strcpy(msg.name, ""); 218 | new_board(&msg.game); 219 | token = strtok_r(rest, " ", &rest); 220 | 221 | msg.message_type = (message_type) strtol(token, &p, 10); 222 | 223 | switch (msg.message_type) { 224 | case CONNECT: 225 | token = strtok_r(rest, " ", &rest); 226 | strcpy(msg.name, token); 227 | break; 228 | case PING: case WAIT: case DISCONNECT: 229 | token = strtok_r(rest, " ", &rest); 230 | strcpy(msg.name, token); 231 | free(msg_buf); 232 | return msg; 233 | case MOVE: case GAME_FOUND: case GAME_FINISHED: 234 | token = strtok_r(rest, " ", &rest); 235 | strcpy(msg.game.board, token); 236 | token = strtok_r(rest, " ", &rest); 237 | msg.game.turn = token[0]; 238 | token = strtok_r(rest, " ", &rest); 239 | msg.game.winner = token[0]; 240 | break; 241 | default: 242 | break; 243 | } 244 | 245 | free(msg_buf); 246 | 247 | return msg; 248 | 249 | } 250 | 251 | #endif //SYSOPY_COMMON_H -------------------------------------------------------------------------------- /cw02/zad2/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #define __USE_XOPEN_EXTENDED 1 13 | #include 14 | 15 | const char format[] = "%Y-%m-%d %H:%M:%S"; 16 | int atime = -1, mtime = -1; 17 | int max_depth = 100000; 18 | char asign, msign; 19 | 20 | void print_results(char* file_path, struct stat *stat){ 21 | char file_type[64] = "undefined"; 22 | if (S_ISREG(stat -> st_mode)) strcpy(file_type, "file"); 23 | else if (S_ISDIR(stat -> st_mode)) strcpy(file_type, "dir"); 24 | else if (S_ISLNK(stat -> st_mode)) strcpy(file_type, "slink"); 25 | else if (S_ISCHR(stat -> st_mode)) strcpy(file_type, "char dev"); 26 | else if (S_ISBLK(stat -> st_mode)) strcpy(file_type, "block dev"); 27 | else if (S_ISFIFO(stat -> st_mode)) strcpy(file_type, "fifo"); 28 | else if (S_ISSOCK(stat -> st_mode)) strcpy(file_type, "socket"); 29 | 30 | struct tm tm_modif_time; 31 | localtime_r(&stat -> st_mtime, &tm_modif_time); 32 | char modif_time_str[255]; 33 | strftime(modif_time_str, 255, format, &tm_modif_time); 34 | 35 | struct tm tm_access_time; 36 | localtime_r(&stat -> st_atime, &tm_access_time); 37 | char access_time_str[255]; 38 | strftime(access_time_str, 255, format, &tm_access_time); 39 | 40 | printf("Path: %s || type: %s, size: %ld, modification time: %s, access time: %s, nlinks: %ld\n\n", 41 | file_path, file_type, stat -> st_size, modif_time_str, access_time_str, stat -> st_nlink); 42 | } 43 | 44 | void print_results_nftw(const char* file_path, const struct stat *stat){ 45 | char file_type[64] = "undefined"; 46 | if (S_ISREG(stat -> st_mode)) strcpy(file_type, "file"); 47 | else if (S_ISDIR(stat -> st_mode)) strcpy(file_type, "dir"); 48 | else if (S_ISLNK(stat -> st_mode)) strcpy(file_type, "slink"); 49 | else if (S_ISCHR(stat -> st_mode)) strcpy(file_type, "char dev"); 50 | else if (S_ISBLK(stat -> st_mode)) strcpy(file_type, "block dev"); 51 | else if (S_ISFIFO(stat -> st_mode)) strcpy(file_type, "fifo"); 52 | else if (S_ISSOCK(stat -> st_mode)) strcpy(file_type, "socket"); 53 | 54 | struct tm tm_modif_time; 55 | localtime_r(&stat -> st_mtime, &tm_modif_time); 56 | char modif_time_str[255]; 57 | strftime(modif_time_str, 255, format, &tm_modif_time); 58 | 59 | struct tm tm_access_time; 60 | localtime_r(&stat -> st_atime, &tm_access_time); 61 | char access_time_str[255]; 62 | strftime(access_time_str, 255, format, &tm_access_time); 63 | 64 | printf("Path: %s || type: %s, size: %ld, modification time: %s, access time: %s, nlinks: %ld\n\n", 65 | file_path, file_type, stat -> st_size, modif_time_str, access_time_str, stat -> st_nlink); 66 | } 67 | 68 | int check_time(int count, char sign, time_t time_from_file){ 69 | time_t now; 70 | struct tm *time_info; 71 | time(&now); 72 | time_info = localtime(&now); 73 | time_t current_date = mktime(time_info); 74 | 75 | int diff = difftime(current_date, time_from_file) / 86400; // (24h * 60min * 60s) 76 | 77 | if ((sign == '+' && diff > count) || (sign == '-' && diff < count) || (sign == '=' && diff == count)) 78 | return 1; 79 | 80 | return 0; 81 | } 82 | 83 | int check_conditions(struct stat* dir_stat){ 84 | if (atime != -1 && check_time(atime, asign, dir_stat -> st_atime) == 0) return 0; 85 | if (mtime != -1 && check_time(mtime, msign, dir_stat -> st_mtime) == 0) return 0; 86 | return 1; 87 | } 88 | 89 | int check_conditions_nftw(const struct stat* dir_stat){ 90 | if (atime != -1 && check_time(atime, asign, dir_stat -> st_atime) == 0) return 0; 91 | if (mtime != -1 && check_time(mtime, msign, dir_stat -> st_mtime) == 0) return 0; 92 | return 1; 93 | } 94 | 95 | void find_dir(char *path, int depth){ 96 | if (depth > max_depth) return; 97 | if (path == NULL) return; 98 | DIR* dir = opendir(path); 99 | if (dir == NULL){ 100 | printf("Cannot open directory"); 101 | exit(EXIT_FAILURE); 102 | } 103 | 104 | struct dirent *file; 105 | char new_path[256]; 106 | 107 | while ((file = readdir(dir)) != NULL){ 108 | strcpy(new_path, path); 109 | strcat(new_path, "/"); 110 | strcat(new_path, file -> d_name); 111 | 112 | struct stat buffer; 113 | if (lstat(new_path, &buffer) < 0){ 114 | printf("Cannot lstat file %s: ", new_path); 115 | exit(EXIT_FAILURE); 116 | } 117 | 118 | if (S_ISDIR(buffer.st_mode)){ 119 | if (strcmp(file -> d_name, ".") == 0 || strcmp(file -> d_name, "..") == 0){ 120 | continue; 121 | } 122 | find_dir(new_path, depth + 1); 123 | } 124 | if (check_conditions(&buffer) == 1){ 125 | print_results(new_path, &buffer); 126 | } 127 | 128 | } 129 | closedir(dir); 130 | } 131 | 132 | static int find_nftw(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf){ 133 | if (ftwbuf -> level > max_depth) return 0; 134 | if (check_conditions_nftw(sb) == 1){ 135 | print_results_nftw(fpath, sb); 136 | } 137 | return 0; 138 | } 139 | 140 | int main(int argc, char** argv){ 141 | if (argc < 2){ 142 | printf("Wrong number of arguments"); 143 | exit(EXIT_FAILURE); 144 | } 145 | 146 | char* path; 147 | path = argv[1]; 148 | int i = 2; 149 | int is_nftw = 0; 150 | 151 | while(i < argc){ 152 | if (!strcmp(argv[i], "-mtime")){ 153 | if (mtime != -1){ 154 | printf("Too many declarations of mtimt"); 155 | exit(EXIT_FAILURE); 156 | } 157 | i++; 158 | if (argv[i][0] == '+' || argv[i][0] == '-') msign = argv[i][0]; 159 | else msign = '='; 160 | mtime = abs(atoi(argv[i])); 161 | } 162 | else if(!strcmp(argv[i], "-atime")){ 163 | if (atime != -1){ 164 | printf("Too many declarations of atimt"); 165 | exit(EXIT_FAILURE); 166 | } 167 | i++; 168 | if (argv[i][0] == '+' || argv[i][0] == '-') asign = argv[i][0]; 169 | else asign = '='; 170 | atime = abs(atoi(argv[i])); 171 | } 172 | else if (!strcmp(argv[i], "-maxdepth")){ 173 | i++; 174 | max_depth = atoi(argv[i]); 175 | } 176 | else if (!strcmp(argv[i], "nftw")) { 177 | is_nftw = 1; 178 | } 179 | i ++; 180 | } 181 | 182 | if (is_nftw == 1){ 183 | nftw(path, find_nftw, 10, FTW_PHYS); 184 | } 185 | else{ 186 | find_dir(path, 1); 187 | } 188 | return 0; 189 | 190 | } 191 | --------------------------------------------------------------------------------