├── lab1_v2 ├── zad1 │ ├── main.c │ ├── makefile │ └── lib_diff.h ├── zad2 │ ├── makefile │ ├── raport2.txt │ ├── args.txt │ ├── diff_dynamic.h │ └── main.c ├── zad3a │ ├── makefile │ ├── args.txt │ └── raport3a.txt ├── zad3b │ ├── makefile │ └── args.txt └── README.md ├── lab3 ├── zad1 │ ├── makefile │ └── main.c ├── zad3 │ ├── makefile │ ├── help.c │ └── matrix_helper.c ├── zad2 │ ├── makefile │ ├── help.c │ └── matrix_helper.c └── README.md ├── lab1 ├── zad1 │ ├── c.txt │ ├── d.txt │ ├── a.txt │ ├── e.txt │ ├── f.txt │ ├── b.txt │ ├── library.h │ ├── makefile │ ├── main.c │ └── library.c ├── .vscode │ └── settings.json ├── .gitignore ├── zad2 │ ├── makefile │ ├── raport2.txt │ ├── args.txt │ ├── diff_dynamic.h │ └── main.c ├── zad3a │ ├── makefile │ ├── args.txt │ └── raport3a.txt ├── zad3b │ ├── makefile │ └── args.txt └── README.md ├── .vscode └── settings.json ├── README.md ├── lab4 ├── zad1 │ ├── makefile │ └── main.c ├── zad3 │ ├── makefile │ └── main.c ├── zad4a │ ├── makefile │ ├── catcher.c │ └── sender.c ├── zad4b │ ├── makefile │ ├── catcher.c │ └── sender.c ├── zad2 │ ├── raport2.txt │ ├── makefile │ ├── exec.c │ └── main.c └── README.md ├── lab5 ├── zad2 │ ├── file.txt │ ├── makefile │ └── sort.c ├── zad1 │ ├── file.txt │ ├── makefile │ ├── popen.c │ └── pipes.c ├── zad3 │ ├── makefile │ ├── consumer.c │ ├── producer.c │ └── main.c └── README.md ├── lab9 ├── zad1 │ ├── makefile │ └── barber.c └── README.md ├── lab6 ├── zad1 │ ├── keygen.h │ ├── utils.h │ ├── types.h │ ├── makefile │ ├── message.h │ ├── keygen.c │ ├── que.h │ ├── que.c │ ├── utils.c │ └── client.c ├── zad2 │ ├── makefile │ ├── types.h │ ├── types.c │ └── server.c └── README.md ├── lab2 ├── zad2 │ ├── makefile │ ├── readme.md │ └── find_nftw.c ├── zad1 │ ├── generator.h │ ├── makefile │ └── generator_prog.c └── README.md ├── lab7 ├── zad1 │ ├── makefile │ ├── shared.c │ ├── shared.h │ ├── worker_1.c │ ├── worker_3.c │ ├── worker_2.c │ └── main.c ├── zad2 │ ├── makefile │ ├── shared.h │ ├── worker_1.c │ ├── worker_3.c │ ├── worker_2.c │ └── main.c └── README.md ├── lab10 ├── zad1 │ └── makefile ├── zad2 │ └── makefile └── README.md ├── .gitignore └── lab8 ├── zad1 ├── makefile └── Times.txt └── README.md /lab1_v2/zad1/main.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lab3/zad1/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -Wall -o main main.c -------------------------------------------------------------------------------- /lab1/zad1/c.txt: -------------------------------------------------------------------------------- 1 | aaa 2 | bbb ccc 3 | ddd 4 | eee 5 | hhh iii -------------------------------------------------------------------------------- /lab1/zad1/d.txt: -------------------------------------------------------------------------------- 1 | jjj kkk 2 | aaa 3 | fff ccc 4 | eee 5 | bbb ggg -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.errorSquiggles": "Disabled" 3 | } -------------------------------------------------------------------------------- /lab1/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.errorSquiggles": "Disabled" 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SYSOPY 2 | ## AGH Operating Systems Course 2020 3 | Jeśli pomogłem daj gwiazdkę <3 4 | -------------------------------------------------------------------------------- /lab4/zad1/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -Wall -std=c99 -o main main.c 3 | ./main 4 | clean: 5 | rm -rf main -------------------------------------------------------------------------------- /lab5/zad2/file.txt: -------------------------------------------------------------------------------- 1 | zzzz 2 | aa 3 | hsjdhjk 4 | sdasdsa 5 | dfds 6 | dfggg 7 | dfddd 8 | aafgh 9 | pksdf -------------------------------------------------------------------------------- /lab5/zad1/file.txt: -------------------------------------------------------------------------------- 1 | cat ./pipes.c | wc -l 2 | cat ./pipes.c | head -3 | sort -r 3 | ps -aux | grep root | wc -l -------------------------------------------------------------------------------- /lab5/zad2/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -Wall -std=c99 -o sort sort.c 3 | ./sort file.txt 4 | make clean 5 | clean: 6 | rm sort -------------------------------------------------------------------------------- /lab9/zad1/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | make clean 3 | gcc -o main barber.c -lpthread -lm 4 | ./main 5 5 5 | clean: 6 | rm -f main -------------------------------------------------------------------------------- /lab1/zad1/a.txt: -------------------------------------------------------------------------------- 1 | aaa 2 | bbb ccc 3 | ddd 4 | eee 5 | hhh 6 | sdf 7 | sass 8 | aaa 9 | asdff 10 | aa 11 | koza 12 | a2 -------------------------------------------------------------------------------- /lab1/zad1/e.txt: -------------------------------------------------------------------------------- 1 | I need to buy apples. 2 | I need to do the laundry. 3 | I need to wash the car. 4 | I need to get the dog detailed. -------------------------------------------------------------------------------- /lab1/zad1/f.txt: -------------------------------------------------------------------------------- 1 | I need to buy apples. 2 | I need to run the laundry. 3 | I need to wash the dog. 4 | I need to get the car detailed. -------------------------------------------------------------------------------- /lab1/zad1/b.txt: -------------------------------------------------------------------------------- 1 | jjj kkk 2 | aaa 3 | fff ccc 4 | eee 5 | a sksk 6 | as 7 | df 8 | af 9 | sss 10 | ffgdfg 11 | a2 12 | koza 13 | -------------------------------------------------------------------------------- /lab4/zad3/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -Wall -std=c99 -o main main.c 3 | ./main sigint 4 | ./main queue 5 | ./main child 6 | 7 | 8 | clean: 9 | rm -rf main -------------------------------------------------------------------------------- /lab6/zad1/keygen.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYGEN_H 2 | #define KEYGEN_H 3 | #include 4 | 5 | key_t get_public_key(); 6 | key_t get_private_key(); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /lab6/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall 2 | 3 | all: 4 | gcc server.c types.c -o server -lrt 5 | gcc client.c types.c -o client -lrt 6 | 7 | clean: 8 | rm -f client server *.o -------------------------------------------------------------------------------- /lab6/zad1/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILS_H 2 | #define UTILS_H 3 | 4 | void split_line(char *line, char *output[], int *output_len); 5 | void separate_command(char *line, char *command, char *rest); 6 | 7 | #endif -------------------------------------------------------------------------------- /lab1/.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.so 3 | zad2/*.txt 4 | zad1/*.txt 5 | *.txt 6 | !zad2/args.txt 7 | !zad2/raport2.txt 8 | main 9 | !zad3a/args.txt 10 | !zad3a/raport3a.txt 11 | !zad3b/args.txt 12 | !zad3b/raport3b.txt 13 | -------------------------------------------------------------------------------- /lab6/zad1/types.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPES_H 2 | #define TYPES_H 3 | 4 | #define TYPE_STOP 1 5 | #define TYPE_DISCONNECT 2 6 | #define TYPE_LIST 3 7 | #define TYPE_CONNECT 4 8 | #define TYPE_INIT 5 9 | #define TYPE_MESSAGE 6 10 | #endif -------------------------------------------------------------------------------- /lab4/zad4a/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -Wall -std=c99 3 | 4 | all: 5 | make catcher 6 | make sender 7 | catcher: 8 | $(CC) $(FLAGS) catcher.c -o catcher 9 | 10 | sender: 11 | $(CC) $(FLAGS) sender.c -o sender 12 | 13 | clean: 14 | rm -rf sender catcher -------------------------------------------------------------------------------- /lab4/zad4b/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -Wall -std=c99 3 | 4 | all: 5 | make catcher 6 | make sender 7 | 8 | catcher: 9 | $(CC) $(FLAGS) catcher.c -o catcher 10 | 11 | sender: 12 | $(CC) $(FLAGS) sender.c -o sender 13 | clean: 14 | rm -rf catcher sender -------------------------------------------------------------------------------- /lab2/zad2/makefile: -------------------------------------------------------------------------------- 1 | dir: 2 | gcc -Wall -o main find_dir.c 3 | ./main ../../ mtime + 7 -1 4 | ./main ../../ mtime + 7 1 5 | ./main ../../ atime - 3 2 6 | nftw: 7 | gcc -Wall -o main find_nftw.c 8 | ./main ../../ mtime + 7 -1 9 | ./main ../../ mtime + 7 1 10 | ./main ../../ atime - 3 2 -------------------------------------------------------------------------------- /lab5/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | 4 | all: 5 | make pipes 6 | make popen 7 | make clean 8 | 9 | pipes: 10 | $(CC) $(FLAGS) -o pipes pipes.c 11 | ./pipes file.txt 12 | 13 | popen: 14 | $(CC) $(FLAGS) -o popen popen.c 15 | ./popen file.txt 16 | clean: 17 | rm pipes popen -------------------------------------------------------------------------------- /lab7/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC=gcc -Wall 2 | 3 | all: build test clean 4 | 5 | build: 6 | $(CC) -o main main.c 7 | $(CC) -o worker_1 worker_1.c shared.c 8 | $(CC) -o worker_2 worker_2.c shared.c 9 | $(CC) -o worker_3 worker_3.c shared.c 10 | 11 | test: 12 | ./main 13 | 14 | clean: 15 | rm -f main worker_1 worker_2 worker_3 -------------------------------------------------------------------------------- /lab5/zad3/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -Wall -std=c99 -o producer producer.c 3 | gcc -Wall -std=c99 -o consumer consumer.c 4 | gcc -Wall -std=c99 -o main main.c 5 | ./main 6 | make clean 7 | prod: 8 | ./producer fif producer_data/a 5 9 | cons: 10 | ./consumer fif consumer_data/a 5 11 | clean: 12 | rm fif producer main consumer -------------------------------------------------------------------------------- /lab4/zad2/raport2.txt: -------------------------------------------------------------------------------- 1 | Raport dla fork(): 2 | Sygnal ktory czeka w przodku nie jest widoczny w dziecku po wywolaniu funcjki fork(). 3 | Proces potomny "dziedziczy" maskowanie, handlery i ignorowanie. 4 | Raport dla exec(): 5 | Po wykonaniu fincji exec dziedziczone jest maskowanie i ignorowanie. 6 | Sygnal oczekujacy w przodku rowniez oczekuje w potomku. -------------------------------------------------------------------------------- /lab3/zad3/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall -std=c11 -ggdb 2 | 3 | all: 4 | make test 5 | 6 | clean: 7 | rm -f -r .tmp files help matrix lista 8 | 9 | helper: 10 | rm -f help 11 | $(CC) help.c -o help 12 | 13 | test: 14 | make clean 15 | $(CC) help.c -o help 16 | $(CC) matrix.c -o matrix 17 | ./help create 7 14 5 18 | ./matrix lista 6 3 1 1 100 -------------------------------------------------------------------------------- /lab7/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC=gcc -Wall 2 | 3 | all: build test clean 4 | 5 | build: 6 | $(CC) -o main main.c -lpthread -lrt 7 | $(CC) -o worker1 worker_1.c -lpthread -lrt 8 | $(CC) -o worker2 worker_2.c -lpthread -lrt 9 | $(CC) -o worker3 worker_3.c -lpthread -lrt 10 | 11 | test: 12 | ./main 13 | 14 | clean: 15 | rm -f main worker1 worker2 worker3 -------------------------------------------------------------------------------- /lab6/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | 4 | all: 5 | make clean 6 | make server 7 | make client 8 | make r: 9 | make server 10 | make client 11 | server: 12 | $(CC) $(FLAGS) server.c keygen.c que.c utils.c -o server 13 | 14 | client: 15 | $(CC) $(FLAGS) client.c keygen.c que.c utils.c -o client 16 | 17 | clean: 18 | rm server client -------------------------------------------------------------------------------- /lab4/zad2/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | make normal 3 | make clean 4 | 5 | exec: 6 | gcc -Wall -std=c99 -o main main.c 7 | gcc -Wall -std=c99 -o exec exec.c 8 | ./main ignore exec 9 | ./main pending exec 10 | ./main mask exec 11 | ./main handler exec 12 | 13 | normal: 14 | gcc -Wall -std=c99 -o main main.c 15 | ./main ignore n 16 | ./main pending n 17 | ./main mask n 18 | ./main handler n 19 | 20 | clean: 21 | rm -rf main exec -------------------------------------------------------------------------------- /lab6/zad1/message.h: -------------------------------------------------------------------------------- 1 | #ifndef MESSAGE_H 2 | #define MESSAGE_H 3 | 4 | #define MESSAGE_BUFFER_SIZE 1024 5 | 6 | typedef struct message_t 7 | { 8 | long type; 9 | time_t timestamp; 10 | int id; 11 | char text[MESSAGE_BUFFER_SIZE]; 12 | int pid; 13 | } message_t; 14 | 15 | #define MAX_MESSAGE_SIZE sizeof(message_t) - sizeof(long) 16 | #define ALL_MESSAGE_SIZE sizeof(message_t) 17 | #define MAX_MESSAGES 10 18 | 19 | #endif -------------------------------------------------------------------------------- /lab1/zad1/library.h: -------------------------------------------------------------------------------- 1 | #ifndef LAB1_LIBRARY_H 2 | #define LAB1_LIBRARY_H 3 | #pragma once 4 | 5 | int create_table(unsigned int size); 6 | void define_pair_sequence(char *sequence); 7 | void compare_pairs(); 8 | int get_operations_count(int idx); 9 | int tmp_to_array(); 10 | int delete_block(int idx); 11 | void delete_array(); 12 | void remove_operation(int block_idx, int operation_idx); 13 | char *get_block(int idx); 14 | 15 | #endif //LAB1_LIBRARY_H -------------------------------------------------------------------------------- /lab1/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 | make clean 11 | 12 | shared: 13 | $(CC) -fPIC $(FLAGS) -c library.c -o $(LIB_NAME).o 14 | $(CC) -fPIC $(FLAGS) -shared -o $(LIB_NAME).so $(LIB_NAME).o 15 | make clean 16 | 17 | clean: 18 | rm -f *.o 19 | 20 | clean_all: 21 | rm main tmp.txt $(LIB_NAME).a $(LIB_NAME).so 22 | -------------------------------------------------------------------------------- /lab1_v2/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -Wall 3 | LIB_NAME = lib_diff 4 | SOURCE_NAME = lib_diff 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 | make clean 11 | 12 | shared: 13 | $(CC) -fPIC $(FLAGS) -c $(SOURCE_NAME).c -o $(LIB_NAME).o 14 | $(CC) -fPIC $(FLAGS) -shared -o $(LIB_NAME).so $(LIB_NAME).o 15 | make clean 16 | 17 | clean: 18 | rm -f *.o 19 | 20 | clean_all: 21 | rm main tmp.txt $(LIB_NAME).a $(LIB_NAME).so -------------------------------------------------------------------------------- /lab2/zad2/readme.md: -------------------------------------------------------------------------------- 1 | ## FIND 2 | 3 | ## How to use? 4 | 5 | void print_files_handler(char *root_path, char *comm, char mode, int count, int maxdep); 6 | 7 | * root_path - path to directory 8 | * comm - "maxdepth" or "atime" or "mtime" 9 | * mode - "-" or "+" or "=" 10 | * count - number after mode 11 | * maxdep - maxdepth (-1 - if you don't want) 12 | 13 | ## Examples 14 | 15 | ```c 16 | print_files_handler("../../", "mtime", '+', 3, 2); 17 | ``` 18 | 19 | The command is similar to: 20 | 21 | ```bash 22 | find -maxdepth 2 -mtime +3 23 | ``` -------------------------------------------------------------------------------- /lab10/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -Wall -Wextra -pedantic -Werror -std=c11 -g -pthread 3 | 4 | all: 5 | make clean 6 | make server 7 | make client 8 | ./server 6666 socket 9 | 10 | client: 11 | $(CC) $(CFLAGS) -o client client.c 12 | 13 | server: 14 | $(CC) $(CFLAGS) -o server server.c 15 | 16 | 17 | client1: 18 | ./client Mateusz local socket 19 | 20 | client2: 21 | ./client Tomek local socket 22 | 23 | client1_host: 24 | ./client Mateusz xxx 6666 25 | 26 | client2_host: 27 | ./client Tomek xxx 6666 28 | 29 | clean: 30 | rm -f $(obj) client server socket -------------------------------------------------------------------------------- /lab10/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -Wall -Wextra -pedantic -Werror -std=c11 -g -pthread 3 | 4 | all: 5 | make clean 6 | make server 7 | make client 8 | ./server 6666 socket 9 | 10 | client: 11 | $(CC) $(CFLAGS) -o client client.c 12 | 13 | server: 14 | $(CC) $(CFLAGS) -o server server.c 15 | 16 | 17 | client1: 18 | ./client Mateusz local socket 19 | 20 | client2: 21 | ./client Tomek local socket 22 | 23 | client1_host: 24 | ./client Mateusz xxx 6666 25 | 26 | client2_host: 27 | ./client Tomek xxx 6666 28 | 29 | clean: 30 | rm -f $(obj) client server socket -------------------------------------------------------------------------------- /lab4/zad2/exec.c: -------------------------------------------------------------------------------- 1 | #define _POSIX_C_SOURCE 1 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int main(int argc, char **argv) 10 | { 11 | if (strcmp(argv[1], "pending") != 0) 12 | { 13 | raise(SIGUSR1); 14 | } 15 | if (strcmp(argv[1], "mask") == 0 || strcmp(argv[1], "pending") == 0) 16 | { 17 | sigset_t newmask; 18 | sigpending(&newmask); 19 | printf("Signal pending: %d\n", sigismember(&newmask, SIGUSR1)); 20 | } 21 | return 0; 22 | } -------------------------------------------------------------------------------- /lab1/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: 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 | clean: 22 | rm -rf main tmp.txt raport2.txt -------------------------------------------------------------------------------- /lab6/zad1/keygen.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | 3 | #include "keygen.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | key_t get_public_key() 11 | { 12 | key_t key; 13 | if ((key = ftok(getenv("HOME"), 1)) == -1) 14 | { 15 | perror("Can't generate public key"); 16 | } 17 | return key; 18 | } 19 | 20 | key_t get_private_key() 21 | { 22 | key_t key; 23 | if ((key = ftok(getenv("HOME"), getpid())) == -1) 24 | { 25 | perror("Can't generate private key"); 26 | } 27 | return key; 28 | } -------------------------------------------------------------------------------- /lab1_v2/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: 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 | clean: 22 | rm -rf main tmp.txt raport2.txt -------------------------------------------------------------------------------- /lab3/zad2/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc -Wall -std=c11 -ggdb 2 | 3 | all: 4 | make test 5 | 6 | clean: 7 | rm -f -r .tmp files help matrix lista 8 | 9 | helper: 10 | rm -f help 11 | $(CC) help.c -o help 12 | 13 | test: 14 | make clean 15 | $(CC) help.c -o help 16 | $(CC) matrix.c -o matrix 17 | ./help create 7 14 5 18 | ./matrix lista 6 3 1 19 | ./help check lista 20 | 21 | paste: 22 | make clean 23 | $(CC) help.c -o help 24 | $(CC) matrix.c -o matrix 25 | ./help create 7 14 5 26 | ./matrix lista 6 3 2 27 | 28 | flock: 29 | make clean 30 | $(CC) help.c -o help 31 | $(CC) matrix.c -o matrix 32 | ./help create 7 14 5 33 | ./matrix lista 6 3 1 34 | -------------------------------------------------------------------------------- /lab5/zad2/sort.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | if (argc != 2) 15 | { 16 | fprintf(stderr, "wrong arguments, usage: [file]\n"); 17 | exit(1); 18 | } 19 | char *file_path = argv[1]; 20 | 21 | char line[200]; 22 | sprintf(line, "cat %s | sort", file_path); 23 | FILE *popen_file = popen(line, "w"); 24 | pclose(popen_file); 25 | 26 | return 0; 27 | } -------------------------------------------------------------------------------- /lab2/zad1/generator.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERATOR_LIB_H 2 | #define GENERATOR_LIB_H 3 | 4 | void generate(const char *file_name, const unsigned int num_records, const unsigned int byte_num); 5 | 6 | void copy_lib(const char *file_from, const char *file_to, const unsigned int num_records, const unsigned int byte_num); 7 | 8 | void copy_sys(const char *file_from, const char *file_to, const unsigned int num_records, const unsigned int byte_num); 9 | 10 | void sort_sys(const char *file_name, const unsigned int num_records, const unsigned int byte_num); 11 | 12 | void sort_lib(const char *file_name, const unsigned int num_records, const unsigned int byte_num); 13 | 14 | #endif -------------------------------------------------------------------------------- /lab7/zad1/shared.c: -------------------------------------------------------------------------------- 1 | #include "shared.h" 2 | 3 | int get_semaphore() 4 | { 5 | key_t sem_key = ftok(getenv("HOME"), 0); 6 | int semaphore_id = semget(sem_key, 0, 0); 7 | if (semaphore_id < 0) 8 | { 9 | printf("Can't get semaphore %d\n", errno); 10 | exit(EXIT_FAILURE); 11 | } 12 | return semaphore_id; 13 | } 14 | 15 | int get_shared_memory() 16 | { 17 | key_t shm_key = ftok(getenv("HOME"), 1); 18 | int shared_memory_id = shmget(shm_key, 0, 0); 19 | if (shared_memory_id < 0) 20 | { 21 | printf("Can't access shared memory %d\n", errno); 22 | exit(EXIT_FAILURE); 23 | } 24 | return shared_memory_id; 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /lab1_v2/zad1/txt/ 2 | /lab1_v2/zad1/lib_diff 3 | /lab1_v2/zad1/lib_diff.a 4 | /lab1_v2/zad1/lib_diff.so 5 | 6 | /lab1_v2/zad1/tmp.txt 7 | /lab1_v2/zad2/txt/ 8 | /lab1_v2/zad2/lib_diff 9 | /lab1_v2/zad2/lib_diff.a 10 | /lab1_v2/zad2/lib_diff.so 11 | /lab1_v2/zad3a/txt/ 12 | /lab1_v2/zad3b/txt/ 13 | /lab1_v2/zad2/tmp.txt 14 | /lab1_v2/zad2/main 15 | 16 | main 17 | tmp.txt 18 | 19 | tmp2.txt 20 | original.txt 21 | 22 | /lab2/zad1/*.txt 23 | /lab2/zad2/*.txt 24 | /lab2/zad2/find_ex.c 25 | /lab2/zad1/*.a 26 | !/lab2/zad1/wyniki.txt 27 | /lab2/zad1/generator_prog 28 | 29 | .vscode 30 | 31 | /lab2/zad2/test/ 32 | /lab3/*/*.txt 33 | /lab3/zad2/A 34 | /lab3/zad2/B 35 | /lab3/zad2/C 36 | /lab3/pr 37 | /lab3/zad2_delete 38 | -------------------------------------------------------------------------------- /lab6/zad1/que.h: -------------------------------------------------------------------------------- 1 | #ifndef QUE_H 2 | #define QUE_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "message.h" 14 | 15 | int send(int queue, message_t *message); 16 | 17 | int receive(int queue, message_t *message); 18 | 19 | int create_queue(int key); 20 | 21 | int delete_queue(int queue, int key); 22 | 23 | int get_queue(int key); 24 | 25 | int close_queue(int queue); 26 | 27 | int is_empty(int queueId); 28 | 29 | int receive_no_wait(int queue, message_t *message); 30 | 31 | #define SOMETHING_HAPPEND SIGRTMIN 32 | 33 | #endif -------------------------------------------------------------------------------- /lab1/zad1/main.c: -------------------------------------------------------------------------------- 1 | #include "library.h" 2 | #include 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | create_table(20); 9 | 10 | define_pair_sequence("a.txt b.txt c.txt d.txt e.txt f.txt"); 11 | 12 | compare_pairs(); 13 | compare_pairs(); 14 | compare_pairs(); 15 | compare_pairs(); 16 | compare_pairs(); 17 | 18 | // remove_operation(25, 0); 19 | // remove_operation(26, 0); 20 | remove_operation(12, 1); 21 | delete_block(14); 22 | // compare_pairs(); 23 | 24 | for (int i = 0; i < 20; ++i) 25 | { 26 | int idx = i; 27 | printf("idx: %d\n", idx); 28 | printf("block: %s\n\n", get_block(idx)); 29 | delete_block(idx); 30 | } 31 | return 0; 32 | } -------------------------------------------------------------------------------- /lab7/zad1/shared.h: -------------------------------------------------------------------------------- 1 | #ifndef SHARED_H 2 | #define SHARED_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 | #define MAX_ORDERS 5 16 | #define min_sleep 100 17 | #define max_sleep 1000 18 | #define MIN_VAL 1 19 | #define MAX_VAL 100 20 | typedef struct 21 | { 22 | int values[MAX_ORDERS]; 23 | } orders; 24 | 25 | #define rand_int (rand() % (MAX_VAL - MIN_VAL + 1) + MIN_VAL) 26 | 27 | #define rand_time ((rand() % (max_sleep - min_sleep + 1) + min_sleep) * 1000) 28 | 29 | int get_semaphore(); 30 | int get_shared_memory(); 31 | 32 | #endif //SHARED_H -------------------------------------------------------------------------------- /lab1_v2/zad1/lib_diff.h: -------------------------------------------------------------------------------- 1 | #ifndef LAB1_LIBRARY_H 2 | #define LAB1_LIBRARY_H 3 | #pragma once 4 | #include 5 | #include 6 | typedef struct 7 | { 8 | char *content; 9 | } Operation; 10 | 11 | typedef struct 12 | { 13 | int count; 14 | Operation **operations; 15 | } Operations; 16 | 17 | typedef struct 18 | { 19 | int size; 20 | Operations **block_array; 21 | } Diff_handler; 22 | 23 | int create_table(unsigned int size); 24 | void define_pair_sequence(char *files); 25 | void compare_pairs(); 26 | int get_operations_count(int idx); 27 | int tmp_to_array(); 28 | void delete_block(int idx); 29 | void delete_array(); 30 | void remove_operation(int block_idx, int operation_idx); 31 | char *get_operation(int block_idx, int operation_idx); 32 | 33 | #endif //LAB1_LIBRARY_H -------------------------------------------------------------------------------- /lab1/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: 16 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -I$(LIB_PATH) -ldl -D DYNAMIC 17 | 18 | test: 19 | LD_LIBRARY_PATH=$(LIB_PATH) ./main $(shell cat args.txt) 20 | 21 | test_all: 22 | printf "static:\n" > raport.txt 23 | make static 24 | make test 25 | printf "shared:\n" >> raport.txt 26 | make shared 27 | make test 28 | printf "dynamic:\n" >> raport.txt 29 | make dynamic 30 | make test 31 | mv raport.txt $(REPORT_FILE) -------------------------------------------------------------------------------- /lab1_v2/zad3a/makefile: -------------------------------------------------------------------------------- 1 | 2 | CC = gcc 3 | FLAGS = -std=c99 -Wall 4 | LIB_NAME = lib_diff 5 | LIB_PATH = ../zad1 6 | TEST_PATH = ../zad2 7 | TEST_SOURCE_NAME = main.c 8 | REPORT_FILE = raport3a.txt 9 | 10 | static: 11 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -I$(LIB_PATH) $(LIB_PATH)/$(LIB_NAME).a 12 | 13 | shared: 14 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -I$(LIB_PATH) -L$(LIB_PATH) -l_diff 15 | 16 | dynamic: 17 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -I$(LIB_PATH) -ldl -D DYNAMIC 18 | 19 | test: 20 | LD_LIBRARY_PATH=$(LIB_PATH) ./main $(shell cat args.txt) 21 | 22 | test_all: 23 | printf "static:\n" > raport.txt 24 | make static 25 | make test 26 | printf "shared:\n" >> raport.txt 27 | make shared 28 | make test 29 | printf "dynamic:\n" >> raport.txt 30 | make dynamic 31 | make test 32 | mv raport.txt $(REPORT_FILE) -------------------------------------------------------------------------------- /lab8/zad1/makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | make clean 4 | gcc -o main main.c -lpthread -lm 5 | make test_sign 6 | make test_block 7 | make test_interleaved 8 | 9 | test_sign: 10 | ./main 1 sign mona_lisa.ascii.pgm output.txt 11 | ./main 2 sign mona_lisa.ascii.pgm output.txt 12 | ./main 4 sign mona_lisa.ascii.pgm output.txt 13 | ./main 8 sign mona_lisa.ascii.pgm output.txt 14 | 15 | test_block: 16 | ./main 1 block mona_lisa.ascii.pgm output.txt 17 | ./main 2 block mona_lisa.ascii.pgm output.txt 18 | ./main 4 block mona_lisa.ascii.pgm output.txt 19 | ./main 8 block mona_lisa.ascii.pgm output.txt 20 | test_interleaved: 21 | ./main 1 interleaved mona_lisa.ascii.pgm output.txt 22 | ./main 2 interleaved mona_lisa.ascii.pgm output.txt 23 | ./main 4 interleaved mona_lisa.ascii.pgm output.txt 24 | ./main 8 interleaved mona_lisa.ascii.pgm output.txt 25 | clean: 26 | rm -f main output.txt Times.txt -------------------------------------------------------------------------------- /lab7/zad2/shared.h: -------------------------------------------------------------------------------- 1 | #ifndef SHARED_H 2 | #define SHARED_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 | #define MAX_ORDERS 5 16 | #define min_sleep 100 17 | #define max_sleep 1000 18 | #define MIN_VAL 1 19 | #define MAX_VAL 100 20 | #define SHARED_MEMORY "/SHARED_MEMORY" 21 | int shared_memory_descriptor; 22 | const char *SEMAPHORES[6] = {"/TOGGLER", "/INDEX", "/ORDER_INDEX", "/ORDERS_TO_PREPARE", "/SEND_INDEX", "/ORDERS_TO_SEND"}; 23 | sem_t *semaphores[6]; 24 | typedef struct 25 | { 26 | int values[MAX_ORDERS]; 27 | } orders; 28 | 29 | #define rand_int (rand() % (MAX_VAL - MIN_VAL + 1) + MIN_VAL) 30 | 31 | #define rand_time ((rand() % (max_sleep - min_sleep + 1) + min_sleep) * 1000) 32 | 33 | #endif //SHARED_H -------------------------------------------------------------------------------- /lab4/zad1/main.c: -------------------------------------------------------------------------------- 1 | #define _POSIX_C_SOURCE 1 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int stop = 0; 8 | 9 | void handle_sigint(int sig_no) 10 | { 11 | printf("Otrzyno sygnal SIGINT.\n"); 12 | exit(0); 13 | } 14 | 15 | void handle_sigtstp(int sig_no) 16 | { 17 | if (stop) 18 | { 19 | stop = 0; 20 | return; 21 | } 22 | 23 | printf("Oczekuję na CTRL+Z - kontynuacja albo CTR+C - zakończenie programu. \n"); 24 | stop = 1; 25 | } 26 | 27 | int main() 28 | { 29 | signal(SIGINT, handle_sigint); 30 | struct sigaction act; 31 | act.sa_handler = handle_sigtstp; 32 | sigemptyset(&act.sa_mask); 33 | act.sa_flags = 0; 34 | sigaction(SIGTSTP, &act, NULL); 35 | 36 | while (1) 37 | { 38 | 39 | if (!stop) 40 | { 41 | system("ls -la"); 42 | sleep(1); 43 | } 44 | else 45 | { 46 | pause(); 47 | } 48 | } 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /lab6/zad1/que.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "message.h" 9 | #include "types.h" 10 | 11 | int send(int queue, message_t *message) 12 | { 13 | return msgsnd(queue, message, MAX_MESSAGE_SIZE, 0); 14 | } 15 | 16 | int receive(int queue, message_t *message) 17 | { 18 | return msgrcv(queue, message, MAX_MESSAGE_SIZE, -100, 0); 19 | } 20 | int receive_no_wait(int queue, message_t *message) 21 | { 22 | return msgrcv(queue, message, MAX_MESSAGE_SIZE, -100, IPC_NOWAIT); 23 | } 24 | 25 | int create_queue(int key) 26 | { 27 | return msgget(key, IPC_CREAT | IPC_EXCL | 0600); 28 | } 29 | 30 | int delete_queue(int queue, int key) 31 | { 32 | return msgctl(queue, IPC_RMID, NULL); 33 | } 34 | 35 | int get_queue(int key) 36 | { 37 | return msgget(key, 0); 38 | } 39 | 40 | int close_queue(int queue) 41 | { 42 | return 0; 43 | } 44 | 45 | int is_empty(int queueId) 46 | { 47 | struct msqid_ds buf; 48 | msgctl(queueId, IPC_STAT, &buf); 49 | 50 | return buf.msg_qnum == 0; 51 | } -------------------------------------------------------------------------------- /lab5/zad3/consumer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | if (argc != 4) 13 | { 14 | fprintf(stderr, "Wrong arguments: [pipe_path] [file_path] [character count]"); 15 | exit(1); 16 | } 17 | char *pipe_path = argv[1]; 18 | char *file_path = argv[2]; 19 | int N = atoi(argv[3]); 20 | FILE *write_file = fopen(file_path, "w"); 21 | if (write_file == NULL) 22 | { 23 | fprintf(stderr, "Can't open or read file: %s", file_path); 24 | exit(1); 25 | } 26 | FILE *pipe_file = fopen(pipe_path, "r"); 27 | if (pipe_file == NULL) 28 | { 29 | fprintf(stderr, "Can't open or read file: %s", pipe_path); 30 | exit(1); 31 | } 32 | char buffer[N]; 33 | while (fgets(buffer, N, pipe_file) != NULL) 34 | { 35 | fprintf(write_file, buffer, strlen(buffer)); 36 | } 37 | fclose(pipe_file); 38 | fclose(write_file); 39 | return 0; 40 | } -------------------------------------------------------------------------------- /lab2/zad1/makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | FLAGS = -std=c99 -Wall 3 | SOURCE_NAME = generator 4 | GEN_PROG_NAME = generator_prog 5 | 6 | static: 7 | $(CC) $(FLAGS) -c $(SOURCE_NAME).c -o lib$(SOURCE_NAME).o 8 | ar rcs lib$(SOURCE_NAME).a lib$(SOURCE_NAME).o 9 | make clean 10 | 11 | prog: 12 | make static 13 | $(CC) $(FLAGS) $(GEN_PROG_NAME).c -o $(GEN_PROG_NAME) lib$(SOURCE_NAME).a 14 | 15 | test: 16 | make prog 17 | rm -f wyniki.txt 18 | 19 | for byte_num in 1 4 512 1024 4096 8192 ; do \ 20 | for rec_num in 1000 5000 10000; do \ 21 | ./$(GEN_PROG_NAME) generate dane $$rec_num $$byte_num ; \ 22 | ./$(GEN_PROG_NAME) copy dane dane.$$rec_num.$$byte_num.lib $$rec_num $$byte_num lib ; \ 23 | ./$(GEN_PROG_NAME) copy dane dane.$$rec_num.$$byte_num.sys $$rec_num $$byte_num sys ; \ 24 | done; \ 25 | done 26 | 27 | for byte_num in 1 4 512 1024 4096 8192 ; do \ 28 | for rec_num in 1000 5000 10000; do \ 29 | ./$(GEN_PROG_NAME) sort dane.$$rec_num.$$byte_num.lib $$rec_num $$byte_num lib ; \ 30 | ./$(GEN_PROG_NAME) sort dane.$$rec_num.$$byte_num.sys $$rec_num $$byte_num sys ; \ 31 | done; \ 32 | done 33 | 34 | rm -rf dane* 35 | 36 | 37 | clean: 38 | rm -f *.o -------------------------------------------------------------------------------- /lab1/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 -$O -I$(LIB_PATH) $(LIB_PATH)/$(LIB_NAME).a 12 | 13 | shared: 14 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -$O -I$(LIB_PATH) -L$(LIB_PATH) -l_diff 15 | 16 | dynamic: 17 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -$O -I$(LIB_PATH) -ldl -D DYNAMIC 18 | 19 | test: 20 | LD_LIBRARY_PATH=$(LIB_PATH) ./main $(shell cat args.txt) 21 | 22 | test_all: 23 | rm -f $(REPORT_FILE) 24 | rm -f raport.txt 25 | 26 | printf "static O1:\n" > raport.txt 27 | make static O=O1 28 | make test 29 | printf "static O2:\n" >> raport.txt 30 | make static O=O2 31 | make test 32 | printf "static: O3\n" >> raport.txt 33 | make static O=O3 34 | make test 35 | printf "static: Ofast\n" >> raport.txt 36 | make static O=Ofast 37 | make test 38 | printf "static: Os\n" >> raport.txt 39 | make static O=Os 40 | make test 41 | printf "static: O0\n" >> raport.txt 42 | make static O=O0 43 | make test 44 | mv raport.txt $(REPORT_FILE) -------------------------------------------------------------------------------- /lab1_v2/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 -$O -I$(LIB_PATH) $(LIB_PATH)/$(LIB_NAME).a 12 | 13 | shared: 14 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -$O -I$(LIB_PATH) -L$(LIB_PATH) -l_diff 15 | 16 | dynamic: 17 | $(CC) $(FLAGS) $(TEST_PATH)/$(TEST_SOURCE_NAME) -o main -$O -I$(LIB_PATH) -ldl -D DYNAMIC 18 | 19 | test: 20 | LD_LIBRARY_PATH=$(LIB_PATH) ./main $(shell cat args.txt) 21 | 22 | test_all: 23 | rm -f $(REPORT_FILE) 24 | rm -f raport.txt 25 | 26 | printf "static O1:\n" > raport.txt 27 | make static O=O1 28 | make test 29 | printf "static O2:\n" >> raport.txt 30 | make static O=O2 31 | make test 32 | printf "static: O3\n" >> raport.txt 33 | make static O=O3 34 | make test 35 | printf "static: Ofast\n" >> raport.txt 36 | make static O=Ofast 37 | make test 38 | printf "static: Os\n" >> raport.txt 39 | make static O=Os 40 | make test 41 | printf "static: O0\n" >> raport.txt 42 | make static O=O0 43 | make test 44 | mv raport.txt $(REPORT_FILE) -------------------------------------------------------------------------------- /lab5/zad3/producer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | 13 | if (argc != 4) 14 | { 15 | fprintf(stderr, "Wrong arguments: [pipe_path] [file_path] [character count]"); 16 | exit(1); 17 | } 18 | char *pipe_path = argv[1]; 19 | char *file_path = argv[2]; 20 | int N = atoi(argv[3]); 21 | 22 | FILE *read_file = fopen(file_path, "r"); 23 | if (read_file == NULL) 24 | { 25 | fprintf(stderr, "Can't open or read file: %s", file_path); 26 | exit(1); 27 | } 28 | int pipe_file = open(pipe_path, O_WRONLY); 29 | if (pipe_file < 0) 30 | { 31 | fprintf(stderr, "Can't open file: %d", pipe_file); 32 | exit(1); 33 | } 34 | char buffer[N]; 35 | srand(time(NULL)); 36 | 37 | while (fgets(buffer, N, read_file) != NULL) 38 | { 39 | char message[N + 20]; 40 | sprintf(message, "#%d#%s\n", getpid(), buffer); 41 | write(pipe_file, message, strlen(message)); 42 | sleep(rand() % 2); 43 | } 44 | close(pipe_file); 45 | fclose(read_file); 46 | return 0; 47 | } -------------------------------------------------------------------------------- /lab6/zad1/utils.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "utils.h" 13 | 14 | void split_line(char *line, char *output[], int *output_len) 15 | { 16 | char line_cpy[256]; 17 | strcpy(line_cpy, line); 18 | 19 | char *line_tmp = line_cpy; 20 | char *arg = strtok_r(line_cpy, " ", &line_tmp); 21 | 22 | int arg_cnt = 0; 23 | 24 | while (arg != NULL && arg[0] != EOF) 25 | { 26 | output[arg_cnt++] = strdup(arg); 27 | arg = strtok_r(NULL, " ", &line_tmp); 28 | } 29 | *output_len = arg_cnt; 30 | } 31 | 32 | void separate_command(char *line, char *command, char *rest) 33 | { 34 | char line_cpy[256]; 35 | strcpy(line_cpy, line); 36 | 37 | char *line_tmp = line_cpy; 38 | char *cmd = strtok_r(line_cpy, " \n", &line_tmp); 39 | 40 | char *txt = strtok_r(NULL, "\n", &line_tmp); 41 | if (txt == NULL) 42 | { 43 | rest[0] = '\0'; 44 | } 45 | else 46 | { 47 | strcpy(rest, txt); 48 | } 49 | if (cmd == NULL) 50 | { 51 | command[0] = '\0'; 52 | } 53 | else 54 | { 55 | strcpy(command, cmd); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lab1/zad2/raport2.txt: -------------------------------------------------------------------------------- 1 | Name Real [s] User [s] System [s] Child User [s] Child System [s] 2 | table create 100: 0.000000 0.000000 0.000000 0.000000 0.000000 3 | small diff: 0.010000 0.000000 0.000000 0.000000 0.000000 4 | small remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 5 | small remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 6 | medium diff: 0.010000 0.000000 0.000000 0.010000 0.000000 7 | medium remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 8 | medium remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 9 | big diff: 0.030000 0.000000 0.000000 0.020000 0.000000 10 | big remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 11 | big remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 12 | add remove 7 times: 0.000000 0.000000 0.000000 0.000000 0.000000 13 | -------------------------------------------------------------------------------- /lab5/zad1/popen.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | long get_file_size(FILE *f) 13 | { 14 | fseek(f, 0, SEEK_END); 15 | long file_size = ftell(f); 16 | fseek(f, 0, SEEK_SET); 17 | return file_size; 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | if (argc != 2) 23 | { 24 | fprintf(stderr, "wrong arguments, usage: [file]\n"); 25 | exit(1); 26 | } 27 | char *file_path = argv[1]; 28 | FILE *f = fopen(file_path, "r"); 29 | if (f == NULL) 30 | { 31 | fprintf(stderr, "can't find or open file %s\n", file_path); 32 | exit(1); 33 | } 34 | long file_size = get_file_size(f); 35 | char *buffer = malloc(file_size + 1); 36 | if (fread(buffer, 1, file_size, f) != file_size) 37 | { 38 | fprintf(stderr, "cant read from file %s\n", file_path); 39 | exit(1); 40 | } 41 | fclose(f); 42 | char *lines_tmp = buffer; 43 | char *line = strtok_r(buffer, "\n", &lines_tmp); 44 | while (line != NULL) 45 | { 46 | FILE *popen_file = popen(line, "w"); 47 | pclose(popen_file); 48 | line = strtok_r(NULL, "\n", &lines_tmp); 49 | } 50 | free(buffer); 51 | return 0; 52 | } -------------------------------------------------------------------------------- /lab3/zad1/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void search_dir(char *path) 10 | { 11 | if (!path) 12 | return; 13 | DIR *directory = opendir(path); 14 | if (!directory) 15 | return; 16 | struct dirent *d; 17 | struct stat st; 18 | 19 | while ((d = readdir(directory))) 20 | { 21 | if (strcmp(d->d_name, "..") == 0) 22 | continue; 23 | if (strcmp(d->d_name, ".") == 0) 24 | continue; 25 | char *dir = malloc(sizeof(char) * (strlen(path) + strlen(d->d_name)) + 2); 26 | sprintf(dir, "%s/%s", path, d->d_name); 27 | if (lstat(dir, &st) < 0) 28 | continue; 29 | if (S_ISDIR(st.st_mode) && fork() == 0) 30 | { 31 | printf("\npid(%i) path(%s)\n", getpid(), dir); 32 | static const char cmd[] = "ls -la %s"; 33 | char *ls = calloc(sizeof(cmd), sizeof(char)); 34 | sprintf(ls, cmd, dir); 35 | system(ls); 36 | free(ls); 37 | exit(0); 38 | } 39 | else 40 | wait(NULL); 41 | free(dir); 42 | } 43 | closedir(directory); 44 | } 45 | 46 | int main(int argc, char **argv) 47 | { 48 | char *path = argc > 1 ? argv[1] : "."; 49 | search_dir(path); 50 | return 0; 51 | } -------------------------------------------------------------------------------- /lab1/zad2/args.txt: -------------------------------------------------------------------------------- 1 | start create_table 100 end "table create 100" 2 | start compare_pairs "a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt" end "small diff" 3 | start remove_block 0 end "small remove from array" 4 | start remove_operation 2 0 end "small remove operation from array" 5 | start compare_pairs "a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt big.txt big2.txt" end "medium diff" 6 | start remove_operation 6 0 end "medium remove operation from array" 7 | start remove_block 6 end "medium remove from array" 8 | start compare_pairs "a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt big.txt big2.txt f.txt 9 | h.txt 10 | c.txt 11 | d.txt 12 | e.txt 13 | big2.txt 14 | a.txt 15 | b.txt 16 | big.txt 17 | g.txt h.txt 18 | f.txt 19 | big2.txt 20 | e.txt 21 | g.txt 22 | c.txt 23 | b.txt 24 | d.txt 25 | a.txt 26 | big.txt d.txt 27 | h.txt 28 | e.txt 29 | big.txt 30 | a.txt 31 | big2.txt 32 | b.txt 33 | c.txt 34 | g.txt 35 | f.txt a.txt 36 | d.txt 37 | h.txt 38 | big2.txt 39 | e.txt 40 | f.txt 41 | g.txt 42 | big.txt 43 | c.txt 44 | b.txt big.txt big2.txt" end "big diff" 45 | start remove_operation 42 0 end "big remove operation from array" 46 | start remove_block 50 end "big remove from array" 47 | start tmp_to_array remove_block 0 48 | tmp_to_array remove_block 0 49 | tmp_to_array remove_block 0 50 | tmp_to_array remove_block 0 51 | tmp_to_array remove_block 0 52 | tmp_to_array remove_block 0 53 | tmp_to_array remove_block 0 54 | end "add remove 7 times" -------------------------------------------------------------------------------- /lab1/zad3a/args.txt: -------------------------------------------------------------------------------- 1 | start create_table 100 end "table create 100" 2 | start compare_pairs "a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt" end "small diff" 3 | start remove_block 0 end "small remove from array" 4 | start remove_operation 2 0 end "small remove operation from array" 5 | start compare_pairs "a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt big.txt big2.txt" end "medium diff" 6 | start remove_operation 6 0 end "medium remove operation from array" 7 | start remove_block 6 end "medium remove from array" 8 | start compare_pairs "a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt big.txt big2.txt f.txt 9 | h.txt 10 | c.txt 11 | d.txt 12 | e.txt 13 | big2.txt 14 | a.txt 15 | b.txt 16 | big.txt 17 | g.txt h.txt 18 | f.txt 19 | big2.txt 20 | e.txt 21 | g.txt 22 | c.txt 23 | b.txt 24 | d.txt 25 | a.txt 26 | big.txt d.txt 27 | h.txt 28 | e.txt 29 | big.txt 30 | a.txt 31 | big2.txt 32 | b.txt 33 | c.txt 34 | g.txt 35 | f.txt a.txt 36 | d.txt 37 | h.txt 38 | big2.txt 39 | e.txt 40 | f.txt 41 | g.txt 42 | big.txt 43 | c.txt 44 | b.txt big.txt big2.txt" end "big diff" 45 | start remove_operation 42 0 end "big remove operation from array" 46 | start remove_block 50 end "big remove from array" 47 | start tmp_to_array remove_block 0 48 | tmp_to_array remove_block 0 49 | tmp_to_array remove_block 0 50 | tmp_to_array remove_block 0 51 | tmp_to_array remove_block 0 52 | tmp_to_array remove_block 0 53 | tmp_to_array remove_block 0 54 | end "add remove 7 times" -------------------------------------------------------------------------------- /lab1/zad3b/args.txt: -------------------------------------------------------------------------------- 1 | start create_table 100 end "table create 100" 2 | start compare_pairs "a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt" end "small diff" 3 | start remove_block 0 end "small remove from array" 4 | start remove_operation 2 0 end "small remove operation from array" 5 | start compare_pairs "a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt big.txt big2.txt" end "medium diff" 6 | start remove_operation 6 0 end "medium remove operation from array" 7 | start remove_block 6 end "medium remove from array" 8 | start compare_pairs "a.txt b.txt c.txt d.txt e.txt f.txt g.txt h.txt big.txt big2.txt f.txt 9 | h.txt 10 | c.txt 11 | d.txt 12 | e.txt 13 | big2.txt 14 | a.txt 15 | b.txt 16 | big.txt 17 | g.txt h.txt 18 | f.txt 19 | big2.txt 20 | e.txt 21 | g.txt 22 | c.txt 23 | b.txt 24 | d.txt 25 | a.txt 26 | big.txt d.txt 27 | h.txt 28 | e.txt 29 | big.txt 30 | a.txt 31 | big2.txt 32 | b.txt 33 | c.txt 34 | g.txt 35 | f.txt a.txt 36 | d.txt 37 | h.txt 38 | big2.txt 39 | e.txt 40 | f.txt 41 | g.txt 42 | big.txt 43 | c.txt 44 | b.txt big.txt big2.txt" end "big diff" 45 | start remove_operation 42 0 end "big remove operation from array" 46 | start remove_block 50 end "big remove from array" 47 | start tmp_to_array remove_block 0 48 | tmp_to_array remove_block 0 49 | tmp_to_array remove_block 0 50 | tmp_to_array remove_block 0 51 | tmp_to_array remove_block 0 52 | tmp_to_array remove_block 0 53 | tmp_to_array remove_block 0 54 | end "add remove 7 times" -------------------------------------------------------------------------------- /lab6/zad2/types.h: -------------------------------------------------------------------------------- 1 | #define TYPES_H 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define CLIENT_SERVER_STOP 5 15 | #define CLIENT_SERVER_DISCONNECT 4 16 | #define CLIENT_SERVER_LIST 3 17 | #define CLIENT_SERVER_CONNECT 2 18 | #define CLIENT_SERVER_INIT 1 19 | 20 | #define SERVER_CLIENT_CHAT_INIT 1 21 | #define SERVER_CLIENT_TERMINATE 2 22 | #define SERVER_CLIENT_REGISTRED 3 23 | #define CLIENT_CLIENT_MSG 4 24 | #define CLIENT_CLIENT_DICONNECT 5 25 | 26 | #define MAX_MESSAGE_SIZE 256 27 | 28 | #define PREFIX ("/queues-") 29 | #define SERVER_NAME (concat(PREFIX, "server")) 30 | #define CLIENT_RANDOM_NAME \ 31 | (concat(PREFIX, concat("client-", random_string(12)))) 32 | 33 | void delete_queue(char *name); 34 | void close_queue(mqd_t descr); 35 | int create_queue(char *name); 36 | int get_queue(char *name); 37 | void send_message(mqd_t desc, char *msgPointer, int type); 38 | void receive_message(mqd_t desc, char *msgPointer, int *typePointer); 39 | void register_notification(mqd_t desc, struct sigevent *s); 40 | void printError(); 41 | int equals(char *str1, char *str2); 42 | char *random_string(int length); 43 | char *concat(const char *s1, const char *s2); 44 | 45 | struct Client 46 | { 47 | int id; 48 | int queue; 49 | char *name; 50 | int available; 51 | } typedef Client; -------------------------------------------------------------------------------- /lab5/zad3/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | char *consumer[] = {"./consumer", "fif", "./consumer_data/output", "10", NULL}; 14 | char *producer_1[] = {"./producer", "fif", "./producer_data/a", "5", NULL}; 15 | char *producer_2[] = {"./producer", "fif", "./producer_data/b", "5", NULL}; 16 | char *producer_3[] = {"./producer", "fif", "./producer_data/c", "5", NULL}; 17 | char *producer_4[] = {"./producer", "fif", "./producer_data/e", "5", NULL}; 18 | char *producer_5[] = {"./producer", "fif", "./producer_data/f", "5", NULL}; 19 | 20 | mkfifo("fif", S_IRUSR | S_IWUSR); 21 | 22 | pid_t pid_tab[6]; 23 | if ((pid_tab[0] = fork()) == 0) 24 | execvp(consumer[0], consumer); 25 | 26 | if ((pid_tab[1] = fork()) == 0) 27 | execvp(producer_2[0], producer_2); 28 | 29 | if ((pid_tab[2] = fork()) == 0) 30 | execvp(producer_3[0], producer_3); 31 | 32 | if ((pid_tab[3] = fork()) == 0) 33 | execvp(producer_1[0], producer_1); 34 | 35 | if ((pid_tab[4] = fork()) == 0) 36 | execvp(producer_4[0], producer_4); 37 | 38 | if ((pid_tab[5] = fork()) == 0) 39 | execvp(producer_5[0], producer_5); 40 | for (int i = 0; i < 6; i++) 41 | waitpid(pid_tab[i], NULL, 0); 42 | 43 | printf("Now you can check consumer_data/output file\n"); 44 | return 0; 45 | } -------------------------------------------------------------------------------- /lab1_v2/zad2/raport2.txt: -------------------------------------------------------------------------------- 1 | Name Real [s] User [s] System [s] Child User [s] Child System [s] 2 | table create 100: 0.000000 0.000000 0.000000 0.000000 0.000000 3 | small diff: 0.000000 0.000000 0.000000 0.000000 0.000000 4 | small remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 5 | small remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 6 | medium diff: 0.010000 0.000000 0.000000 0.010000 0.000000 7 | medium remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 8 | medium remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 9 | big diff: 0.050000 0.000000 0.000000 0.040000 0.000000 10 | big remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 11 | big remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 12 | add remove 7 times: 0.000000 0.000000 0.000000 0.000000 0.000000 13 | 14 | Czasy zaobserwowane sa bardzo male dlatego ciezko wyciagnac jakiekolwiek wnbioski, jedynie mozna zauwazyc ze operacja diff 15 | zajmuje "jakikolwiek" czas, mysle ze jest to spowodowane wykonywaniem tej operacji przez system a nie przez samo C -------------------------------------------------------------------------------- /lab6/zad2/types.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | 3 | int equals(char *str1, char *str2) { return strcmp(str1, str2) == 0; } 4 | 5 | char *random_string(int length) 6 | { 7 | char *str = calloc(length + 1, sizeof(char)); 8 | 9 | for (int i = 0; i < length; i++) 10 | { 11 | char randomletter = 'a' + (rand() % 26); 12 | str[i] = randomletter; 13 | } 14 | 15 | str[length] = '\0'; 16 | 17 | return str; 18 | } 19 | 20 | char *concat(const char *s1, const char *s2) 21 | { 22 | int len = strlen(s1) + strlen(s2) + 1; 23 | char *result = (char *)malloc(len); 24 | 25 | strcpy(result, s1); 26 | strcat(result, s2); 27 | 28 | return result; 29 | } 30 | 31 | void printError() 32 | { 33 | if (errno != 0) 34 | { 35 | fprintf(stderr, "Value of errno: %d\n", errno); 36 | perror("Error printed by perror"); 37 | } 38 | } 39 | 40 | void delete_queue(char *name) { mq_unlink(name); } 41 | void close_queue(mqd_t descr) { mq_close(descr); } 42 | int create_queue(char *name) 43 | { 44 | struct mq_attr attr; 45 | attr.mq_flags = 0; 46 | attr.mq_maxmsg = 10; 47 | attr.mq_msgsize = MAX_MESSAGE_SIZE - 1; 48 | attr.mq_curmsgs = 0; 49 | 50 | return mq_open(name, O_RDONLY | O_CREAT | O_EXCL, 0666, &attr); 51 | } 52 | int get_queue(char *name) { return mq_open(name, O_WRONLY); } 53 | 54 | void send_message(mqd_t desc, char *msgPointer, int type) { mq_send(desc, msgPointer, strlen(msgPointer), type); } 55 | 56 | void receive_message(mqd_t desc, char *msgPointer, int *typePointer) { mq_receive(desc, msgPointer, MAX_MESSAGE_SIZE, typePointer); } 57 | 58 | void register_notification(mqd_t desc, struct sigevent *s) { mq_notify(desc, s); } -------------------------------------------------------------------------------- /lab4/zad2/main.c: -------------------------------------------------------------------------------- 1 | #define _POSIX_C_SOURCE 1 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void handler(int sig) 10 | { 11 | printf("Handler - Signal received!\n"); 12 | } 13 | 14 | int main(int argc, char **argv) 15 | { 16 | if (strcmp(argv[1], "mask") == 0 || strcmp(argv[1], "pending") == 0) 17 | { 18 | sigset_t newmask; 19 | sigemptyset(&newmask); 20 | sigaddset(&newmask, SIGUSR1); 21 | if (sigprocmask(SIG_BLOCK, &newmask, NULL) < 0) 22 | perror("Nie udało się zablokować sygnału"); 23 | } 24 | 25 | else if (strcmp(argv[1], "handler") == 0) 26 | { 27 | signal(SIGUSR1, handler); 28 | } 29 | else if (strcmp(argv[1], "ignore") == 0) 30 | { 31 | signal(SIGUSR1, SIG_IGN); 32 | } 33 | raise(SIGUSR1); 34 | sigset_t newmask; 35 | 36 | if (strcmp(argv[1], "mask") == 0 || strcmp(argv[1], "pending") == 0) 37 | { 38 | sigpending(&newmask); 39 | printf("Signal pending: %d\n", sigismember(&newmask, SIGUSR1)); 40 | } 41 | 42 | if (strcmp(argv[2], "exec") == 0) 43 | { 44 | execl("./exec", "./exec", argv[1], NULL); 45 | } 46 | else 47 | { 48 | pid_t child_pid = fork(); 49 | if (child_pid == 0) 50 | { 51 | if (strcmp(argv[1], "pending") != 0) 52 | { 53 | raise(SIGUSR1); 54 | } 55 | if (strcmp(argv[1], "mask") == 0 || strcmp(argv[1], "pending") == 0) 56 | { 57 | sigpending(&newmask); 58 | printf("Signal pending: %d\n", sigismember(&newmask, SIGUSR1)); 59 | } 60 | } 61 | } 62 | return 0; 63 | } -------------------------------------------------------------------------------- /lab1_v2/zad2/args.txt: -------------------------------------------------------------------------------- 1 | start create_table 100 end "table create 100" 2 | start compare_pairs "txt/a.txt:txt/b.txt txt/c.txt:txt/d.txt txt/e.txt:txt/f.txt txt/g.txt:txt/h.txt" end "small diff" 3 | start remove_block 0 end "small remove from array" 4 | start remove_operation 2 0 end "small remove operation from array" 5 | start compare_pairs "txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt 6 | txt/a.txt:txt/b.txt txt/big2.txt:txt/d.txt txt/e.txt:txt/f.txt txt/g.txt:txt/h.txt 7 | txt/a.txt:txt/b.txt txt/c.txt:txt/d.txt txt/big2.txt:txt/big.txt txt/g.txt:txt/h.txt" end "medium diff" 8 | start remove_block 6 end "medium remove from array" 9 | start remove_operation 10 1 end "medium remove operation from array" 10 | start compare_pairs "txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 11 | txt/big2.txt:txt/b.txt txt/c.txt:txt/d.txt txt/big2.txt:txt/big.txt txt/a.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 12 | txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 13 | txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 14 | txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/big.txt:txt/big2.txt " end "big diff" 15 | start remove_block 30 end "big remove from array" 16 | start remove_operation 25 1 end "big remove operation from array" 17 | start tmp_to_array remove_block 0 18 | tmp_to_array remove_block 0 19 | tmp_to_array remove_block 0 20 | tmp_to_array remove_block 0 21 | tmp_to_array remove_block 0 22 | tmp_to_array remove_block 0 23 | tmp_to_array remove_block 0 24 | end "add remove 7 times" -------------------------------------------------------------------------------- /lab1_v2/zad3a/args.txt: -------------------------------------------------------------------------------- 1 | start create_table 100 end "table create 100" 2 | start compare_pairs "txt/a.txt:txt/b.txt txt/c.txt:txt/d.txt txt/e.txt:txt/f.txt txt/g.txt:txt/h.txt" end "small diff" 3 | start remove_block 0 end "small remove from array" 4 | start remove_operation 2 0 end "small remove operation from array" 5 | start compare_pairs "txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt 6 | txt/a.txt:txt/b.txt txt/big2.txt:txt/d.txt txt/e.txt:txt/f.txt txt/g.txt:txt/h.txt 7 | txt/a.txt:txt/b.txt txt/c.txt:txt/d.txt txt/big2.txt:txt/big.txt txt/g.txt:txt/h.txt" end "medium diff" 8 | start remove_block 6 end "medium remove from array" 9 | start remove_operation 10 1 end "medium remove operation from array" 10 | start compare_pairs "txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 11 | txt/big2.txt:txt/b.txt txt/c.txt:txt/d.txt txt/big2.txt:txt/big.txt txt/a.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 12 | txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 13 | txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 14 | txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/big.txt:txt/big2.txt " end "big diff" 15 | start remove_block 30 end "big remove from array" 16 | start remove_operation 25 1 end "big remove operation from array" 17 | start tmp_to_array remove_block 0 18 | tmp_to_array remove_block 0 19 | tmp_to_array remove_block 0 20 | tmp_to_array remove_block 0 21 | tmp_to_array remove_block 0 22 | tmp_to_array remove_block 0 23 | tmp_to_array remove_block 0 24 | end "add remove 7 times" -------------------------------------------------------------------------------- /lab1_v2/zad3b/args.txt: -------------------------------------------------------------------------------- 1 | start create_table 100 end "table create 100" 2 | start compare_pairs "txt/a.txt:txt/b.txt txt/c.txt:txt/d.txt txt/e.txt:txt/f.txt txt/g.txt:txt/h.txt" end "small diff" 3 | start remove_block 0 end "small remove from array" 4 | start remove_operation 2 0 end "small remove operation from array" 5 | start compare_pairs "txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt 6 | txt/a.txt:txt/b.txt txt/big2.txt:txt/d.txt txt/e.txt:txt/f.txt txt/g.txt:txt/h.txt 7 | txt/a.txt:txt/b.txt txt/c.txt:txt/d.txt txt/big2.txt:txt/big.txt txt/g.txt:txt/h.txt" end "medium diff" 8 | start remove_block 6 end "medium remove from array" 9 | start remove_operation 10 1 end "medium remove operation from array" 10 | start compare_pairs "txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 11 | txt/big2.txt:txt/b.txt txt/c.txt:txt/d.txt txt/big2.txt:txt/big.txt txt/a.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 12 | txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 13 | txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/c.txt:txt/big.txt 14 | txt/big2.txt:txt/big.txt txt/c.txt:txt/d.txt txt/e.txt:txt/big.txt txt/g.txt:txt/h.txt txt/a.txt:txt/big2.txt txt/big.txt:txt/big2.txt " end "big diff" 15 | start remove_block 30 end "big remove from array" 16 | start remove_operation 25 1 end "big remove operation from array" 17 | start tmp_to_array remove_block 0 18 | tmp_to_array remove_block 0 19 | tmp_to_array remove_block 0 20 | tmp_to_array remove_block 0 21 | tmp_to_array remove_block 0 22 | tmp_to_array remove_block 0 23 | tmp_to_array remove_block 0 24 | end "add remove 7 times" -------------------------------------------------------------------------------- /lab7/zad1/worker_1.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 "shared.h" 14 | 15 | int semaphore_id; 16 | int shared_memory_id; 17 | 18 | typedef struct sembuf sembuf; 19 | 20 | void add_order() 21 | { 22 | sembuf *load = calloc(3, sizeof(sembuf)); 23 | load[0].sem_num = 0; 24 | load[0].sem_op = 0; 25 | load[0].sem_flg = 0; 26 | 27 | load[1].sem_num = 0; 28 | load[1].sem_op = 1; 29 | load[1].sem_flg = 0; 30 | 31 | load[2].sem_num = 1; 32 | load[2].sem_op = 1; 33 | load[2].sem_flg = 0; 34 | 35 | semop(semaphore_id, load, 3); 36 | 37 | orders *ord = shmat(shared_memory_id, NULL, 0); 38 | int index = (semctl(semaphore_id, 1, GETVAL, NULL) - 1) % MAX_ORDERS; 39 | int value = rand_int; 40 | ord->values[index] = value; 41 | int orders_to_prepare = semctl(semaphore_id, 3, GETVAL, NULL) + 1; 42 | int orders_to_send = semctl(semaphore_id, 5, GETVAL, NULL); 43 | printf("[%d %ld] Dodalem liczbe: %d. Liczba zamowien do przygotowania: %d. Liczba zamowien do wyslania: %d.\n", 44 | getpid(), time(NULL), value, orders_to_prepare, orders_to_send); 45 | 46 | shmdt(ord); 47 | 48 | sembuf *back = calloc(2, sizeof(sembuf)); 49 | 50 | back[0].sem_num = 0; 51 | back[0].sem_op = -1; 52 | back[0].sem_flg = 0; 53 | 54 | back[1].sem_num = 3; 55 | back[1].sem_op = 1; 56 | back[1].sem_flg = 0; 57 | 58 | semop(semaphore_id, back, 2); 59 | } 60 | 61 | int main() 62 | { 63 | srand(time(NULL)); 64 | 65 | semaphore_id = get_semaphore(); 66 | shared_memory_id = get_shared_memory(); 67 | 68 | while (1) 69 | { 70 | usleep(rand_time); 71 | if (semctl(semaphore_id, 3, GETVAL, NULL) + semctl(semaphore_id, 5, GETVAL, NULL) < MAX_ORDERS) 72 | { 73 | add_order(); 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /lab7/zad1/worker_3.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 "shared.h" 14 | 15 | int semaphore_id; 16 | int shared_memory_id; 17 | 18 | typedef struct sembuf sembuf; 19 | 20 | void send_order() 21 | { 22 | sembuf *load = calloc(4, sizeof(sembuf)); 23 | 24 | load[0].sem_num = 0; 25 | load[0].sem_op = 0; 26 | load[0].sem_flg = 0; 27 | 28 | load[1].sem_num = 0; 29 | load[1].sem_op = 1; 30 | load[1].sem_flg = 0; 31 | 32 | load[2].sem_num = 4; 33 | load[2].sem_op = 1; 34 | load[2].sem_flg = 0; 35 | 36 | load[3].sem_num = 5; 37 | load[3].sem_op = -1; 38 | load[3].sem_flg = 0; 39 | 40 | semop(semaphore_id, load, 4); 41 | 42 | orders *ord = shmat(shared_memory_id, NULL, 0); 43 | 44 | int index = (semctl(semaphore_id, 4, GETVAL, NULL) - 1) % MAX_ORDERS; 45 | ord->values[index] *= 3; 46 | int orders_to_prepare = semctl(semaphore_id, 3, GETVAL, NULL); 47 | int orders_to_send = semctl(semaphore_id, 5, GETVAL, NULL); 48 | printf("[%d %ld] Wyslalem zamowienie o wielkosci: %d. Liczba zamowien do przygotowania: %d. Liczba zamowien do wyslania: %d.\n", 49 | getpid(), time(NULL), ord->values[index], orders_to_prepare, orders_to_send); 50 | ord->values[index] = 0; 51 | 52 | shmdt(ord); 53 | sembuf *back = calloc(1, sizeof(sembuf)); 54 | 55 | back[0].sem_num = 0; 56 | back[0].sem_op = -1; 57 | back[0].sem_flg = 0; 58 | 59 | semop(semaphore_id, back, 1); 60 | } 61 | 62 | int main() 63 | { 64 | srand(time(NULL)); 65 | 66 | semaphore_id = get_semaphore(); 67 | shared_memory_id = get_shared_memory(); 68 | 69 | while (1) 70 | { 71 | usleep(rand_time); 72 | if (semctl(semaphore_id, 5, GETVAL, NULL) > 0) 73 | { 74 | send_order(); 75 | } 76 | } 77 | 78 | return 0; 79 | } -------------------------------------------------------------------------------- /lab7/zad1/worker_2.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 "shared.h" 14 | 15 | int semaphore_id; 16 | int shared_memory_id; 17 | 18 | typedef struct sembuf sembuf; 19 | 20 | void pack_order() 21 | { 22 | sembuf *load = calloc(4, sizeof(sembuf)); 23 | 24 | load[0].sem_num = 0; 25 | load[0].sem_op = 0; 26 | load[0].sem_flg = 0; 27 | 28 | load[1].sem_num = 0; 29 | load[1].sem_op = 1; 30 | load[1].sem_flg = 0; 31 | 32 | load[2].sem_num = 2; 33 | load[2].sem_op = 1; 34 | load[2].sem_flg = 0; 35 | 36 | load[3].sem_num = 3; 37 | load[3].sem_op = -1; 38 | load[3].sem_flg = 0; 39 | 40 | semop(semaphore_id, load, 4); 41 | 42 | orders *ord = shmat(shared_memory_id, NULL, 0); 43 | 44 | int index = (semctl(semaphore_id, 2, GETVAL, NULL) - 1) % MAX_ORDERS; 45 | ord->values[index] *= 2; 46 | int orders_to_prepare = semctl(semaphore_id, 3, GETVAL, NULL); 47 | int orders_to_send = semctl(semaphore_id, 5, GETVAL, NULL) + 1; 48 | printf("[%d %ld] Przygotowalem zamowienie o wielkosci: %d. Liczba zamowien do przygotowania: %d. Liczba zamowien do wyslania: %d.\n", 49 | getpid(), time(NULL), ord->values[index], orders_to_prepare, orders_to_send); 50 | 51 | shmdt(ord); 52 | 53 | sembuf *back = calloc(2, sizeof(sembuf)); 54 | 55 | back[0].sem_num = 0; 56 | back[0].sem_op = -1; 57 | back[0].sem_flg = 0; 58 | 59 | back[1].sem_num = 5; 60 | back[1].sem_op = 1; 61 | back[1].sem_flg = 0; 62 | 63 | semop(semaphore_id, back, 2); 64 | } 65 | 66 | int main() 67 | { 68 | srand(time(NULL)); 69 | 70 | semaphore_id = get_semaphore(); 71 | shared_memory_id = get_shared_memory(); 72 | 73 | while (1) 74 | { 75 | usleep(rand_time); 76 | if (semctl(semaphore_id, 3, GETVAL, NULL) > 0) 77 | { 78 | pack_order(); 79 | } 80 | } 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /lab9/README.md: -------------------------------------------------------------------------------- 1 | # Zadania - Zestaw 9 2 | Opis problemu: 3 | W ramach zadania należy zaimplementować rozwiązanie problemu śpiącego golibrody. 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 | Gdy klient wychodzi z salonu z powodu braku miejsca w poczekalni, powinien odczekać losową liczbe sekund i spróbować wejść jeszcze raz. 25 | 26 | 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. -------------------------------------------------------------------------------- /lab10/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 | 6 | Serwer nasłuchuje jednocześnie na gnieździe sieciowym i gnieździe lokalnym. 7 | 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. 8 | 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). 9 | 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. 10 | 11 | Serwer przyjmuje jako swoje argumenty: 12 | 13 | - numer portu TCP/UDP (zależnie od zadania) 14 | - ścieżkę gniazda UNIX 15 | 16 | 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). 17 | 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. 18 | Można przyjąć, że ilość klientów zarejestrowanych na serwerze jest ograniczona do maksymalnie kilkunastu. 19 | 20 | 21 | Klient przyjmuje jako swoje argumenty: 22 | 23 | - swoją nazwę (string o z góry ograniczonej długości) 24 | - sposób połączenia z serwerem (sieć lub komunikacja lokalna przez gniazda UNIX) 25 | - adres serwera (adres IPv4 i numer portu lub ścieżkę do gniazda UNIX serwera) 26 | 27 | Klient przy wyłączeniu Ctrl+C powinien wyrejestrować się z serwera. 28 | 29 | 30 | **Zadanie 1 (50%)** 31 | Komunikacja klientów i serwera odbywa się z użyciem protokołu strumieniowego. 32 | 33 | **Zadanie 2 (50%)** 34 | Komunikacja klientów i serwera odbywa się z użyciem protokołu datagramowego. 35 | -------------------------------------------------------------------------------- /lab1/zad2/diff_dynamic.h: -------------------------------------------------------------------------------- 1 | #ifndef DIFF_DYN_H 2 | #define DIFF_DYN_H 3 | #include 4 | #include 5 | #include 6 | 7 | static void *handle = NULL; 8 | 9 | int (*_create_table)(unsigned int size); 10 | void (*_define_pair_sequence)(char *sequence); 11 | void (*_compare_pairs)(); 12 | int (*_get_operations_count)(int idx); 13 | int (*_tmp_to_array)(); 14 | int (*_delete_block)(int idx); 15 | void (*_delete_array)(); 16 | void (*_remove_operation)(int block_idx, int operation_idx); 17 | char *(*_get_block)(int idx); 18 | 19 | void init_dynamic_library() 20 | { 21 | handle = dlopen("lib_diff.so", RTLD_NOW); 22 | if (handle == NULL) 23 | { 24 | fprintf(stderr, "Error dynamic library open"); 25 | return; 26 | } 27 | 28 | _create_table = dlsym(handle, "create_table"); 29 | _define_pair_sequence = dlsym(handle, "define_pair_sequence"); 30 | _compare_pairs = dlsym(handle, "compare_pairs"); 31 | _get_operations_count = dlsym(handle, "get_operations_count"); 32 | _tmp_to_array = dlsym(handle, "tmp_to_array"); 33 | _delete_block = dlsym(handle, "delete_block"); 34 | _delete_array = dlsym(handle, "delete_array"); 35 | _remove_operation = dlsym(handle, "remove_operation"); 36 | _get_block = dlsym(handle, "get_block"); 37 | 38 | char *error; 39 | if ((error = dlerror()) != NULL) 40 | { 41 | fprintf(stderr, "%s\n", error); 42 | exit(1); 43 | } 44 | } 45 | 46 | int create_table(unsigned int size) 47 | { 48 | return (*_create_table)(size); 49 | } 50 | void define_pair_sequence(char *sequence) 51 | { 52 | return (*_define_pair_sequence)(sequence); 53 | } 54 | void compare_pairs() 55 | { 56 | return (*_compare_pairs)(); 57 | } 58 | int get_operations_count(int idx) 59 | { 60 | return (*_get_operations_count)(idx); 61 | } 62 | int tmp_to_array() 63 | { 64 | return (*_tmp_to_array)(); 65 | } 66 | int delete_block(int idx) 67 | { 68 | return (*_delete_block)(idx); 69 | } 70 | void delete_array() 71 | { 72 | return (*_delete_array)(); 73 | } 74 | void remove_operation(int block_idx, int operation_idx) 75 | { 76 | return (*_remove_operation)(block_idx, operation_idx); 77 | } 78 | char *get_block(int idx) 79 | { 80 | return (*_get_block)(idx); 81 | } 82 | 83 | #endif -------------------------------------------------------------------------------- /lab4/zad3/main.c: -------------------------------------------------------------------------------- 1 | #define _POSIX_C_SOURCE 199309L 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void handler_CHILD(int sig, siginfo_t *info, void *ucontext) 11 | { 12 | printf("Signal number %d\n", info->si_signo); 13 | printf("Sending process ID %d\n", info->si_pid); 14 | printf("Child exit value %d\n", info->si_status); 15 | } 16 | 17 | void handle_SIGINT(int sig, siginfo_t *info, void *ucontext) 18 | { 19 | printf("Signal number %d\n", info->si_signo); 20 | printf("Sending process ID %d\n", info->si_pid); 21 | if (info->si_code == SI_USER) 22 | { 23 | printf("USER\n"); 24 | } 25 | else if (info->si_code == SI_KERNEL) 26 | { 27 | printf("KERNEL\n"); 28 | } 29 | else if (info->si_code == SI_QUEUE) 30 | { 31 | printf("SIGQUEUE\n"); 32 | } 33 | } 34 | void handle_QUEUE(int sig, siginfo_t *info, void *ucontext) 35 | { 36 | printf("Signal number %d\n", info->si_signo); 37 | printf("Sending process ID %d\n", info->si_pid); 38 | printf("Value %d\n", info->si_value.sival_int); 39 | } 40 | 41 | int main(int argc, char **argv) 42 | { 43 | if (argc < 2) 44 | { 45 | printf("./main [child/status/queue]"); 46 | exit(-1); 47 | } 48 | 49 | struct sigaction act; 50 | sigemptyset(&act.sa_mask); 51 | act.sa_flags = SA_SIGINFO; 52 | if (strcmp(argv[1], "child") == 0) 53 | { 54 | act.sa_sigaction = handler_CHILD; 55 | sigaction(SIGCHLD, &act, NULL); 56 | pid_t child_pid = fork(); 57 | 58 | if (child_pid == 0) 59 | { 60 | exit(123); 61 | } 62 | 63 | wait(NULL); 64 | } 65 | else if (strcmp(argv[1], "queue") == 0) 66 | { 67 | act.sa_sigaction = handle_QUEUE; 68 | sigaction(SIGINT, &act, NULL); 69 | 70 | union sigval sigval; 71 | sigval.sival_int = 123; 72 | 73 | sigqueue(getpid(), SIGINT, sigval); 74 | } 75 | else if (strcmp(argv[1], "sigint") == 0) 76 | { 77 | 78 | act.sa_sigaction = handle_SIGINT; 79 | sigaction(SIGINT, &act, NULL); 80 | union sigval sigval; 81 | 82 | sigqueue(getpid(), SIGINT, sigval); 83 | } 84 | 85 | return 0; 86 | } -------------------------------------------------------------------------------- /lab1_v2/zad2/diff_dynamic.h: -------------------------------------------------------------------------------- 1 | #ifndef DIFF_DYN_H 2 | #define DIFF_DYN_H 3 | #include 4 | #include 5 | #include 6 | 7 | static void *handle = NULL; 8 | 9 | char *(*_get_operation)(int block_idx, int operation_idx); 10 | int (*_create_table)(unsigned int size); 11 | void (*_define_pair_sequence)(char *sequence); 12 | void (*_compare_pairs)(); 13 | int (*_get_operations_count)(int idx); 14 | int (*_tmp_to_array)(); 15 | void (*_delete_block)(int idx); 16 | void (*_delete_array)(); 17 | void (*_remove_operation)(int block_idx, int operation_idx); 18 | 19 | void init_dynamic_library() 20 | { 21 | handle = dlopen("lib_diff.so", RTLD_NOW); 22 | if (handle == NULL) 23 | { 24 | fprintf(stderr, "Error dynamic library open"); 25 | return; 26 | } 27 | _get_operation = dlsym(handle, "get_operation"); 28 | _create_table = dlsym(handle, "create_table"); 29 | _define_pair_sequence = dlsym(handle, "define_pair_sequence"); 30 | _compare_pairs = dlsym(handle, "compare_pairs"); 31 | _get_operations_count = dlsym(handle, "get_operations_count"); 32 | _tmp_to_array = dlsym(handle, "tmp_to_array"); 33 | _delete_block = dlsym(handle, "delete_block"); 34 | _delete_array = dlsym(handle, "delete_array"); 35 | _remove_operation = dlsym(handle, "remove_operation"); 36 | 37 | char *error; 38 | if ((error = dlerror()) != NULL) 39 | { 40 | fprintf(stderr, "%s\n", error); 41 | exit(1); 42 | } 43 | } 44 | 45 | int create_table(unsigned int size) 46 | { 47 | return (*_create_table)(size); 48 | } 49 | void define_pair_sequence(char *sequence) 50 | { 51 | return (*_define_pair_sequence)(sequence); 52 | } 53 | void compare_pairs() 54 | { 55 | return (*_compare_pairs)(); 56 | } 57 | int get_operations_count(int idx) 58 | { 59 | return (*_get_operations_count)(idx); 60 | } 61 | int tmp_to_array() 62 | { 63 | return (*_tmp_to_array)(); 64 | } 65 | void delete_block(int idx) 66 | { 67 | return (*_delete_block)(idx); 68 | } 69 | void delete_array() 70 | { 71 | return (*_delete_array)(); 72 | } 73 | void remove_operation(int block_idx, int operation_idx) 74 | { 75 | return (*_remove_operation)(block_idx, operation_idx); 76 | } 77 | char *get_operation(int block_idx, int operation_idx) 78 | { 79 | return (*_get_operation)(block_idx, operation_idx); 80 | } 81 | 82 | #endif -------------------------------------------------------------------------------- /lab7/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%) -------------------------------------------------------------------------------- /lab8/zad1/Times.txt: -------------------------------------------------------------------------------- 1 | Mode: sign | threads: 1 2 | Thread 0 ------- 520.606000 microseconds 3 | FULL TIME: 662.244000 4 | 5 | Mode: sign | threads: 2 6 | Thread 0 ------- 518.316000 microseconds 7 | Thread 1 ------- 389.987000 microseconds 8 | FULL TIME: 650.116000 9 | 10 | Mode: sign | threads: 4 11 | Thread 0 ------- 552.201000 microseconds 12 | Thread 1 ------- 763.285000 microseconds 13 | Thread 2 ------- 427.822000 microseconds 14 | Thread 3 ------- 662.846000 microseconds 15 | FULL TIME: 869.432000 16 | 17 | Mode: sign | threads: 8 18 | Thread 0 ------- 831.349000 microseconds 19 | Thread 1 ------- 782.672000 microseconds 20 | Thread 2 ------- 765.845000 microseconds 21 | Thread 3 ------- 691.649000 microseconds 22 | Thread 4 ------- 692.063000 microseconds 23 | Thread 5 ------- 583.054000 microseconds 24 | Thread 6 ------- 375.985000 microseconds 25 | Thread 7 ------- 365.133000 microseconds 26 | FULL TIME: 1483.973000 27 | 28 | Mode: block | threads: 1 29 | Thread 0 ------- 440.534000 microseconds 30 | FULL TIME: 581.717000 31 | 32 | Mode: block | threads: 2 33 | Thread 0 ------- 239.109000 microseconds 34 | Thread 1 ------- 332.799000 microseconds 35 | FULL TIME: 428.167000 36 | 37 | Mode: block | threads: 4 38 | Thread 0 ------- 127.941000 microseconds 39 | Thread 1 ------- 179.491000 microseconds 40 | Thread 2 ------- 104.473000 microseconds 41 | Thread 3 ------- 128.023000 microseconds 42 | FULL TIME: 470.792000 43 | 44 | Mode: block | threads: 8 45 | Thread 0 ------- 108.274000 microseconds 46 | Thread 1 ------- 88.272000 microseconds 47 | Thread 2 ------- 87.971000 microseconds 48 | Thread 3 ------- 92.457000 microseconds 49 | Thread 4 ------- 84.929000 microseconds 50 | Thread 5 ------- 80.510000 microseconds 51 | Thread 6 ------- 43.981000 microseconds 52 | Thread 7 ------- 54.918000 microseconds 53 | FULL TIME: 427.612000 54 | 55 | Mode: interleaved | threads: 1 56 | Thread 0 ------- 451.187000 microseconds 57 | FULL TIME: 629.255000 58 | 59 | Mode: interleaved | threads: 2 60 | Thread 0 ------- 241.309000 microseconds 61 | Thread 1 ------- 241.586000 microseconds 62 | FULL TIME: 386.385000 63 | 64 | Mode: interleaved | threads: 4 65 | Thread 0 ------- 179.320000 microseconds 66 | Thread 1 ------- 162.143000 microseconds 67 | Thread 2 ------- 121.290000 microseconds 68 | Thread 3 ------- 148.591000 microseconds 69 | FULL TIME: 386.867000 70 | 71 | Mode: interleaved | threads: 8 72 | Thread 0 ------- 119.460000 microseconds 73 | Thread 1 ------- 104.503000 microseconds 74 | Thread 2 ------- 85.208000 microseconds 75 | Thread 3 ------- 102.868000 microseconds 76 | Thread 4 ------- 92.331000 microseconds 77 | Thread 5 ------- 78.299000 microseconds 78 | Thread 6 ------- 58.163000 microseconds 79 | Thread 7 ------- 50.207000 microseconds 80 | FULL TIME: 428.144000 81 | 82 | -------------------------------------------------------------------------------- /lab7/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 "shared.h" 14 | 15 | #define W_1 3 16 | #define W_2 3 17 | #define W_3 3 18 | 19 | union semun { 20 | int val; 21 | struct semid_ds *buf; 22 | unsigned short *array; 23 | struct seminfo *__buf; 24 | }; 25 | 26 | pid_t pids[W_1 + W_2 + W_3]; 27 | 28 | int semaphore_id; 29 | int shared_memory_id; 30 | 31 | void set_semaphore() 32 | { 33 | key_t sem_key = ftok(getenv("HOME"), 0); 34 | semaphore_id = semget(sem_key, 6, IPC_CREAT | 0666); 35 | if (semaphore_id < 0) 36 | { 37 | printf("Cannot create semaphores set %d\n", errno); 38 | exit(EXIT_FAILURE); 39 | } 40 | union semun arg; 41 | arg.val = 0; 42 | 43 | for (int i = 0; i < 6; i++) 44 | { 45 | semctl(semaphore_id, i, SETVAL, arg); 46 | } 47 | } 48 | 49 | void create_shared_memory() 50 | { 51 | key_t shm_key = ftok(getenv("HOME"), 1); 52 | shared_memory_id = shmget(shm_key, sizeof(orders), IPC_CREAT | 0666); 53 | if (shared_memory_id < 0) 54 | { 55 | printf("Cannot create shared memory %d\n", errno); 56 | exit(EXIT_FAILURE); 57 | } 58 | } 59 | 60 | void clear() 61 | { 62 | semctl(semaphore_id, 0, IPC_RMID, NULL); 63 | shmctl(shared_memory_id, IPC_RMID, NULL); 64 | system("make clean"); 65 | } 66 | 67 | void handle_SIGINT(int signum) 68 | { 69 | for (int i = 0; i < W_1 + W_2 + W_3; i++) 70 | { 71 | kill(pids[i], SIGINT); 72 | } 73 | clear(); 74 | exit(0); 75 | } 76 | 77 | void run_workers() 78 | { 79 | for (int i = 0; i < W_1; i++) 80 | { 81 | pid_t child_pid = fork(); 82 | if (child_pid == 0) 83 | { 84 | execlp("./worker_1", "worker_1", NULL); 85 | } 86 | pids[i] = child_pid; 87 | } 88 | 89 | for (int i = 0; i < W_2; i++) 90 | { 91 | pid_t child_pid = fork(); 92 | if (child_pid == 0) 93 | { 94 | execlp("./worker_2", "worker_2", NULL); 95 | } 96 | pids[i + W_1] = child_pid; 97 | } 98 | 99 | for (int i = 0; i < W_3; i++) 100 | { 101 | pid_t child_pid = fork(); 102 | if (child_pid == 0) 103 | { 104 | execlp("./worker_3", "worker_3", NULL); 105 | } 106 | pids[i + W_1 + W_2] = child_pid; 107 | } 108 | for (int i = 0; i < W_1 + W_2 + W_3; i++) 109 | { 110 | wait(NULL); 111 | } 112 | } 113 | 114 | int main() 115 | { 116 | signal(SIGINT, handle_SIGINT); 117 | set_semaphore(); 118 | create_shared_memory(); 119 | run_workers(); 120 | clear(); 121 | return 0; 122 | } -------------------------------------------------------------------------------- /lab4/zad4b/catcher.c: -------------------------------------------------------------------------------- 1 | 2 | #define _XOPEN_SOURCE 500 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | typedef enum Mode 12 | { 13 | KILL, 14 | QUEUE, 15 | SIGRT 16 | } Mode; 17 | 18 | int COUNT_SIGNAL; 19 | int END_SIGNAL; 20 | 21 | Mode mode; 22 | 23 | int received_signals = 0; 24 | 25 | union sigval value; 26 | 27 | void handle_signals(int sig, siginfo_t *info, void *ucontext) 28 | { 29 | 30 | if (sig == COUNT_SIGNAL) 31 | { 32 | received_signals++; 33 | 34 | if (mode == KILL || mode == SIGRT) 35 | { 36 | kill(info->si_pid, COUNT_SIGNAL); 37 | } 38 | else 39 | { 40 | sigqueue(info->si_pid, COUNT_SIGNAL, value); 41 | } 42 | } 43 | else if (sig == END_SIGNAL) 44 | { 45 | if (mode == KILL || mode == SIGRT) 46 | { 47 | kill(info->si_pid, END_SIGNAL); 48 | } 49 | else 50 | { 51 | sigqueue(info->si_pid, END_SIGNAL, value); 52 | } 53 | printf("catcher received: %d signals\n", received_signals); 54 | exit(0); 55 | } 56 | } 57 | 58 | int main(int argc, char *argv[]) 59 | { 60 | if (argc != 2) 61 | { 62 | fprintf(stderr, "wrong arguments, usage: [mode]\n"); 63 | exit(1); 64 | } 65 | 66 | char *mode_str = argv[1]; 67 | 68 | if (strcmp("kill", mode_str) == 0) 69 | { 70 | mode = KILL; 71 | COUNT_SIGNAL = SIGUSR1; 72 | END_SIGNAL = SIGUSR2; 73 | } 74 | else if (strcmp("queue", mode_str) == 0) 75 | { 76 | mode = QUEUE; 77 | COUNT_SIGNAL = SIGUSR1; 78 | END_SIGNAL = SIGUSR2; 79 | } 80 | else if (strcmp("sigrt", mode_str) == 0) 81 | { 82 | mode = SIGRT; 83 | COUNT_SIGNAL = SIGRTMIN + 1; 84 | END_SIGNAL = SIGRTMIN + 2; 85 | } 86 | else 87 | { 88 | fprintf(stderr, "wring mode, allowed: [kill, queue, sigrt]\n"); 89 | exit(1); 90 | } 91 | 92 | value.sival_int = 0; 93 | sigset_t mask; 94 | sigfillset(&mask); 95 | sigdelset(&mask, COUNT_SIGNAL); 96 | sigdelset(&mask, END_SIGNAL); 97 | 98 | if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) 99 | { 100 | perror("cant block signals\n"); 101 | exit(1); 102 | } 103 | 104 | struct sigaction sa_handle; 105 | sa_handle.sa_flags = SA_SIGINFO; 106 | sa_handle.sa_sigaction = handle_signals; 107 | 108 | sigemptyset(&sa_handle.sa_mask); 109 | sigaddset(&sa_handle.sa_mask, COUNT_SIGNAL); 110 | sigaddset(&sa_handle.sa_mask, END_SIGNAL); 111 | 112 | sigaction(COUNT_SIGNAL, &sa_handle, NULL); 113 | sigaction(END_SIGNAL, &sa_handle, NULL); 114 | 115 | printf("created catcher with PID: %d\n", getpid()); 116 | while (1) 117 | { 118 | usleep(100); 119 | } 120 | 121 | return 0; 122 | } -------------------------------------------------------------------------------- /lab7/zad2/worker_1.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 | 14 | #include "shared.h" 15 | 16 | void handle_SIGINT(int signum) 17 | { 18 | for (int i = 0; i < 6; i++) 19 | { 20 | if (sem_close(semaphores[i]) < 0) 21 | { 22 | printf("Cant close semaphore\n"); 23 | printf("Errno: %d\n", errno); 24 | exit(EXIT_FAILURE); 25 | } 26 | } 27 | exit(0); 28 | } 29 | 30 | int get_value(int index) 31 | { 32 | int value; 33 | sem_getvalue(semaphores[index], &value); 34 | return value; 35 | } 36 | 37 | void add_order() 38 | { 39 | sem_wait(semaphores[0]); 40 | sem_post(semaphores[1]); 41 | 42 | orders *ord = mmap(NULL, sizeof(orders), PROT_READ | PROT_WRITE, MAP_SHARED, shared_memory_descriptor, 0); 43 | if (ord == (void *)-1) 44 | { 45 | printf("Cant map shared memory\n"); 46 | printf("Errno: %d\n", errno); 47 | exit(EXIT_FAILURE); 48 | } 49 | 50 | int value = rand_int; 51 | int index = (get_value(1) - 1) % MAX_ORDERS; 52 | ord->values[index] = value; 53 | int orders_to_prepare = get_value(3) + 1; 54 | int orders_to_send = get_value(5); 55 | printf("[%d %ld] Dodalem liczbe: %d. Liczba zamowien do przygotowania: %d. Liczba zamowien do wyslania: %d.\n", 56 | getpid(), time(NULL), value, orders_to_prepare, orders_to_send); 57 | if (munmap(ord, sizeof(orders)) < 0) 58 | { 59 | printf("Cant unmap shared memory\n"); 60 | printf("Errno: %d\n", errno); 61 | exit(EXIT_FAILURE); 62 | } 63 | sem_post(semaphores[0]); 64 | sem_post(semaphores[3]); 65 | } 66 | 67 | void init_semaphores() 68 | { 69 | 70 | for (int i = 0; i < 6; i++) 71 | { 72 | semaphores[i] = sem_open(SEMAPHORES[i], O_RDWR); 73 | if (semaphores[i] < 0) 74 | { 75 | printf("Cant open semaphore\n"); 76 | printf("Errno: %d\n", errno); 77 | exit(EXIT_FAILURE); 78 | } 79 | } 80 | } 81 | 82 | void init_shared_memory() 83 | { 84 | shared_memory_descriptor = shm_open(SHARED_MEMORY, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); 85 | if (shared_memory_descriptor < 0) 86 | { 87 | printf("Cant access shared memory\n"); 88 | printf("Errno: %d\n", errno); 89 | exit(EXIT_FAILURE); 90 | } 91 | } 92 | 93 | int main() 94 | { 95 | srand(time(NULL)); 96 | 97 | signal(SIGINT, handle_SIGINT); 98 | 99 | init_semaphores(); 100 | init_shared_memory(); 101 | 102 | while (1) 103 | { 104 | usleep(rand_time); 105 | 106 | if (get_value(3) + get_value(5) < MAX_ORDERS) 107 | { 108 | add_order(); 109 | } 110 | } 111 | 112 | return 0; 113 | } -------------------------------------------------------------------------------- /lab4/zad4a/catcher.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef enum Mode 11 | { 12 | KILL, 13 | QUEUE, 14 | SIGRT 15 | } Mode; 16 | 17 | int COUNT_SIGNAL; 18 | int END_SIGNAL; 19 | 20 | Mode mode; 21 | 22 | int received_signals = 0; 23 | 24 | void handle_signals(int sig, siginfo_t *info, void *ucontext) 25 | { 26 | if (sig == COUNT_SIGNAL) 27 | received_signals++; 28 | else if (sig == END_SIGNAL) 29 | { 30 | if (mode == KILL || mode == SIGRT) 31 | { 32 | for (int i = 0; i < received_signals; ++i) 33 | { 34 | kill(info->si_pid, COUNT_SIGNAL); 35 | } 36 | kill(info->si_pid, END_SIGNAL); 37 | } 38 | else 39 | { 40 | union sigval value; 41 | for (int i = 0; i < received_signals; ++i) 42 | { 43 | value.sival_int = i; 44 | sigqueue(info->si_pid, COUNT_SIGNAL, value); 45 | } 46 | sigqueue(info->si_pid, END_SIGNAL, value); 47 | } 48 | printf("catcher received: %d signals\n", received_signals); 49 | exit(0); 50 | } 51 | } 52 | 53 | int main(int argc, char *argv[]) 54 | { 55 | if (argc != 2) 56 | { 57 | fprintf(stderr, "wrong arguments, usage: [mode]\n"); 58 | exit(1); 59 | } 60 | 61 | char *mode_str = argv[1]; 62 | 63 | if (strcmp("kill", mode_str) == 0) 64 | { 65 | mode = KILL; 66 | COUNT_SIGNAL = SIGUSR1; 67 | END_SIGNAL = SIGUSR2; 68 | } 69 | else if (strcmp("queue", mode_str) == 0) 70 | { 71 | mode = QUEUE; 72 | COUNT_SIGNAL = SIGUSR1; 73 | END_SIGNAL = SIGUSR2; 74 | } 75 | else if (strcmp("sigrt", mode_str) == 0) 76 | { 77 | mode = SIGRT; 78 | COUNT_SIGNAL = SIGRTMIN + 1; 79 | END_SIGNAL = SIGRTMIN + 2; 80 | } 81 | else 82 | { 83 | fprintf(stderr, "wring mode, allowed: [kill, queue, sigrt]\n"); 84 | exit(1); 85 | } 86 | 87 | sigset_t mask; 88 | sigfillset(&mask); 89 | sigdelset(&mask, COUNT_SIGNAL); 90 | sigdelset(&mask, END_SIGNAL); 91 | 92 | if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) 93 | { 94 | perror("cant block signals\n"); 95 | exit(1); 96 | } 97 | 98 | struct sigaction sa_handle; 99 | sa_handle.sa_flags = SA_SIGINFO; 100 | sa_handle.sa_sigaction = handle_signals; 101 | 102 | sigemptyset(&sa_handle.sa_mask); 103 | sigaddset(&sa_handle.sa_mask, COUNT_SIGNAL); 104 | sigaddset(&sa_handle.sa_mask, END_SIGNAL); 105 | 106 | sigaction(COUNT_SIGNAL, &sa_handle, NULL); 107 | sigaction(END_SIGNAL, &sa_handle, NULL); 108 | 109 | printf("created catcher with PID: %d\n", getpid()); 110 | 111 | while (1) 112 | { 113 | usleep(100); 114 | } 115 | 116 | return 0; 117 | } -------------------------------------------------------------------------------- /lab7/zad2/worker_3.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 "shared.h" 14 | 15 | sem_t *semaphores[6]; 16 | int shared_memory_descriptor; 17 | 18 | void handle_SIGINT(int signum) 19 | { 20 | for (int i = 0; i < 6; i++) 21 | { 22 | if (sem_close(semaphores[i]) < 0) 23 | { 24 | printf("Cant close semaphore\n"); 25 | printf("Errno: %d\n", errno); 26 | exit(EXIT_FAILURE); 27 | } 28 | } 29 | exit(0); 30 | } 31 | int get_value(int index) 32 | { 33 | int value; 34 | sem_getvalue(semaphores[index], &value); 35 | return value; 36 | } 37 | 38 | void send_order() 39 | { 40 | sem_wait(semaphores[0]); 41 | sem_post(semaphores[4]); 42 | sem_wait(semaphores[5]); 43 | orders *ord = mmap(NULL, sizeof(orders), PROT_READ | PROT_WRITE, MAP_SHARED, shared_memory_descriptor, 0); 44 | if (ord == (void *)-1) 45 | { 46 | printf("Cant map shared memory\n"); 47 | printf("Errno: %d\n", errno); 48 | exit(EXIT_FAILURE); 49 | } 50 | 51 | int index = (get_value(4) - 1) % MAX_ORDERS; 52 | ord->values[index] *= 3; 53 | int orders_to_prepare = get_value(3); 54 | int orders_to_send = get_value(5); 55 | printf("[%d %ld] Wyslalem zamowienie o wielkosci: %d. Liczba zamowien do przygotowania: %d. Liczba zamowien do wyslania: %d.\n", 56 | getpid(), time(NULL), ord->values[index], orders_to_prepare, orders_to_send); 57 | ord->values[index] = 0; 58 | 59 | if (munmap(ord, sizeof(orders)) < 0) 60 | { 61 | printf("Cant unmap shared memory\n"); 62 | printf("Errno: %d\n", errno); 63 | exit(EXIT_FAILURE); 64 | } 65 | sem_post(semaphores[0]); 66 | } 67 | void init_semaphores() 68 | { 69 | 70 | for (int i = 0; i < 6; i++) 71 | { 72 | semaphores[i] = sem_open(SEMAPHORES[i], O_RDWR); 73 | if (semaphores[i] < 0) 74 | { 75 | printf("Cant open semaphore\n"); 76 | printf("Errno: %d\n", errno); 77 | exit(EXIT_FAILURE); 78 | } 79 | } 80 | } 81 | 82 | void init_shared_memory() 83 | { 84 | shared_memory_descriptor = shm_open(SHARED_MEMORY, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); 85 | if (shared_memory_descriptor < 0) 86 | { 87 | printf("Cant access shared memory\n"); 88 | printf("Errno: %d\n", errno); 89 | exit(EXIT_FAILURE); 90 | } 91 | } 92 | int main() 93 | { 94 | srand(time(NULL)); 95 | 96 | signal(SIGINT, handle_SIGINT); 97 | 98 | init_semaphores(); 99 | init_shared_memory(); 100 | 101 | while (1) 102 | { 103 | usleep(rand_time); 104 | 105 | if (get_value(5) > 0) 106 | { 107 | send_order(); 108 | } 109 | } 110 | 111 | return 0; 112 | } -------------------------------------------------------------------------------- /lab7/zad2/worker_2.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 "shared.h" 14 | 15 | sem_t *semaphores[6]; 16 | int shared_memory_descriptor; 17 | 18 | void handle_SIGINT(int signum) 19 | { 20 | for (int i = 0; i < 6; i++) 21 | { 22 | if (sem_close(semaphores[i]) < 0) 23 | { 24 | printf("Cant close semaphore\n"); 25 | printf("Errno: %d\n", errno); 26 | exit(EXIT_FAILURE); 27 | } 28 | } 29 | exit(0); 30 | } 31 | 32 | int get_value(int index) 33 | { 34 | int value; 35 | sem_getvalue(semaphores[index], &value); 36 | return value; 37 | } 38 | 39 | void pack_order() 40 | { 41 | sem_wait(semaphores[0]); 42 | sem_post(semaphores[2]); 43 | sem_wait(semaphores[3]); 44 | orders *ord = mmap(NULL, sizeof(orders), PROT_READ | PROT_WRITE, MAP_SHARED, shared_memory_descriptor, 0); 45 | if (ord == (void *)-1) 46 | { 47 | printf("Cant map shared memory\n"); 48 | printf("Errno: %d\n", errno); 49 | exit(EXIT_FAILURE); 50 | } 51 | 52 | int index = (get_value(2) - 1) % MAX_ORDERS; 53 | ord->values[index] *= 2; 54 | int orders_to_prepare = get_value(3); 55 | int orders_to_send = get_value(5) + 1; 56 | printf("[%d %ld] Przygotowalem zamowienie o wielkosci: %d. Liczba zamowien do przygotowania: %d. Liczba zamowien do wyslania: %d.\n", 57 | getpid(), time(NULL), ord->values[index], orders_to_prepare, orders_to_send); 58 | 59 | if (munmap(ord, sizeof(orders)) < 0) 60 | { 61 | printf("Cant unmap shared memory\n"); 62 | printf("Errno: %d\n", errno); 63 | exit(EXIT_FAILURE); 64 | } 65 | sem_post(semaphores[0]); 66 | sem_post(semaphores[5]); 67 | } 68 | void init_semaphores() 69 | { 70 | 71 | for (int i = 0; i < 6; i++) 72 | { 73 | semaphores[i] = sem_open(SEMAPHORES[i], O_RDWR); 74 | if (semaphores[i] < 0) 75 | { 76 | printf("Cant open semaphore\n"); 77 | printf("Errno: %d\n", errno); 78 | exit(EXIT_FAILURE); 79 | } 80 | } 81 | } 82 | 83 | void init_shared_memory() 84 | { 85 | shared_memory_descriptor = shm_open(SHARED_MEMORY, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO); 86 | if (shared_memory_descriptor < 0) 87 | { 88 | printf("Cant access shared memory\n"); 89 | printf("Errno: %d\n", errno); 90 | exit(EXIT_FAILURE); 91 | } 92 | } 93 | int main() 94 | { 95 | srand(time(NULL)); 96 | 97 | signal(SIGINT, handle_SIGINT); 98 | 99 | init_semaphores(); 100 | init_shared_memory(); 101 | 102 | while (1) 103 | { 104 | usleep(rand_time); 105 | 106 | if (get_value(3) > 0) 107 | { 108 | pack_order(); 109 | } 110 | } 111 | 112 | return 0; 113 | } -------------------------------------------------------------------------------- /lab4/zad4a/sender.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef enum Mode 11 | { 12 | KILL, 13 | QUEUE, 14 | SIGRT 15 | } Mode; 16 | 17 | int COUNT_SIGNAL; 18 | int END_SIGNAL; 19 | 20 | Mode mode; 21 | 22 | int sigs_to_send; 23 | int received_signals; 24 | 25 | void handle_signals(int sig, siginfo_t *info, void *ucontext) 26 | { 27 | if (sig == COUNT_SIGNAL) 28 | { 29 | received_signals++; 30 | if (mode == QUEUE) 31 | { 32 | printf("already received: %d, catcher index: %d\n", received_signals, info->si_value.sival_int); 33 | } 34 | } 35 | else if (sig == END_SIGNAL) 36 | { 37 | 38 | printf("sender received: %d signals, should receive: %d\n", received_signals, sigs_to_send); 39 | exit(0); 40 | } 41 | } 42 | 43 | int main(int argc, char *argv[]) 44 | { 45 | if (argc != 4) 46 | { 47 | fprintf(stderr, "wrong arguments, usage: [catcher PID] [num sig to send] [mode]\n"); 48 | } 49 | int catcher_PID = atoi(argv[1]); 50 | sigs_to_send = atoi(argv[2]); 51 | 52 | char *mode_str = argv[3]; 53 | 54 | if (strcmp("kill", mode_str) == 0) 55 | { 56 | mode = KILL; 57 | COUNT_SIGNAL = SIGUSR1; 58 | END_SIGNAL = SIGUSR2; 59 | } 60 | else if (strcmp("queue", mode_str) == 0) 61 | { 62 | mode = QUEUE; 63 | COUNT_SIGNAL = SIGUSR1; 64 | END_SIGNAL = SIGUSR2; 65 | } 66 | else if (strcmp("sigrt", mode_str) == 0) 67 | { 68 | mode = SIGRT; 69 | COUNT_SIGNAL = SIGRTMIN + 1; 70 | END_SIGNAL = SIGRTMIN + 2; 71 | } 72 | else 73 | { 74 | fprintf(stderr, "wring mode, allowed: [kill, queue, sigrt]\n"); 75 | exit(1); 76 | } 77 | 78 | sigset_t mask; 79 | sigfillset(&mask); 80 | sigdelset(&mask, COUNT_SIGNAL); 81 | sigdelset(&mask, END_SIGNAL); 82 | 83 | if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) 84 | { 85 | perror("cant block signals\n"); 86 | exit(1); 87 | } 88 | 89 | struct sigaction sa_handle; 90 | sa_handle.sa_flags = SA_SIGINFO; 91 | sa_handle.sa_sigaction = handle_signals; 92 | 93 | sigemptyset(&sa_handle.sa_mask); 94 | sigaddset(&sa_handle.sa_mask, COUNT_SIGNAL); 95 | sigaddset(&sa_handle.sa_mask, END_SIGNAL); 96 | 97 | sigaction(COUNT_SIGNAL, &sa_handle, NULL); 98 | sigaction(END_SIGNAL, &sa_handle, NULL); 99 | 100 | printf("created sender with PID: %d\n", getpid()); 101 | 102 | if (mode == KILL || mode == SIGRT) 103 | { 104 | for (int i = 0; i < sigs_to_send; ++i) 105 | { 106 | kill(catcher_PID, COUNT_SIGNAL); 107 | } 108 | kill(catcher_PID, END_SIGNAL); 109 | } 110 | else 111 | { 112 | union sigval value; 113 | value.sival_int = 0; 114 | for (int i = 0; i < sigs_to_send; ++i) 115 | { 116 | sigqueue(catcher_PID, COUNT_SIGNAL, value); 117 | } 118 | sigqueue(catcher_PID, END_SIGNAL, value); 119 | } 120 | 121 | while (1) 122 | { 123 | usleep(100); 124 | } 125 | 126 | return 0; 127 | } -------------------------------------------------------------------------------- /lab4/zad4b/sender.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | typedef enum Mode 10 | { 11 | KILL, 12 | QUEUE, 13 | SIGRT 14 | } Mode; 15 | 16 | int COUNT_SIGNAL; 17 | int END_SIGNAL; 18 | 19 | Mode mode; 20 | int catcher_PID; 21 | 22 | int sigs_to_send; 23 | int received_signals; 24 | int num_send = 0; 25 | union sigval value; 26 | void send_next_signal() 27 | { 28 | num_send++; 29 | if (mode == KILL || mode == SIGRT) 30 | { 31 | kill(catcher_PID, COUNT_SIGNAL); 32 | } 33 | else 34 | { 35 | sigqueue(catcher_PID, COUNT_SIGNAL, value); 36 | } 37 | } 38 | 39 | void send_end_signal() 40 | { 41 | if (mode == KILL || mode == SIGRT) 42 | { 43 | kill(catcher_PID, END_SIGNAL); 44 | } 45 | else 46 | { 47 | sigqueue(catcher_PID, END_SIGNAL, value); 48 | } 49 | } 50 | void handle_signals(int sig, siginfo_t *info, void *ucontext) 51 | { 52 | if (sig == COUNT_SIGNAL) 53 | { 54 | received_signals++; 55 | if (num_send < sigs_to_send) 56 | { 57 | send_next_signal(); 58 | } 59 | else 60 | { 61 | send_end_signal(); 62 | } 63 | } 64 | else if (sig == END_SIGNAL) 65 | { 66 | printf("sender received: %d signals, should receive: %d\n", received_signals, sigs_to_send); 67 | exit(0); 68 | } 69 | } 70 | 71 | int main(int argc, char *argv[]) 72 | { 73 | if (argc != 4) 74 | { 75 | fprintf(stderr, "wrong arguments, usage: [catcher PID] [num sig to send] [mode]\n"); 76 | } 77 | catcher_PID = atoi(argv[1]); 78 | sigs_to_send = atoi(argv[2]); 79 | 80 | char *mode_str = argv[3]; 81 | 82 | if (strcmp("kill", mode_str) == 0) 83 | { 84 | mode = KILL; 85 | COUNT_SIGNAL = SIGUSR1; 86 | END_SIGNAL = SIGUSR2; 87 | } 88 | else if (strcmp("queue", mode_str) == 0) 89 | { 90 | mode = QUEUE; 91 | COUNT_SIGNAL = SIGUSR1; 92 | END_SIGNAL = SIGUSR2; 93 | } 94 | else if (strcmp("sigrt", mode_str) == 0) 95 | { 96 | mode = SIGRT; 97 | COUNT_SIGNAL = SIGRTMIN + 1; 98 | END_SIGNAL = SIGRTMIN + 2; 99 | } 100 | else 101 | { 102 | fprintf(stderr, "wring mode, allowed: [kill, queue, sigrt]\n"); 103 | exit(1); 104 | } 105 | sigset_t mask; 106 | sigfillset(&mask); 107 | sigdelset(&mask, COUNT_SIGNAL); 108 | sigdelset(&mask, END_SIGNAL); 109 | 110 | if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) 111 | { 112 | perror("cant block signals\n"); 113 | exit(1); 114 | } 115 | struct sigaction sa_handle; 116 | sa_handle.sa_flags = SA_SIGINFO; 117 | sa_handle.sa_sigaction = handle_signals; 118 | 119 | sigemptyset(&sa_handle.sa_mask); 120 | sigaddset(&sa_handle.sa_mask, COUNT_SIGNAL); 121 | sigaddset(&sa_handle.sa_mask, END_SIGNAL); 122 | 123 | sigaction(COUNT_SIGNAL, &sa_handle, NULL); 124 | sigaction(END_SIGNAL, &sa_handle, NULL); 125 | printf("created sender with PID: %d\n", getpid()); 126 | send_next_signal(); 127 | 128 | while (1) 129 | { 130 | usleep(100); 131 | } 132 | 133 | return 0; 134 | } -------------------------------------------------------------------------------- /lab9/zad1/barber.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int count_of_clients; 12 | int count_of_chairs; 13 | 14 | pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 15 | pthread_cond_t condition = PTHREAD_COND_INITIALIZER; 16 | 17 | pthread_t current_client; 18 | 19 | int next_chair = 0; 20 | int next_chair_for_barber = 0; 21 | int clients_served = 0; 22 | 23 | pthread_t *chairs; 24 | int sleeping = 0; 25 | int free_chairs; 26 | void *barber() 27 | { 28 | while (1) 29 | { 30 | pthread_mutex_lock(&mutex); 31 | if (free_chairs == count_of_chairs) 32 | { 33 | printf("Golibroda: ide spac\n"); 34 | sleeping = 1; 35 | pthread_cond_wait(&condition, &mutex); 36 | sleeping = 0; 37 | } 38 | else 39 | { 40 | free_chairs++; 41 | current_client = chairs[next_chair_for_barber]; 42 | next_chair_for_barber = (next_chair_for_barber + 1) % count_of_chairs; 43 | } 44 | printf("Golibroda: czeka %d klientow, gole klienta %ld\n", count_of_chairs - free_chairs, current_client); 45 | pthread_mutex_unlock(&mutex); 46 | sleep((rand() % 3 + 1)); 47 | pthread_mutex_lock(&mutex); 48 | clients_served++; 49 | if (clients_served == count_of_clients) 50 | { 51 | pthread_mutex_unlock(&mutex); 52 | break; 53 | } 54 | pthread_mutex_unlock(&mutex); 55 | } 56 | pthread_exit((void *)0); 57 | } 58 | 59 | void *client() 60 | { 61 | pthread_t client_id = pthread_self(); 62 | while (1) 63 | { 64 | pthread_mutex_lock(&mutex); 65 | if (sleeping) 66 | { 67 | current_client = client_id; 68 | printf("Klient: budze golibrode; %ld\n", client_id); 69 | pthread_cond_broadcast(&condition); 70 | break; 71 | } 72 | else if (free_chairs > 0) 73 | { 74 | chairs[next_chair] = client_id; 75 | next_chair = (next_chair + 1) % count_of_chairs; 76 | free_chairs--; 77 | printf("Klient: poczekalnia, wolne miejsca %d; %ld\n", free_chairs, client_id); 78 | break; 79 | } 80 | else 81 | { 82 | printf("Klient: zajete; %ld\n", client_id); 83 | pthread_mutex_unlock(&mutex); 84 | sleep((rand() % 3 + 1) * 4); 85 | } 86 | } 87 | pthread_mutex_unlock(&mutex); 88 | pthread_exit((void *)0); 89 | } 90 | void run_threads() 91 | { 92 | pthread_t *clients = calloc(count_of_clients + 1, sizeof(pthread_t)); 93 | 94 | pthread_create(&clients[0], NULL, barber, NULL); 95 | for (int i = 1; i < count_of_clients + 1; i++) 96 | { 97 | sleep(rand() % 3 + 1); 98 | pthread_create(&clients[i], NULL, client, NULL); 99 | } 100 | 101 | for (int i = 0; i < count_of_clients + 1; i++) 102 | { 103 | pthread_join(clients[i], NULL); 104 | } 105 | } 106 | 107 | int main(int args, char **argv) 108 | { 109 | count_of_chairs = atoi(argv[1]); 110 | count_of_clients = atoi(argv[2]); 111 | free_chairs = count_of_chairs; 112 | srand(time(NULL)); 113 | chairs = calloc(count_of_chairs, sizeof(pthread_t)); 114 | run_threads(); 115 | return 0; 116 | } -------------------------------------------------------------------------------- /lab7/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 "shared.h" 13 | #define W_1 3 14 | #define W_2 3 15 | #define W_3 3 16 | pid_t pids[W_1 + W_2 + W_3]; 17 | 18 | void clear() 19 | { 20 | for (int i = 0; i < 6; i++) 21 | if (sem_unlink(SEMAPHORES[i]) < 0) 22 | { 23 | printf("Cant unline semaphore\n"); 24 | printf("Errno: %d\n", errno); 25 | exit(EXIT_FAILURE); 26 | } 27 | if (shm_unlink(SHARED_MEMORY)) 28 | { 29 | printf("Cant delete shared memory\n"); 30 | printf("Errno: %d\n", errno); 31 | exit(EXIT_FAILURE); 32 | } 33 | system("make clean"); 34 | } 35 | 36 | void handle_SIGINT(int signum) 37 | { 38 | printf("Konczenie dzialania...\n"); 39 | for (int i = 0; i < W_1 + W_2 + W_3; i++) 40 | { 41 | kill(pids[i], SIGINT); 42 | } 43 | clear(); 44 | exit(0); 45 | } 46 | 47 | void create_semaphores() 48 | { 49 | sem_t *sem = sem_open(SEMAPHORES[0], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 1); 50 | if (sem == SEM_FAILED) 51 | { 52 | printf("Cant cretate first semaphore\n"); 53 | printf("Errno: %d\n", errno); 54 | exit(EXIT_FAILURE); 55 | } 56 | sem_close(sem); 57 | 58 | for (int i = 1; i < 6; i++) 59 | { 60 | sem = sem_open(SEMAPHORES[i], O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 0); 61 | if (sem == SEM_FAILED) 62 | { 63 | printf("Cant create semaphoree\n"); 64 | printf("Errno: %d\n", errno); 65 | exit(EXIT_FAILURE); 66 | } 67 | sem_close(sem); 68 | } 69 | } 70 | void create_shared_memory() 71 | { 72 | int fd = shm_open(SHARED_MEMORY, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO); 73 | if (fd < 0) 74 | { 75 | printf("Cant create shared memory\n"); 76 | printf("Errno: %d\n", errno); 77 | exit(EXIT_FAILURE); 78 | } 79 | if (ftruncate(fd, sizeof(orders)) < 0) 80 | { 81 | printf("Cant create segment size\n"); 82 | printf("Errno: %d\n", errno); 83 | exit(EXIT_FAILURE); 84 | } 85 | } 86 | 87 | void run_workers() 88 | { 89 | for (int i = 0; i < W_1; i++) 90 | { 91 | pid_t child_pid = fork(); 92 | if (child_pid == 0) 93 | { 94 | execlp("./worker1", "worker1", NULL); 95 | } 96 | pids[i] = child_pid; 97 | } 98 | 99 | for (int i = 0; i < W_2; i++) 100 | { 101 | pid_t child_pid = fork(); 102 | if (child_pid == 0) 103 | { 104 | execlp("./worker2", "worker2", NULL); 105 | } 106 | pids[i + W_1] = child_pid; 107 | } 108 | 109 | for (int i = 0; i < W_3; i++) 110 | { 111 | pid_t child_pid = fork(); 112 | if (child_pid == 0) 113 | { 114 | execlp("./worker3", "worker3", NULL); 115 | } 116 | pids[i + W_1 + W_2] = child_pid; 117 | } 118 | 119 | for (int i = 0; i < W_1 + W_2 + W_3; i++) 120 | { 121 | wait(NULL); 122 | } 123 | } 124 | int main() 125 | { 126 | signal(SIGINT, handle_SIGINT); 127 | create_semaphores(); 128 | create_shared_memory(); 129 | run_workers(); 130 | clear(); 131 | 132 | return 0; 133 | } -------------------------------------------------------------------------------- /lab3/zad2/help.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "matrix_helper.c" 7 | 8 | bool check_multiply_correctness(char *a_filename, char *b_filename, char *c_filename) 9 | { 10 | matrix a = load_matrix(a_filename); 11 | matrix b = load_matrix(b_filename); 12 | matrix c = load_matrix(c_filename); 13 | matrix correct_matrix = multiply_matrices(a, b); 14 | if (correct_matrix.cols != c.cols || correct_matrix.rows != c.rows) 15 | return false; 16 | for (int i = 0; i < correct_matrix.rows; i++) 17 | { 18 | for (int j = 0; j < correct_matrix.cols; j++) 19 | { 20 | if (correct_matrix.values[i][j] != c.values[i][j]) 21 | return false; 22 | } 23 | } 24 | free_matrix(&a); 25 | free_matrix(&b); 26 | free_matrix(&c); 27 | free_matrix(&correct_matrix); 28 | return true; 29 | } 30 | 31 | int main(int argc, char **argv) 32 | { 33 | char *mode = calloc(10, sizeof(char)); 34 | mode = argv[1]; 35 | if (strcmp(mode, "create") == 0) 36 | { 37 | srand(time(NULL)); 38 | int min = atoi(argv[2]); 39 | int max = atoi(argv[3]); 40 | int number = atoi(argv[4]); 41 | system("mkdir files"); 42 | for (int i = 0; i < number; i++) 43 | { 44 | int a_rows = rand() % (max - min + 1) + min; 45 | int a_cols = rand() % (max - min + 1) + min; 46 | int b_cols = rand() % (max - min + 1) + min; 47 | char *a_name = calloc(100, sizeof(char)); 48 | char *b_name = calloc(100, sizeof(char)); 49 | char *c_name = calloc(100, sizeof(char)); 50 | sprintf(a_name, "files/a%d.txt", i); 51 | sprintf(b_name, "files/b%d.txt", i); 52 | sprintf(c_name, "files/c%d.txt", i); 53 | 54 | generate_matrix(a_rows, a_cols, a_name); 55 | generate_matrix(a_cols, b_cols, b_name); 56 | 57 | char *command = calloc(1000, sizeof(char)); 58 | sprintf(command, "echo \"%s %s %s\" >> lista", a_name, b_name, c_name); 59 | system(command); 60 | } 61 | } 62 | else if (strcmp(mode, "check") == 0) 63 | { 64 | 65 | char **a_filenames = calloc(100, sizeof(char *)); 66 | char **b_filenames = calloc(100, sizeof(char *)); 67 | char **c_filenames = calloc(100, sizeof(char *)); 68 | FILE *input_file = fopen(argv[2], "r"); 69 | char input_line[PATH_MAX * 3 + 3]; 70 | int pair_counter = 0; 71 | while (fgets(input_line, PATH_MAX * 3 + 3, input_file) != NULL) 72 | { 73 | a_filenames[pair_counter] = calloc(PATH_MAX, sizeof(char)); 74 | b_filenames[pair_counter] = calloc(PATH_MAX, sizeof(char)); 75 | c_filenames[pair_counter] = calloc(PATH_MAX, sizeof(char)); 76 | strcpy(a_filenames[pair_counter], strtok(input_line, " ")); 77 | strcpy(b_filenames[pair_counter], strtok(NULL, " ")); 78 | strcpy(c_filenames[pair_counter], strtok(NULL, " ")); 79 | 80 | bool correct = check_multiply_correctness(a_filenames[pair_counter], b_filenames[pair_counter], c_filenames[pair_counter]); 81 | if (correct) 82 | { 83 | puts("mnozenie poprawne"); 84 | } 85 | else 86 | { 87 | puts("mnozenie bledne"); 88 | } 89 | pair_counter++; 90 | } 91 | } 92 | else 93 | { 94 | fprintf(stderr, "Error zly arg"); 95 | } 96 | return 0; 97 | } -------------------------------------------------------------------------------- /lab3/zad3/help.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "matrix_helper.c" 7 | 8 | bool check_multiply_correctness(char *a_filename, char *b_filename, char *c_filename) 9 | { 10 | matrix a = load_matrix(a_filename); 11 | matrix b = load_matrix(b_filename); 12 | matrix c = load_matrix(c_filename); 13 | matrix correct_matrix = multiply_matrices(a, b); 14 | if (correct_matrix.cols != c.cols || correct_matrix.rows != c.rows) 15 | return false; 16 | for (int i = 0; i < correct_matrix.rows; i++) 17 | { 18 | for (int j = 0; j < correct_matrix.cols; j++) 19 | { 20 | if (correct_matrix.values[i][j] != c.values[i][j]) 21 | return false; 22 | } 23 | } 24 | free_matrix(&a); 25 | free_matrix(&b); 26 | free_matrix(&c); 27 | free_matrix(&correct_matrix); 28 | return true; 29 | } 30 | 31 | int main(int argc, char **argv) 32 | { 33 | char *mode = calloc(10, sizeof(char)); 34 | mode = argv[1]; 35 | if (strcmp(mode, "create") == 0) 36 | { 37 | srand(time(NULL)); 38 | int min = atoi(argv[2]); 39 | int max = atoi(argv[3]); 40 | int number = atoi(argv[4]); 41 | system("mkdir files"); 42 | for (int i = 0; i < number; i++) 43 | { 44 | int a_rows = rand() % (max - min + 1) + min; 45 | int a_cols = rand() % (max - min + 1) + min; 46 | int b_cols = rand() % (max - min + 1) + min; 47 | char *a_name = calloc(100, sizeof(char)); 48 | char *b_name = calloc(100, sizeof(char)); 49 | char *c_name = calloc(100, sizeof(char)); 50 | sprintf(a_name, "files/a%d.txt", i); 51 | sprintf(b_name, "files/b%d.txt", i); 52 | sprintf(c_name, "files/c%d.txt", i); 53 | 54 | generate_matrix(a_rows, a_cols, a_name); 55 | generate_matrix(a_cols, b_cols, b_name); 56 | 57 | char *command = calloc(1000, sizeof(char)); 58 | sprintf(command, "echo \"%s %s %s\" >> lista", a_name, b_name, c_name); 59 | system(command); 60 | } 61 | } 62 | else if (strcmp(mode, "check") == 0) 63 | { 64 | 65 | char **a_filenames = calloc(100, sizeof(char *)); 66 | char **b_filenames = calloc(100, sizeof(char *)); 67 | char **c_filenames = calloc(100, sizeof(char *)); 68 | FILE *input_file = fopen(argv[2], "r"); 69 | char input_line[PATH_MAX * 3 + 3]; 70 | int pair_counter = 0; 71 | while (fgets(input_line, PATH_MAX * 3 + 3, input_file) != NULL) 72 | { 73 | a_filenames[pair_counter] = calloc(PATH_MAX, sizeof(char)); 74 | b_filenames[pair_counter] = calloc(PATH_MAX, sizeof(char)); 75 | c_filenames[pair_counter] = calloc(PATH_MAX, sizeof(char)); 76 | strcpy(a_filenames[pair_counter], strtok(input_line, " ")); 77 | strcpy(b_filenames[pair_counter], strtok(NULL, " ")); 78 | strcpy(c_filenames[pair_counter], strtok(NULL, " ")); 79 | 80 | bool correct = check_multiply_correctness(a_filenames[pair_counter], b_filenames[pair_counter], c_filenames[pair_counter]); 81 | if (correct) 82 | { 83 | puts("mnozenie poprawne"); 84 | } 85 | else 86 | { 87 | puts("mnozenie bledne"); 88 | } 89 | pair_counter++; 90 | } 91 | } 92 | else 93 | { 94 | fprintf(stderr, "Error zly arg"); 95 | } 96 | return 0; 97 | } -------------------------------------------------------------------------------- /lab8/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. -------------------------------------------------------------------------------- /lab5/zad1/pipes.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define MAX_PROGRAMS 32 13 | #define MAX_ARG_COUNT 16 14 | 15 | void fill_program_with_arguments(char *args[], char *cmd) 16 | { 17 | char *args_tmp = cmd; 18 | char *arg = strtok_r(cmd, " ", &args_tmp); 19 | int arg_counter = 0; 20 | while (arg != NULL) 21 | { 22 | args[arg_counter++] = arg; 23 | arg = strtok_r(NULL, " ", &args_tmp); 24 | } 25 | } 26 | 27 | void execute_command(char *line) 28 | { 29 | char *programs[MAX_PROGRAMS][MAX_ARG_COUNT]; 30 | 31 | for (int i = 0; i < MAX_PROGRAMS; ++i) 32 | { 33 | for (int j = 0; j < MAX_ARG_COUNT; ++j) 34 | { 35 | programs[i][j] = NULL; 36 | } 37 | } 38 | char *cmd_tmp = line; 39 | char *cmd = strtok_r(line, "|", &cmd_tmp); 40 | int prog_count = 0; 41 | while (cmd != NULL) 42 | { 43 | fill_program_with_arguments(programs[prog_count++], cmd); 44 | cmd = strtok_r(NULL, "|", &cmd_tmp); 45 | } 46 | int pipes[MAX_PROGRAMS][2]; 47 | for (int i = 0; i < prog_count - 1; i++) 48 | { 49 | 50 | if (pipe(pipes[i]) < 0) 51 | { 52 | fprintf(stderr, "cant make pipe\n"); 53 | exit(1); 54 | } 55 | } 56 | 57 | for (int i = 0; i < prog_count; i++) 58 | { 59 | pid_t pid = fork(); 60 | if (pid < 0) 61 | { 62 | fprintf(stderr, "cant fork\n"); 63 | exit(1); 64 | } 65 | else if (pid == 0) 66 | { 67 | if (i > 0) 68 | { 69 | dup2(pipes[i - 1][0], STDIN_FILENO); 70 | } 71 | if (i + 1 < prog_count) 72 | { 73 | dup2(pipes[i][1], STDOUT_FILENO); 74 | } 75 | for (int j = 0; j < prog_count - 1; j++) 76 | { 77 | close(pipes[j][0]); 78 | close(pipes[j][1]); 79 | } 80 | execvp(programs[i][0], programs[i]); 81 | exit(0); 82 | } 83 | } 84 | for (int j = 0; j < prog_count - 1; ++j) 85 | { 86 | close(pipes[j][0]); 87 | close(pipes[j][1]); 88 | } 89 | for (int i = 0; i < prog_count; ++i) 90 | { 91 | wait(0); 92 | } 93 | } 94 | 95 | long get_file_size(FILE *f) 96 | { 97 | fseek(f, 0, SEEK_END); 98 | long file_size = ftell(f); 99 | fseek(f, 0, SEEK_SET); 100 | return file_size; 101 | } 102 | 103 | int main(int argc, char *argv[]) 104 | { 105 | if (argc != 2) 106 | { 107 | fprintf(stderr, "wrong arguments, usage: [file]\n"); 108 | exit(1); 109 | } 110 | char *file_path = argv[1]; 111 | FILE *f = fopen(file_path, "r"); 112 | if (f == NULL) 113 | { 114 | fprintf(stderr, "can't find or open file %s\n", file_path); 115 | exit(1); 116 | } 117 | 118 | long file_size = get_file_size(f); 119 | char *buffer = malloc(file_size + 1); 120 | if (fread(buffer, 1, file_size, f) != file_size) 121 | { 122 | fprintf(stderr, "cant read from file %s\n", file_path); 123 | exit(1); 124 | } 125 | fclose(f); 126 | 127 | char *lines_tmp = buffer; 128 | char *line = strtok_r(buffer, "\n", &lines_tmp); 129 | while (line != NULL) 130 | { 131 | execute_command(line); 132 | line = strtok_r(NULL, "\n", &lines_tmp); 133 | } 134 | free(buffer); 135 | return 0; 136 | } -------------------------------------------------------------------------------- /lab2/README.md: -------------------------------------------------------------------------------- 1 | ## Zadanie 1. Porównanie wydajności systemowych i bibliotecznych funkcji We/Wy (55%) 2 | 3 | * (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. 4 | 5 | Program udostępniać powinien operacje: 6 | 7 | * generate - tworzenie pliku z rekordami wypełnionego wygenerowaną losową zawartością (można wykorzystać wirtualny generator/dev/random) lub w wersji uproszczonej funkcję rand() 8 | * 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). 9 | * copy - kopiuje plik1 do pliku2. Kopiowanie powinno odbywać się za pomocą bufora o zadanej wielkości rekordu. 10 | 11 | Sortowanie i kopiowanie powinno być zaimplementowane w dwóch wariantach: 12 | 13 | * sys - przy użyciu funkcji systemowych: read i write 14 | * lib - przy użyciu funkcji biblioteki C: fread i fwrite 15 | 16 | Rodzaj operacji oraz sposób dostępu do plików ma być wybierany na podstawie argumentu wywołania, np.: 17 | 18 | ./program generate dane 100 512 powinno losowo generować 100 rekordów o długości 512 bajtów (znaków) 19 | do pliku dane, 20 | 21 | ./program sort dane 100 512 sys powinien sortować rekordy w pliku dane przy użyciu funkcji systemowych, 22 | zakładając że zawiera on 100 rekordów wielkości 512 bajtów 23 | 24 | ./program copy plik1 plik2 100 512 lib powinno skopiować 100 rekordów pliku 1 do pliku 2 za pomocą funkcji 25 | bibliotecznych z wykorzystaniem bufora 512 bajtów 26 | 27 | * (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. 28 | 29 | ## Zadanie 2. Operacje na strukturze katalogów (45%) 30 | 31 | 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: 32 | 33 | * ścieżka bezwzględna pliku, 34 | * liczbę dowiązań 35 | * 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) 36 | * rozmiar w bajtach, 37 | * datę ostatniego dostępu, 38 | * datę ostatniej modyfikacji. 39 | 40 | Ś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. 41 | 42 | Program należy zaimplementować w dwóch wariantach: 43 | 44 | 1. Korzystając z funkcji opendir(), readdir() oraz funkcji z rodziny stat (25%) 45 | 2. Korzystając z funkcji nftw() (20%) 46 | 47 | W ramach testowania funkcji utwórz w badanej strukturze katalogów jakieś dowiązania symboliczne, zwykłe pliki i katalogi. 48 | -------------------------------------------------------------------------------- /lab5/README.md: -------------------------------------------------------------------------------- 1 | # Zadania - Zestaw 5 2 | # Potoki nazwane i nienazwane 3 | ## Zadanie 1 (50%) 4 | Napisz interpreter poleceń przechowywanych w pliku. Ścieżka do pliku to pierwszy argument wywołania programu. 5 | 6 | Polecenia w pliku przechowywane są w kolejnych liniach w postaci: 7 | 8 | prog1 arg1 ... argn1 | prog2 arg1 ... argn2 | ... | progN arg1 ... argnN 9 | 10 | - 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) 11 | - 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). 12 | - Po uruchomieniu ciągu programów składających się na pojedyncze polecenie (linijkę) interpreter powinien oczekiwać na zakończenie wszystkich tych programów. 13 | 14 | Program należy zaimplementować w dwóch wariantach: 15 | - Korzystając z funkcji pipe/fork/exec (50%) 16 | - Korzystając z popen (dodatkowo) 17 | ## Zadanie 2 (10%) 18 | 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). 19 | ## Zadanie 3 (40%) 20 | 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. 21 | 22 | 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. 23 | 24 | Producent: 25 | 26 | - 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 27 | - otwiera potok nazwany 28 | - wielokrotnie (aż do odczytania całego pliku): 29 | - odczekuje losową ilość czasu (np. 1-2 sekund) 30 | - zapisuje do potoku nazwanego linię zawierającą swój PID oraz odczytany fragment pliku w następującej formie: #PID#(N odczytanych znaków) 31 | 32 | Konsument: 33 | 34 | - 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 35 | - otwiera potok nazwany 36 | - wielokrotnie: 37 | - czyta kolejnych N znaków potoku nazwanego 38 | - umieszcza odczytane znaki w pliku tekstowym (różnym od plików, z których korzystają producenci) 39 | 40 | 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. 41 | 42 | 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). 43 | -------------------------------------------------------------------------------- /lab1/zad3a/raport3a.txt: -------------------------------------------------------------------------------- 1 | static: 2 | Name Real [s] User [s] System [s] Child User [s] Child System [s] 3 | table create 100: 0.000000 0.000000 0.000000 0.000000 0.000000 4 | small diff: 0.010000 0.000000 0.000000 0.000000 0.000000 5 | small remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 6 | small remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 7 | medium diff: 0.010000 0.000000 0.000000 0.000000 0.000000 8 | medium remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 9 | medium remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 10 | big diff: 0.040000 0.000000 0.000000 0.040000 0.000000 11 | big remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 12 | big remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 13 | add remove 7 times: 0.000000 0.000000 0.000000 0.000000 0.000000 14 | shared: 15 | Name Real [s] User [s] System [s] Child User [s] Child System [s] 16 | table create 100: 0.000000 0.000000 0.000000 0.000000 0.000000 17 | small diff: 0.010000 0.000000 0.000000 0.000000 0.000000 18 | small remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 19 | small remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 20 | medium diff: 0.010000 0.000000 0.000000 0.010000 0.000000 21 | medium remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 22 | medium remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 23 | big diff: 0.040000 0.000000 0.000000 0.030000 0.000000 24 | big remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 25 | big remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 26 | add remove 7 times: 0.000000 0.000000 0.000000 0.000000 0.000000 27 | dynamic: 28 | Name Real [s] User [s] System [s] Child User [s] Child System [s] 29 | table create 100: 0.000000 0.000000 0.000000 0.000000 0.000000 30 | small diff: 0.010000 0.000000 0.000000 0.000000 0.000000 31 | small remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 32 | small remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 33 | medium diff: 0.010000 0.000000 0.000000 0.010000 0.000000 34 | medium remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 35 | medium remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 36 | big diff: 0.040000 0.000000 0.000000 0.030000 0.000000 37 | big remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 38 | big remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 39 | add remove 7 times: 0.000000 0.000000 0.000000 0.000000 0.000000 40 | -------------------------------------------------------------------------------- /lab3/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 | -------------------------------------------------------------------------------- /lab2/zad1/generator_prog.c: -------------------------------------------------------------------------------- 1 | #include "generator.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | clock_t st_time, en_time; 9 | struct tms st_cpu, en_cpu; 10 | FILE *report_file; 11 | 12 | void start_timer() 13 | { 14 | st_time = times(&st_cpu); 15 | } 16 | 17 | void end_timer() 18 | { 19 | en_time = times(&en_cpu); 20 | } 21 | 22 | void write_file_header(FILE *f) 23 | { 24 | fprintf(f, "%40s\t\t%15s\t%15s\t%15s\n", 25 | "Name", 26 | "Real [s]", 27 | "User [s]", 28 | "System [s]"); 29 | } 30 | 31 | void save_timer(char *name, FILE *f) 32 | { 33 | int clk_tics = sysconf(_SC_CLK_TCK); 34 | double real_time = (double)(en_time - st_time) / clk_tics; 35 | double user_time = (double)(en_cpu.tms_utime - st_cpu.tms_utime) / clk_tics; 36 | double system_time = (double)(en_cpu.tms_stime - st_cpu.tms_stime) / clk_tics; 37 | 38 | fprintf(f, "%40s:\t\t%15f\t%15f\t%15f\n", 39 | name, 40 | real_time, 41 | user_time, 42 | system_time); 43 | } 44 | 45 | int parse_generate(int argc, char *argv[], int i) 46 | { 47 | if (i + 3 > argc) 48 | { 49 | fprintf(stderr, "generate command wrong args\n"); 50 | exit(-1); 51 | } 52 | char *file_name = argv[i + 1]; 53 | int rec_num = atoi(argv[i + 2]); 54 | int byte_num = atoi(argv[i + 3]); 55 | generate(file_name, rec_num, byte_num); 56 | return i + 4; 57 | } 58 | 59 | int parse_sort(int argc, char *argv[], int i) 60 | { 61 | if (i + 4 >= argc) 62 | { 63 | fprintf(stderr, "sort command wrong args\n"); 64 | exit(-1); 65 | } 66 | char *file_name = argv[i + 1]; 67 | int rec_num = atoi(argv[i + 2]); 68 | int byte_num = atoi(argv[i + 3]); 69 | char *lib_sys = argv[i + 4]; 70 | 71 | if (!strcmp(lib_sys, "lib")) 72 | { 73 | start_timer(); 74 | sort_lib(file_name, rec_num, byte_num); 75 | end_timer(); 76 | } 77 | else if (!strcmp(lib_sys, "sys")) 78 | { 79 | start_timer(); 80 | sort_sys(file_name, rec_num, byte_num); 81 | end_timer(); 82 | } 83 | char buff[64]; 84 | snprintf(buff, sizeof buff, "sort %s, records: %d, bytes: %d", lib_sys, rec_num, byte_num); 85 | save_timer(buff, report_file); 86 | 87 | return i + 5; 88 | } 89 | 90 | int parse_copy(int argc, char *argv[], int i) 91 | { 92 | if (i + 5 >= argc) 93 | { 94 | fprintf(stderr, "sort command wrong args\n"); 95 | exit(-1); 96 | } 97 | 98 | char *file_from = argv[i + 1]; 99 | char *file_to = argv[i + 2]; 100 | int rec_num = atoi(argv[i + 3]); 101 | int byte_num = atoi(argv[i + 4]); 102 | char *lib_sys = argv[i + 5]; 103 | 104 | if (!strcmp(lib_sys, "lib")) 105 | { 106 | start_timer(); 107 | copy_lib(file_from, file_to, rec_num, byte_num); 108 | end_timer(); 109 | } 110 | else if (!strcmp(lib_sys, "sys")) 111 | { 112 | start_timer(); 113 | copy_sys(file_from, file_to, rec_num, byte_num); 114 | end_timer(); 115 | } 116 | 117 | char buff[64]; 118 | snprintf(buff, sizeof buff, "copy %s, records: %d, bytes: %d", lib_sys, rec_num, byte_num); 119 | save_timer(buff, report_file); 120 | 121 | return i + 6; 122 | } 123 | 124 | int main(int argc, char *argv[]) 125 | { 126 | char file_name[] = "wyniki.txt"; 127 | 128 | if (access(file_name, F_OK) != 0) 129 | { 130 | report_file = fopen(file_name, "a"); 131 | write_file_header(report_file); 132 | } 133 | else 134 | { 135 | report_file = fopen(file_name, "a"); 136 | } 137 | 138 | int i = 1; 139 | while (i < argc) 140 | { 141 | if (!strcmp(argv[i], "generate")) 142 | { 143 | i = parse_generate(argc, argv, i); 144 | } 145 | else if (!strcmp(argv[i], "sort")) 146 | { 147 | i = parse_sort(argc, argv, i); 148 | } 149 | else if (!strcmp(argv[i], "copy")) 150 | { 151 | i = parse_copy(argc, argv, i); 152 | } 153 | else 154 | { 155 | fprintf(stderr, "Wrong command\n"); 156 | exit(-1); 157 | } 158 | } 159 | fclose(report_file); 160 | return 0; 161 | } -------------------------------------------------------------------------------- /lab1_v2/zad3a/raport3a.txt: -------------------------------------------------------------------------------- 1 | static: 2 | Name Real [s] User [s] System [s] Child User [s] Child System [s] 3 | table create 100: 0.000000 0.000000 0.000000 0.000000 0.000000 4 | small diff: 0.010000 0.000000 0.000000 0.000000 0.000000 5 | small remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 6 | small remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 7 | medium diff: 0.010000 0.000000 0.000000 0.010000 0.000000 8 | medium remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 9 | medium remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 10 | big diff: 0.050000 0.000000 0.000000 0.040000 0.000000 11 | big remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 12 | big remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 13 | add remove 7 times: 0.000000 0.000000 0.000000 0.000000 0.000000 14 | shared: 15 | Name Real [s] User [s] System [s] Child User [s] Child System [s] 16 | table create 100: 0.000000 0.000000 0.000000 0.000000 0.000000 17 | small diff: 0.010000 0.000000 0.000000 0.000000 0.000000 18 | small remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 19 | small remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 20 | medium diff: 0.020000 0.000000 0.000000 0.020000 0.000000 21 | medium remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 22 | medium remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 23 | big diff: 0.050000 0.000000 0.000000 0.030000 0.000000 24 | big remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 25 | big remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 26 | add remove 7 times: 0.000000 0.000000 0.000000 0.000000 0.000000 27 | dynamic: 28 | Name Real [s] User [s] System [s] Child User [s] Child System [s] 29 | table create 100: 0.000000 0.000000 0.000000 0.000000 0.000000 30 | small diff: 0.010000 0.000000 0.000000 0.000000 0.000000 31 | small remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 32 | small remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 33 | medium diff: 0.010000 0.000000 0.000000 0.010000 0.000000 34 | medium remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 35 | medium remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 36 | big diff: 0.050000 0.000000 0.000000 0.040000 0.000000 37 | big remove from array: 0.000000 0.000000 0.000000 0.000000 0.000000 38 | big remove operation from array: 0.000000 0.000000 0.000000 0.000000 0.000000 39 | add remove 7 times: 0.000000 0.000000 0.000000 0.000000 0.000000 40 | 41 | Czasy zaobserwowane sa bardzo male dlatego ciezko wyciagnac jakiekolwiek wnioski, jedynie mozna zauwazyc ze operacja diff 42 | zajmuje "jakikolwiek" czas, mysle ze jest to spowodowane wykonywaniem tej operacji przez system a nie przez samo C -------------------------------------------------------------------------------- /lab4/README.md: -------------------------------------------------------------------------------- 1 | ## Zadanie 1 (10%) 2 | 3 | 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. 4 | 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). 5 | ## Zadanie 2 (30%) 6 | 7 | Napisz program demonstrujący, czy ustawienia dyspozycji dla sygnałów są dziedziczone po wykonaniu funkcji fork oraz exec. 8 | W szczególności eksperymenty proszę wykonać dla sygnału SIGUSR1 w następujący sposób: 9 | 10 | * 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). 11 | * 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. 12 | * Przygotuj plik raport2.txt w którym nastąpi podsumowanie z wnioskami z wykonanych powyższych eksperymentów 13 | 14 | ## Zadanie 3 (15%) 15 | 16 | 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. 17 | ## Zadanie 4 (45%) 18 | 19 | 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. 20 | 21 | 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. 22 | 23 | UWAGA! W żaden sposób nie opóźniamy wysyłania sygnałów, wszelkie "gubienie" sygnałów jest zjawiskiem naturalnym. 24 | 25 | a) Wysyłanie sygnałów w obu programach należy wykonać w następujących trybach: (30%) 26 | 27 | * KILL - za pomocą funkcji kill 28 | * 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. 29 | * 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? 30 | 31 | 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%) 32 | -------------------------------------------------------------------------------- /lab3/zad2/matrix_helper.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #define MAX_COLS_NUMBER 1000 3 | #define MAX_LINE_LENGTH (MAX_COLS_NUMBER * 5) 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | typedef struct 15 | { 16 | int **values; 17 | int rows; 18 | int cols; 19 | } matrix; 20 | 21 | int get_cols_number(char *row) 22 | { 23 | int cols = 0; 24 | char *num = strtok(row, " "); 25 | while (num != NULL) 26 | { 27 | if (strcmp(num, "\n") != 0) 28 | cols++; 29 | num = strtok(NULL, " "); 30 | } 31 | return cols; 32 | } 33 | 34 | void set_cols_and_rows(FILE *f, int *rows, int *cols) 35 | { 36 | char line[MAX_LINE_LENGTH]; 37 | *rows = 0; 38 | *cols = 0; 39 | while (fgets(line, MAX_LINE_LENGTH, f) != NULL) 40 | { 41 | if (*cols == 0) 42 | { 43 | *cols = get_cols_number(line); 44 | } 45 | *rows = *rows + 1; 46 | } 47 | fseek(f, 0, SEEK_SET); 48 | } 49 | 50 | matrix load_matrix(char *filename) 51 | { 52 | FILE *file = fopen(filename, "r"); 53 | int rows, cols; 54 | set_cols_and_rows(file, &rows, &cols); 55 | int **values = calloc(rows, sizeof(int *)); 56 | for (int i = 0; i < rows; i++) 57 | { 58 | values[i] = calloc(cols, sizeof(int)); 59 | } 60 | int x, y = 0; 61 | char line[MAX_LINE_LENGTH]; 62 | while (fgets(line, MAX_LINE_LENGTH, file) != NULL) 63 | { 64 | x = 0; 65 | char *number = strtok(line, " \t\n"); 66 | 67 | while (number != NULL) 68 | { 69 | values[y][x++] = atoi(number); 70 | number = strtok(NULL, " \t\n"); 71 | } 72 | y++; 73 | } 74 | 75 | fclose(file); 76 | matrix m; 77 | m.values = values; 78 | m.rows = rows; 79 | m.cols = cols; 80 | return m; 81 | } 82 | 83 | void free_matrix(matrix *m) 84 | { 85 | for (int y = 0; y < m->rows; y++) 86 | { 87 | free(m->values[y]); 88 | } 89 | free(m->values); 90 | } 91 | 92 | void print_matrix(matrix m) 93 | { 94 | for (int i = 0; i < m.rows; i++) 95 | { 96 | for (int j = 0; j < m.cols; j++) 97 | { 98 | printf("%d ", m.values[i][j]); 99 | } 100 | printf("\n"); 101 | } 102 | } 103 | 104 | matrix multiply_matrices(matrix A, matrix B) 105 | { 106 | int **values = calloc(A.rows, sizeof(int *)); 107 | for (int i = 0; i < A.rows; i++) 108 | { 109 | values[i] = calloc(B.cols, sizeof(int)); 110 | } 111 | for (int i = 0; i < A.rows; i++) 112 | { 113 | for (int j = 0; j < B.cols; j++) 114 | { 115 | int result = 0; 116 | for (int k = 0; k < A.cols; k++) 117 | { 118 | result += (A.values[i][k] * B.values[k][j]); 119 | } 120 | values[i][j] = result; 121 | } 122 | } 123 | 124 | matrix m; 125 | m.values = values; 126 | m.rows = A.rows; 127 | m.cols = B.cols; 128 | 129 | return m; 130 | } 131 | 132 | void generate_matrix(int rows, int cols, char *filename) 133 | { 134 | FILE *file = fopen(filename, "w+"); 135 | 136 | for (int y = 0; y < rows; y++) 137 | { 138 | for (int x = 0; x < cols; x++) 139 | { 140 | if (x > 0) 141 | { 142 | fprintf(file, " "); 143 | } 144 | 145 | fprintf(file, "%d", rand() % (200 + 1) - 100); 146 | }; 147 | fprintf(file, "\n"); 148 | } 149 | fclose(file); 150 | } 151 | 152 | void init_free_matrix(int rows, int cols, char *filename) 153 | { 154 | FILE *file = fopen(filename, "w+"); 155 | 156 | for (int y = 0; y < rows; y++) 157 | { 158 | for (int x = 0; x < cols; x++) 159 | { 160 | if (x > 0) 161 | { 162 | fprintf(file, " "); 163 | } 164 | 165 | fprintf(file, "%d", 0); 166 | }; 167 | fprintf(file, "\n"); 168 | } 169 | fclose(file); 170 | } 171 | 172 | void write_matrix_to_file(FILE *file, matrix a) 173 | { 174 | fseek(file, 0, SEEK_SET); 175 | for (int y = 0; y < a.rows; y++) 176 | { 177 | for (int x = 0; x < a.cols; x++) 178 | { 179 | if (x > 0) 180 | { 181 | fprintf(file, " "); 182 | } 183 | fprintf(file, "%d", a.values[y][x]); 184 | }; 185 | fprintf(file, "\n"); 186 | } 187 | } -------------------------------------------------------------------------------- /lab3/zad3/matrix_helper.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | #define MAX_COLS_NUMBER 1000 3 | #define MAX_LINE_LENGTH (MAX_COLS_NUMBER * 5) 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | typedef struct 15 | { 16 | int **values; 17 | int rows; 18 | int cols; 19 | } matrix; 20 | 21 | int get_cols_number(char *row) 22 | { 23 | int cols = 0; 24 | char *num = strtok(row, " "); 25 | while (num != NULL) 26 | { 27 | if (strcmp(num, "\n") != 0) 28 | cols++; 29 | num = strtok(NULL, " "); 30 | } 31 | return cols; 32 | } 33 | 34 | void set_cols_and_rows(FILE *f, int *rows, int *cols) 35 | { 36 | char line[MAX_LINE_LENGTH]; 37 | *rows = 0; 38 | *cols = 0; 39 | while (fgets(line, MAX_LINE_LENGTH, f) != NULL) 40 | { 41 | if (*cols == 0) 42 | { 43 | *cols = get_cols_number(line); 44 | } 45 | *rows = *rows + 1; 46 | } 47 | fseek(f, 0, SEEK_SET); 48 | } 49 | 50 | matrix load_matrix(char *filename) 51 | { 52 | FILE *file = fopen(filename, "r"); 53 | int rows, cols; 54 | set_cols_and_rows(file, &rows, &cols); 55 | int **values = calloc(rows, sizeof(int *)); 56 | for (int i = 0; i < rows; i++) 57 | { 58 | values[i] = calloc(cols, sizeof(int)); 59 | } 60 | int x, y = 0; 61 | char line[MAX_LINE_LENGTH]; 62 | while (fgets(line, MAX_LINE_LENGTH, file) != NULL) 63 | { 64 | x = 0; 65 | char *number = strtok(line, " \t\n"); 66 | 67 | while (number != NULL) 68 | { 69 | values[y][x++] = atoi(number); 70 | number = strtok(NULL, " \t\n"); 71 | } 72 | y++; 73 | } 74 | 75 | fclose(file); 76 | matrix m; 77 | m.values = values; 78 | m.rows = rows; 79 | m.cols = cols; 80 | return m; 81 | } 82 | 83 | void free_matrix(matrix *m) 84 | { 85 | for (int y = 0; y < m->rows; y++) 86 | { 87 | free(m->values[y]); 88 | } 89 | free(m->values); 90 | } 91 | 92 | void print_matrix(matrix m) 93 | { 94 | for (int i = 0; i < m.rows; i++) 95 | { 96 | for (int j = 0; j < m.cols; j++) 97 | { 98 | printf("%d ", m.values[i][j]); 99 | } 100 | printf("\n"); 101 | } 102 | } 103 | 104 | matrix multiply_matrices(matrix A, matrix B) 105 | { 106 | int **values = calloc(A.rows, sizeof(int *)); 107 | for (int i = 0; i < A.rows; i++) 108 | { 109 | values[i] = calloc(B.cols, sizeof(int)); 110 | } 111 | for (int i = 0; i < A.rows; i++) 112 | { 113 | for (int j = 0; j < B.cols; j++) 114 | { 115 | int result = 0; 116 | for (int k = 0; k < A.cols; k++) 117 | { 118 | result += (A.values[i][k] * B.values[k][j]); 119 | } 120 | values[i][j] = result; 121 | } 122 | } 123 | 124 | matrix m; 125 | m.values = values; 126 | m.rows = A.rows; 127 | m.cols = B.cols; 128 | 129 | return m; 130 | } 131 | 132 | void generate_matrix(int rows, int cols, char *filename) 133 | { 134 | FILE *file = fopen(filename, "w+"); 135 | 136 | for (int y = 0; y < rows; y++) 137 | { 138 | for (int x = 0; x < cols; x++) 139 | { 140 | if (x > 0) 141 | { 142 | fprintf(file, " "); 143 | } 144 | 145 | fprintf(file, "%d", rand() % (200 + 1) - 100); 146 | }; 147 | fprintf(file, "\n"); 148 | } 149 | fclose(file); 150 | } 151 | 152 | void init_free_matrix(int rows, int cols, char *filename) 153 | { 154 | FILE *file = fopen(filename, "w+"); 155 | 156 | for (int y = 0; y < rows; y++) 157 | { 158 | for (int x = 0; x < cols; x++) 159 | { 160 | if (x > 0) 161 | { 162 | fprintf(file, " "); 163 | } 164 | 165 | fprintf(file, "%d", 0); 166 | }; 167 | fprintf(file, "\n"); 168 | } 169 | fclose(file); 170 | } 171 | 172 | void write_matrix_to_file(FILE *file, matrix a) 173 | { 174 | fseek(file, 0, SEEK_SET); 175 | for (int y = 0; y < a.rows; y++) 176 | { 177 | for (int x = 0; x < a.cols; x++) 178 | { 179 | if (x > 0) 180 | { 181 | fprintf(file, " "); 182 | } 183 | fprintf(file, "%d", a.values[y][x]); 184 | }; 185 | fprintf(file, "\n"); 186 | } 187 | } -------------------------------------------------------------------------------- /lab6/README.md: -------------------------------------------------------------------------------- 1 | # Zadania - Zestaw 6 2 | # IPC - kolejki komunikatów 3 | ### Przydatne funkcje: 4 | 5 | System V: 6 | 7 | - msgget, msgctl, msgsnd, msgrcv, ftok 8 | 9 | POSIX: 10 | 11 | - mq_open, mq_send, mq_receive, mq_getattr, mq_setattr, mq_close, mq_unlink, mq_notify 12 | # Zadanie 1. Prosty chat - System V (50%) 13 | Napisz prosty program typu klient-serwer, w którym komunikacja zrealizowana jest za pomocą kolejek komunikatów. 14 | 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. 15 | 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). 16 | 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. 17 | 18 | 19 | ## Rodzaje zleceń 20 | - LIST: 21 | Zlecenie wypisania listy wszystkich aktywnych klientów wraz z informacja czy są dostępni do połączenia. 22 | - CONNECT id_klienta: 23 | 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). 24 | - DISCONNECT: 25 | Zlecenie ustawienia klienta jako dostępnego do połączenia. 26 | - STOP: 27 | 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. 28 | 29 | 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. 30 | 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). 31 | 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). 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 | 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ł. -------------------------------------------------------------------------------- /lab1/zad2/main.c: -------------------------------------------------------------------------------- 1 | #ifdef DYNAMIC 2 | #include "diff_dynamic.h" 3 | #else 4 | #include "library.h" 5 | #endif 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | clock_t st_time, en_time; 16 | struct tms st_cpu, en_cpu; 17 | FILE *report_file; 18 | 19 | void start_timer() 20 | { 21 | st_time = times(&st_cpu); 22 | } 23 | 24 | void end_timer() 25 | { 26 | en_time = times(&en_cpu); 27 | } 28 | 29 | void write_file_header(FILE *f) 30 | { 31 | fprintf(f, "%30s\t\t%15s\t%15s\t%15s\t%15s\t%15s\n", 32 | "Name", 33 | "Real [s]", 34 | "User [s]", 35 | "System [s]", 36 | "Child User [s]", 37 | "Child System [s]"); 38 | } 39 | 40 | void save_timer(char *name, FILE *f) 41 | { 42 | end_timer(); 43 | int clk_tics = sysconf(_SC_CLK_TCK); 44 | double real_time = (double)(en_time - st_time) / clk_tics; 45 | double user_time = (double)(en_cpu.tms_utime - st_cpu.tms_utime) / clk_tics; 46 | double system_time = (double)(en_cpu.tms_stime - st_cpu.tms_stime) / clk_tics; 47 | double child_user_time = (double)(en_cpu.tms_cutime - st_cpu.tms_cutime) / clk_tics; 48 | double child_system_time = (double)(en_cpu.tms_cstime - st_cpu.tms_cstime) / clk_tics; 49 | fprintf(f, "%30s:\t\t%15f\t%15f\t%15f\t%15f\t%15f\t\n", 50 | name, 51 | real_time, 52 | user_time, 53 | system_time, 54 | child_user_time, 55 | child_system_time); 56 | } 57 | int parse_create_table(char *argv[], int i, int argc) 58 | { 59 | if (i + 1 >= argc) 60 | { 61 | fprintf(stderr, "create table wrong number of arguments\n"); 62 | return -1; 63 | } 64 | int size = atoi(argv[i + 1]); 65 | 66 | return create_table(size); 67 | } 68 | int parse_end_timer(char *argv[], int i, int argc) 69 | { 70 | if (i + 1 >= argc) 71 | { 72 | fprintf(stderr, "end timer wrong number of arguments\n"); 73 | return -1; 74 | } 75 | end_timer(); 76 | char *timer_name = argv[i + 1]; 77 | 78 | save_timer(timer_name, report_file); 79 | return 0; 80 | } 81 | 82 | int parse_remove_block(char *argv[], int i, int argc) 83 | { 84 | 85 | if (i + 1 >= argc) 86 | { 87 | fprintf(stderr, "remove block wrong number of arguments\n"); 88 | return -1; 89 | } 90 | int idx = atoi(argv[i + 1]); 91 | return delete_block(idx); 92 | } 93 | int parse_compare_pairs(char *argv[], int i, int argc) 94 | { 95 | if (i + 3 >= argc) 96 | { 97 | fprintf(stderr, "search directory wrong number of arguments\n"); 98 | return -1; 99 | } 100 | char *pairs = argv[i + 1]; 101 | 102 | define_pair_sequence(pairs); 103 | compare_pairs(); 104 | return 1; 105 | } 106 | int parse_remove_operation(char *argv[], int i, int argc) 107 | { 108 | int block_idx = atoi(argv[i + 1]); 109 | int op_idx = atoi(argv[i + 2]); 110 | remove_operation(block_idx, op_idx); 111 | return 1; 112 | } 113 | 114 | int main(int argc, char *argv[]) 115 | { 116 | #ifdef DYNAMIC 117 | init_dynamic_library(); 118 | #endif 119 | 120 | char file_name[] = "raport.txt"; 121 | report_file = fopen(file_name, "a"); 122 | 123 | write_file_header(report_file); 124 | 125 | int i = 1; 126 | while (i < argc) 127 | { 128 | if (!strcmp(argv[i], "create_table")) 129 | { 130 | int err = parse_create_table(argv, i, argc); 131 | if (err < 0) 132 | { 133 | fprintf(stderr, "function create_table returned error, stopping\n"); 134 | return -1; 135 | } 136 | i += 2; 137 | } 138 | else if (!strcmp(argv[i], "compare_pairs")) 139 | { 140 | int err = parse_compare_pairs(argv, i, argc); 141 | if (err < 0) 142 | { 143 | fprintf(stderr, "function search_directory returned error, stopping\n"); 144 | return -1; 145 | } 146 | 147 | i += 2; 148 | } 149 | else if (!strcmp(argv[i], "remove_operation")) 150 | { 151 | int err = parse_remove_operation(argv, i, argc); 152 | if (err < 0) 153 | { 154 | fprintf(stderr, "function load_to_array returned error, stopping\n"); 155 | return -1; 156 | } 157 | i += 3; 158 | } 159 | else if (!strcmp(argv[i], "remove_block")) 160 | { 161 | 162 | int err = parse_remove_block(argv, i, argc); 163 | if (err < 0) 164 | { 165 | fprintf(stderr, "function remove_block returned error, stopping\n"); 166 | return -1; 167 | } 168 | i += 2; 169 | } 170 | else if (!strcmp(argv[i], "tmp_to_array")) 171 | { 172 | tmp_to_array(); 173 | i++; 174 | parse_remove_block(argv, i, argc); 175 | i += 2; 176 | } 177 | else if (!strcmp(argv[i], "start")) 178 | { 179 | start_timer(); 180 | i += 1; 181 | } 182 | else if (!strcmp(argv[i], "end")) 183 | { 184 | parse_end_timer(argv, i, argc); 185 | i += 2; 186 | } 187 | else 188 | { 189 | fprintf(stderr, "Wrong command\n"); 190 | return -1; 191 | } 192 | } 193 | 194 | delete_array(); 195 | 196 | return 0; 197 | } -------------------------------------------------------------------------------- /lab1_v2/zad2/main.c: -------------------------------------------------------------------------------- 1 | #ifdef DYNAMIC 2 | #include "diff_dynamic.h" 3 | #else 4 | #include "lib_diff.h" 5 | #endif 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | clock_t st_time, en_time; 16 | struct tms st_cpu, en_cpu; 17 | FILE *report_file; 18 | 19 | void start_timer() 20 | { 21 | st_time = times(&st_cpu); 22 | } 23 | 24 | void end_timer() 25 | { 26 | en_time = times(&en_cpu); 27 | } 28 | 29 | void write_file_header(FILE *f) 30 | { 31 | fprintf(f, "%30s\t\t%15s\t%15s\t%15s\t%15s\t%15s\n", 32 | "Name", 33 | "Real [s]", 34 | "User [s]", 35 | "System [s]", 36 | "Child User [s]", 37 | "Child System [s]"); 38 | } 39 | 40 | void save_timer(char *name, FILE *f) 41 | { 42 | end_timer(); 43 | int clk_tics = sysconf(_SC_CLK_TCK); 44 | double real_time = (double)(en_time - st_time) / clk_tics; 45 | double user_time = (double)(en_cpu.tms_utime - st_cpu.tms_utime) / clk_tics; 46 | double system_time = (double)(en_cpu.tms_stime - st_cpu.tms_stime) / clk_tics; 47 | double child_user_time = (double)(en_cpu.tms_cutime - st_cpu.tms_cutime) / clk_tics; 48 | double child_system_time = (double)(en_cpu.tms_cstime - st_cpu.tms_cstime) / clk_tics; 49 | fprintf(f, "%30s:\t\t%15f\t%15f\t%15f\t%15f\t%15f\t\n", 50 | name, 51 | real_time, 52 | user_time, 53 | system_time, 54 | child_user_time, 55 | child_system_time); 56 | } 57 | int parse_create_table(char *argv[], int i, int argc) 58 | { 59 | if (i + 1 >= argc) 60 | { 61 | fprintf(stderr, "create table wrong number of arguments\n"); 62 | return -1; 63 | } 64 | int size = atoi(argv[i + 1]); 65 | 66 | return create_table(size); 67 | } 68 | int parse_end_timer(char *argv[], int i, int argc) 69 | { 70 | if (i + 1 >= argc) 71 | { 72 | fprintf(stderr, "end timer wrong number of arguments\n"); 73 | return -1; 74 | } 75 | end_timer(); 76 | char *timer_name = argv[i + 1]; 77 | 78 | save_timer(timer_name, report_file); 79 | return 0; 80 | } 81 | 82 | int parse_remove_block(char *argv[], int i, int argc) 83 | { 84 | 85 | if (i + 1 >= argc) 86 | { 87 | fprintf(stderr, "remove block wrong number of arguments\n"); 88 | return -1; 89 | } 90 | int idx = atoi(argv[i + 1]); 91 | delete_block(idx); 92 | return 1; 93 | } 94 | int parse_compare_pairs(char *argv[], int i, int argc) 95 | { 96 | if (i + 3 >= argc) 97 | { 98 | fprintf(stderr, "search directory wrong number of arguments\n"); 99 | return -1; 100 | } 101 | char *pairs = argv[i + 1]; 102 | 103 | define_pair_sequence(pairs); 104 | compare_pairs(); 105 | return 1; 106 | } 107 | int parse_remove_operation(char *argv[], int i, int argc) 108 | { 109 | int block_idx = atoi(argv[i + 1]); 110 | int op_idx = atoi(argv[i + 2]); 111 | remove_operation(block_idx, op_idx); 112 | return 1; 113 | } 114 | 115 | int main(int argc, char *argv[]) 116 | { 117 | #ifdef DYNAMIC 118 | init_dynamic_library(); 119 | #endif 120 | 121 | char file_name[] = "raport.txt"; 122 | report_file = fopen(file_name, "a"); 123 | 124 | write_file_header(report_file); 125 | 126 | int i = 1; 127 | while (i < argc) 128 | { 129 | if (!strcmp(argv[i], "create_table")) 130 | { 131 | int err = parse_create_table(argv, i, argc); 132 | if (err < 0) 133 | { 134 | fprintf(stderr, "function create_table returned error, stopping\n"); 135 | return -1; 136 | } 137 | i += 2; 138 | } 139 | else if (!strcmp(argv[i], "compare_pairs")) 140 | { 141 | int err = parse_compare_pairs(argv, i, argc); 142 | if (err < 0) 143 | { 144 | fprintf(stderr, "function search_directory returned error, stopping\n"); 145 | return -1; 146 | } 147 | 148 | i += 2; 149 | } 150 | else if (!strcmp(argv[i], "remove_operation")) 151 | { 152 | int err = parse_remove_operation(argv, i, argc); 153 | if (err < 0) 154 | { 155 | fprintf(stderr, "function load_to_array returned error, stopping\n"); 156 | return -1; 157 | } 158 | i += 3; 159 | } 160 | else if (!strcmp(argv[i], "remove_block")) 161 | { 162 | 163 | int err = parse_remove_block(argv, i, argc); 164 | if (err < 0) 165 | { 166 | fprintf(stderr, "function remove_block returned error, stopping\n"); 167 | return -1; 168 | } 169 | i += 2; 170 | } 171 | else if (!strcmp(argv[i], "tmp_to_array")) 172 | { 173 | tmp_to_array(); 174 | i++; 175 | parse_remove_block(argv, i, argc); 176 | i += 2; 177 | } 178 | else if (!strcmp(argv[i], "start")) 179 | { 180 | start_timer(); 181 | i += 1; 182 | } 183 | else if (!strcmp(argv[i], "end")) 184 | { 185 | parse_end_timer(argv, i, argc); 186 | i += 2; 187 | } 188 | else 189 | { 190 | fprintf(stderr, "Wrong command\n"); 191 | return -1; 192 | } 193 | } 194 | 195 | delete_array(); 196 | 197 | return 0; 198 | } -------------------------------------------------------------------------------- /lab1/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 | -------------------------------------------------------------------------------- /lab1_v2/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 | -------------------------------------------------------------------------------- /lab1/zad1/library.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | char **table = NULL; 5 | unsigned int initializated = 0; 6 | unsigned int table_size = 0; 7 | char *tmp_file = NULL; 8 | char *pair_sequence = NULL; 9 | 10 | int create_table(unsigned int size) 11 | { 12 | if (initializated == 1) 13 | { 14 | fprintf(stderr, "already initializated"); 15 | return -1; 16 | } 17 | 18 | table = calloc(size, sizeof(char *)); 19 | table_size = size; 20 | initializated = 1; 21 | tmp_file = "tmp.txt"; 22 | return 0; 23 | } 24 | 25 | int diff_files(char *file1, char *file2) 26 | { 27 | char buf[256]; 28 | snprintf(buf, sizeof buf, "diff %s %s > %s", file1, file2, tmp_file); 29 | int find_status = system(buf); 30 | if (find_status != 0) 31 | return find_status; 32 | 33 | return 0; 34 | } 35 | 36 | int get_file_size(FILE *fp) 37 | { 38 | fseek(fp, 0L, SEEK_END); 39 | int sz = ftell(fp); 40 | rewind(fp); 41 | return sz; 42 | } 43 | 44 | int load_file(char **buffer, char *file_path) 45 | { 46 | FILE *f = fopen(file_path, "rb"); 47 | if (!f) 48 | { 49 | fprintf(stderr, "Problem with reading file"); 50 | return -1; 51 | } 52 | long file_size = get_file_size(f); 53 | *buffer = calloc(file_size, sizeof(char)); 54 | fread(*buffer, sizeof(char), file_size, f); 55 | fclose(f); 56 | return 0; 57 | } 58 | 59 | int file_to_array(char *file_name) 60 | { 61 | for (int i = 0; i < table_size; i++) 62 | { 63 | if (table[i] == NULL) 64 | { 65 | int load_status = load_file(&table[i], file_name); 66 | if (load_status < 0) 67 | { 68 | fprintf(stderr, "can't load into array\n"); 69 | return load_status; 70 | } 71 | return i; 72 | } 73 | } 74 | fprintf(stderr, "can't load into array, array is full\n"); 75 | return -1; 76 | } 77 | 78 | int tmp_to_array() 79 | { 80 | return file_to_array(tmp_file); 81 | } 82 | 83 | char *get_block(int idx) 84 | { 85 | return table[idx]; 86 | } 87 | 88 | int delete_block(int idx) 89 | { 90 | free(table[idx]); 91 | table[idx] = NULL; 92 | return 0; 93 | } 94 | 95 | void delete_array() 96 | { 97 | for (int i = 0; i < table_size; ++i) 98 | { 99 | delete_block(i); 100 | } 101 | free(table); 102 | } 103 | 104 | int get_operations_count(int idx) 105 | { 106 | if (table[idx] == NULL) 107 | { 108 | fprintf(stderr, "table on this index is empty"); 109 | return 0; 110 | } 111 | char *content = get_block(idx); 112 | char *p; 113 | int counter = 0; 114 | p = content; 115 | int flag = 0; 116 | 117 | while (*p != '\0') 118 | { 119 | flag = 1; 120 | if (*p == '\n' && (*(++p) > '0' && *(p) < '9')) 121 | counter++; 122 | p++; 123 | } 124 | int val_to_ret = 0; 125 | if (flag == 1) 126 | val_to_ret = counter + 1; 127 | return val_to_ret; 128 | } 129 | 130 | void remove_operation(int block_idx, int operation_idx) 131 | { 132 | if (table[block_idx] == NULL) 133 | { 134 | fprintf(stderr, "table on this index is empty"); 135 | return; 136 | } 137 | if (get_operations_count(block_idx) == 0) 138 | { 139 | return; 140 | } 141 | char **content = &table[block_idx]; 142 | 143 | char *p = *content; 144 | size_t len = 0; 145 | int counter = 0; 146 | int exist = 0; 147 | char *first = NULL; 148 | 149 | int old_counter = 0; 150 | int chars = 0; 151 | 152 | while (*p != '\0') 153 | { 154 | chars++; 155 | 156 | if (*p == '\n' && (*(++p) > '0' && *(p) < '9')) 157 | { 158 | counter++; 159 | } 160 | 161 | if (counter == operation_idx) 162 | { 163 | 164 | if (exist == 0) 165 | { 166 | exist = 1; 167 | first = p; 168 | } 169 | 170 | len++; 171 | old_counter = counter; 172 | } 173 | 174 | p++; 175 | if (old_counter == counter) 176 | { 177 | if (*p == '\n') 178 | { 179 | len++; 180 | } 181 | } 182 | old_counter = -1; 183 | } 184 | if (counter + 1 <= operation_idx) 185 | { 186 | fprintf(stderr, "Index doesn't exist\n"); 187 | return; 188 | } 189 | 190 | if (get_operations_count(block_idx) == 1) 191 | { 192 | 193 | free(table[block_idx]); 194 | delete_block(block_idx); 195 | 196 | return; 197 | } 198 | 199 | char *new = calloc(strlen(*content) + 1, sizeof(char)); 200 | memcpy(new, *content, first - *content); 201 | char *pointer = new; 202 | while (*pointer != '\0') 203 | { 204 | pointer++; 205 | } 206 | memcpy(pointer, first + len, strlen(first + len)); 207 | delete_block(block_idx); 208 | table[block_idx] = new; 209 | 210 | if (get_operations_count(block_idx) == 0) 211 | { 212 | free(table[block_idx]); 213 | delete_block(block_idx); 214 | } 215 | } 216 | void define_pair_sequence(char *sequence) 217 | { 218 | 219 | pair_sequence = sequence; 220 | } 221 | void compare_pairs() 222 | { 223 | 224 | char *string = strdup(pair_sequence); 225 | 226 | char *token = strtok(string, " "); 227 | while (token != NULL) 228 | { 229 | 230 | char *f1 = token; 231 | token = strtok(NULL, " "); 232 | char *f2 = token; 233 | token = strtok(NULL, " "); 234 | diff_files(f1, f2); 235 | tmp_to_array(); 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /lab2/zad2/find_nftw.c: -------------------------------------------------------------------------------- 1 | 2 | #define _XOPEN_SOURCE 500 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | const char format[] = "%Y-%m-%d %H:%M:%S"; 15 | char follow_mode; 16 | char *command; 17 | time_t follow_date; 18 | int maxdepth; 19 | 20 | void print_from_stat(const char *filename, const struct stat *statptr) 21 | { 22 | char file_type[64] = "undefined"; 23 | 24 | if (S_ISREG(statptr->st_mode)) 25 | strcpy(file_type, "file"); 26 | else if (S_ISDIR(statptr->st_mode)) 27 | strcpy(file_type, "dir"); 28 | else if (S_ISLNK(statptr->st_mode)) 29 | strcpy(file_type, "slink"); 30 | else if (S_ISCHR(statptr->st_mode)) 31 | strcpy(file_type, "char dev"); 32 | else if (S_ISBLK(statptr->st_mode)) 33 | strcpy(file_type, "block dev"); 34 | else if (S_ISFIFO(statptr->st_mode)) 35 | strcpy(file_type, "fifo"); 36 | else if (S_ISSOCK(statptr->st_mode)) 37 | strcpy(file_type, "socket"); 38 | 39 | struct tm tm_modif_time; 40 | localtime_r(&statptr->st_mtime, &tm_modif_time); 41 | char modif_time_str[255]; 42 | strftime(modif_time_str, 255, format, &tm_modif_time); 43 | 44 | struct tm tm_access_time; 45 | localtime_r(&statptr->st_atime, &tm_access_time); 46 | char access_time_str[255]; 47 | strftime(access_time_str, 255, format, &tm_access_time); 48 | 49 | printf("%s || type: %s, size: %ld, modification time: %s, access time: %s\n", 50 | filename, file_type, statptr->st_size, modif_time_str, access_time_str); 51 | } 52 | 53 | int file_info(const char *filename, const struct stat *statptr, 54 | int fileflags, struct FTW *pfwt) 55 | { 56 | 57 | if (maxdepth != -1 && pfwt->level > maxdepth) 58 | { 59 | 60 | return 0; 61 | } 62 | if (strcmp(command, "maxdepth") == 0) 63 | { 64 | print_from_stat(filename, statptr); 65 | 66 | return 0; 67 | } 68 | else if (strcmp(command, "mtime") == 0) 69 | { 70 | 71 | time_t modif_time = statptr->st_mtime; 72 | 73 | if (follow_mode == '-') 74 | { 75 | int diff_modif = difftime(follow_date, modif_time); 76 | if (!((diff_modif == 0 && follow_mode == '=') || (diff_modif > 0 && follow_mode == '+') || (diff_modif < 0 && follow_mode == '-'))) 77 | return 0; 78 | ; 79 | 80 | print_from_stat(filename, statptr); 81 | } 82 | else if (follow_mode == '+') 83 | { 84 | int diff_modif = difftime(follow_date, modif_time); 85 | if (!((diff_modif == 0 && follow_mode == '=') || (diff_modif > 0 && follow_mode == '+') || (diff_modif < 0 && follow_mode == '-'))) 86 | return 0; 87 | 88 | print_from_stat(filename, statptr); 89 | } 90 | else if (follow_mode == '=') 91 | { 92 | 93 | int diff_modif = abs(difftime(modif_time, follow_date)) / (60 * 60 * 24); 94 | int diff_modif2 = difftime(follow_date, modif_time); 95 | 96 | if ((diff_modif == 0 && follow_mode == '=') && !(diff_modif2 < 0 && follow_mode == '=')) 97 | print_from_stat(filename, statptr); 98 | return 0; 99 | } 100 | } 101 | else if (strcmp(command, "atime") == 0) 102 | { 103 | time_t modif_time = statptr->st_atime; 104 | 105 | if (follow_mode == '-') 106 | { 107 | int diff_modif = difftime(follow_date, modif_time); 108 | if (!((diff_modif == 0 && follow_mode == '=') || (diff_modif > 0 && follow_mode == '+') || (diff_modif < 0 && follow_mode == '-'))) 109 | return 0; 110 | ; 111 | 112 | print_from_stat(filename, statptr); 113 | } 114 | else if (follow_mode == '+') 115 | { 116 | int diff_modif = difftime(follow_date, modif_time); 117 | if (!((diff_modif == 0 && follow_mode == '=') || (diff_modif > 0 && follow_mode == '+') || (diff_modif < 0 && follow_mode == '-'))) 118 | return 0; 119 | 120 | print_from_stat(filename, statptr); 121 | } 122 | else if (follow_mode == '=') 123 | { 124 | 125 | int diff_modif = abs(difftime(modif_time, follow_date)) / (60 * 60 * 24); 126 | int diff_modif2 = difftime(follow_date, modif_time); 127 | 128 | if ((diff_modif == 0 && follow_mode == '=') && !(diff_modif2 < 0 && follow_mode == '=')) 129 | print_from_stat(filename, statptr); 130 | return 0; 131 | } 132 | } 133 | return 0; 134 | } 135 | 136 | void print_files_handler(char *root_path, char *comm, char mode, int count, int maxdep) 137 | { 138 | 139 | int flags = FTW_PHYS; 140 | int fd_limit = 2; 141 | follow_mode = mode; 142 | command = comm; 143 | maxdepth = maxdep; 144 | 145 | time_t rawtime; 146 | struct tm *timeinfo; 147 | 148 | time(&rawtime); 149 | timeinfo = localtime(&rawtime); 150 | timeinfo->tm_mday -= count; 151 | if (mode == '+') 152 | { 153 | timeinfo->tm_mday -= 1; 154 | } 155 | follow_date = mktime(timeinfo); 156 | 157 | nftw(root_path, 158 | file_info, 159 | fd_limit, flags); 160 | } 161 | 162 | int main(int argc, char *argv[]) 163 | { 164 | 165 | if (argc != 6) 166 | { 167 | fprintf(stderr, "wrong arguments\n"); 168 | exit(-1); 169 | } 170 | char *dir = argv[1]; 171 | char *comman = argv[2]; 172 | char *mod = argv[3]; 173 | int day = atoi(argv[4]); 174 | int mdep = atoi(argv[5]); 175 | 176 | print_files_handler(dir, comman, mod[0], day, mdep); 177 | 178 | return 0; 179 | } -------------------------------------------------------------------------------- /lab6/zad2/server.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include 3 | #define MAX_CLIENTS 32 4 | Client *clients[MAX_CLIENTS]; 5 | 6 | int server_queue = -1; 7 | int clients_connected = 0; 8 | int waiting = 0; 9 | int current = 0; 10 | 11 | void on_exit_server() 12 | { 13 | printf("Server exits...\n"); 14 | close_queue(server_queue); 15 | delete_queue(SERVER_NAME); 16 | 17 | exit(EXIT_SUCCESS); 18 | } 19 | 20 | void handle_sigint(int signal) 21 | { 22 | char msg[MAX_MESSAGE_SIZE]; 23 | sprintf(msg, "%d", SERVER_CLIENT_TERMINATE); 24 | 25 | if (clients_connected <= 0) 26 | on_exit_server(); 27 | 28 | waiting = 1; 29 | for (int i = 0; i < MAX_CLIENTS; i++) 30 | { 31 | if (clients[i]) 32 | { 33 | send_message(clients[i]->queue, msg, SERVER_CLIENT_TERMINATE); 34 | } 35 | } 36 | 37 | printf("Server is waiting for clients to terminate. Press Ctrl + C on each client side\n"); 38 | } 39 | 40 | void handle_stop(char *msg) 41 | { 42 | int type, id; 43 | sscanf(msg, "%d %d", &type, &id); 44 | 45 | clients[id] = NULL; 46 | free(clients[id]); 47 | 48 | clients_connected -= 1; 49 | printf("Server -- Received STOP from %d\n", id); 50 | 51 | if (waiting && clients_connected <= 0) 52 | { 53 | on_exit_server(); 54 | } 55 | } 56 | 57 | void handle_disconnect(char *msg) 58 | { 59 | int type, id; 60 | sscanf(msg, "%d %d", &type, &id); 61 | 62 | clients[id]->available = 1; 63 | printf("Server -- client with id %d left chat\n", 64 | id); 65 | } 66 | 67 | void handle_list(char *msg) 68 | { 69 | int type, id; 70 | sscanf(msg, "%d %d", &type, &id); 71 | 72 | printf("Server -- listing clients \n"); 73 | for (int i = 0; i < MAX_CLIENTS; i++) 74 | { 75 | if (i == id) 76 | { 77 | printf("\tClient --> id - %d (ME)\n", clients[i]->id); 78 | } 79 | else if (clients[i] && clients[i]->available) 80 | { 81 | printf("\tClient --> id - %d is available\n", clients[i]->id); 82 | } 83 | else if (clients[i] && !clients[i]->available) 84 | { 85 | printf("\tClient --> id - %d isn't available\n", clients[i]->id); 86 | } 87 | } 88 | } 89 | 90 | void handle_connect(char *msg) 91 | { 92 | int type, id, chateeId; 93 | sscanf(msg, "%d %d %d", &type, &id, &chateeId); 94 | 95 | int id1 = id; 96 | int id2 = chateeId; 97 | 98 | if (id2 < 0 || id2 >= MAX_CLIENTS || !clients[id2] || 99 | !clients[id2]->available || id1 == id2) 100 | { 101 | printf("Server -- client is not avaiable\n"); 102 | return; 103 | } 104 | char msg1[MAX_MESSAGE_SIZE]; 105 | char msg2[MAX_MESSAGE_SIZE]; 106 | 107 | sprintf(msg1, "%d %d %s", SERVER_CLIENT_CHAT_INIT, id2, clients[id2]->name); 108 | sprintf(msg2, "%d %d %s", SERVER_CLIENT_CHAT_INIT, id1, clients[id1]->name); 109 | 110 | clients[id1]->available = 0; 111 | clients[id2]->available = 0; 112 | 113 | send_message(clients[id1]->queue, msg1, SERVER_CLIENT_CHAT_INIT); 114 | send_message(clients[id2]->queue, msg2, SERVER_CLIENT_CHAT_INIT); 115 | 116 | printf("Server -- initialized chat between %d and %d\n", id1, id2); 117 | } 118 | 119 | void handle_init(char *msg) 120 | { 121 | int type; 122 | char *name = malloc(MAX_MESSAGE_SIZE * sizeof(char)); 123 | sscanf(msg, "%d %s", &type, name); 124 | 125 | int pointer = -1; 126 | for (int i = 0; i < MAX_CLIENTS; i++) 127 | { 128 | pointer = (current + i) % MAX_CLIENTS; 129 | if (!clients[pointer]) 130 | { 131 | break; 132 | } 133 | } 134 | 135 | if (pointer == -1) 136 | { 137 | printf("Server is full, cannot add another client.\n"); 138 | } 139 | else 140 | { 141 | Client *client = malloc(sizeof(Client)); 142 | client->available = 1; 143 | client->name = name; 144 | client->id = pointer; 145 | client->queue = get_queue(name); 146 | 147 | if (client->queue == -1) 148 | { 149 | printError(); 150 | printf("Failed to open client's queue\n"); 151 | } 152 | 153 | clients[pointer] = client; 154 | 155 | char scMsg[MAX_MESSAGE_SIZE]; 156 | sprintf(scMsg, "%d %d", SERVER_CLIENT_REGISTRED, pointer); 157 | 158 | send_message(client->queue, scMsg, SERVER_CLIENT_REGISTRED); 159 | clients_connected += 1; 160 | printf("Server -- registered client - id: %d, queue_name: %s\n", client->id, 161 | client->name); 162 | } 163 | } 164 | 165 | void handle_message() 166 | { 167 | char *msg = malloc(sizeof(char) * MAX_MESSAGE_SIZE); 168 | unsigned int type; 169 | receive_message(server_queue, msg, &type); 170 | 171 | if (type == CLIENT_SERVER_STOP) 172 | { 173 | handle_stop(msg); 174 | } 175 | else if (type == CLIENT_SERVER_DISCONNECT) 176 | { 177 | handle_disconnect(msg); 178 | } 179 | else if (type == CLIENT_SERVER_LIST) 180 | { 181 | handle_list(msg); 182 | } 183 | else if (type == CLIENT_SERVER_CONNECT) 184 | { 185 | handle_connect(msg); 186 | } 187 | else if (type == CLIENT_SERVER_INIT) 188 | { 189 | handle_init(msg); 190 | } 191 | else 192 | { 193 | printf("Unknown type\n"); 194 | } 195 | 196 | free(msg); 197 | } 198 | 199 | int main(int argc, char *arrgv[]) 200 | { 201 | server_queue = create_queue(SERVER_NAME); 202 | if (server_queue == -1) 203 | { 204 | printf("Failed to open\n"); 205 | printError(); 206 | } 207 | signal(SIGINT, handle_sigint); 208 | 209 | printf("Server running...\n"); 210 | while (1) 211 | { 212 | handle_message(); 213 | } 214 | 215 | return 0; 216 | } -------------------------------------------------------------------------------- /lab6/zad1/client.c: -------------------------------------------------------------------------------- 1 | #define _XOPEN_SOURCE 500 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "keygen.h" 13 | #include "message.h" 14 | #include "types.h" 15 | #include "que.h" 16 | #include "utils.h" 17 | 18 | int server_queue, private_queue; 19 | int friend_queue = -1; 20 | int id; 21 | 22 | void send_to_server(message_t *message) 23 | { 24 | if (send(server_queue, message)) 25 | { 26 | perror("unable to send message to server"); 27 | } 28 | } 29 | void send_to_friend(message_t *message) 30 | { 31 | if (send(friend_queue, message) == -1) 32 | { 33 | perror("unable to send message to friend"); 34 | } 35 | } 36 | void clean() 37 | { 38 | message_t message; 39 | message.type = TYPE_STOP; 40 | message.id = id; 41 | 42 | send_to_server(&message); 43 | close_queue(server_queue); 44 | delete_queue(private_queue, get_private_key()); 45 | if (friend_queue != -1) 46 | { 47 | message_t message; 48 | message.type = TYPE_DISCONNECT; 49 | message.id = id; 50 | send_to_friend(&message); 51 | } 52 | } 53 | 54 | void handle_sigint(int sig) 55 | { 56 | exit(0); 57 | } 58 | 59 | void hanlde_stop() 60 | { 61 | kill(getpid(), SIGINT); 62 | } 63 | 64 | void handle_list() 65 | { 66 | message_t message; 67 | message.type = TYPE_LIST; 68 | message.id = id; 69 | send_to_server(&message); 70 | } 71 | 72 | void handle_disconnect() 73 | { 74 | 75 | message_t message; 76 | message.type = TYPE_DISCONNECT; 77 | message.id = id; 78 | send_to_friend(&message); 79 | friend_queue = -1; 80 | printf("DISCONNECTED"); 81 | send_to_server(&message); 82 | } 83 | void handle_connect(int connect_id) 84 | { 85 | printf("Client %d wants to connect %d\n", id, connect_id); 86 | message_t message; 87 | message.type = TYPE_CONNECT; 88 | message.id = id; 89 | sprintf(message.text, "%d", connect_id); 90 | send_to_server(&message); 91 | } 92 | void handle_message_send(char *mess) 93 | { 94 | message_t message; 95 | message.type = TYPE_MESSAGE; 96 | message.id = id; 97 | sprintf(message.text, "%s", mess); 98 | send_to_friend(&message); 99 | printf("_________\n"); 100 | printf("M: %s\n", mess); 101 | printf("_________\n"); 102 | } 103 | 104 | void sender_handle_line(char *command, char *rest) 105 | { 106 | 107 | if (strcmp("STOP", command) == 0) 108 | { 109 | hanlde_stop(); 110 | } 111 | else if (strcmp("LIST", command) == 0) 112 | { 113 | handle_list(); 114 | } 115 | else if (strcmp("CONNECT", command) == 0) 116 | { 117 | handle_connect(atoi(rest)); 118 | } 119 | else if (strcmp("MESSAGE", command) == 0) 120 | { 121 | handle_message_send(rest); 122 | } 123 | else if (strcmp("DISCONNECT", command) == 0) 124 | { 125 | handle_disconnect(); 126 | } 127 | } 128 | 129 | void initialize() 130 | { 131 | if ((server_queue = get_queue(get_public_key())) == -1) 132 | { 133 | perror("cant open server queue"); 134 | exit(1); 135 | } 136 | 137 | key_t private_key = get_private_key(); 138 | if ((private_queue = create_queue(private_key)) == -1) 139 | { 140 | perror("cant create private queue"); 141 | exit(1); 142 | } 143 | 144 | message_t message; 145 | message.type = TYPE_INIT; 146 | sprintf(message.text, "%d", private_key); 147 | message.pid = getpid(); 148 | 149 | if (send(server_queue, &message) == -1) 150 | { 151 | perror("unable to register"); 152 | exit(1); 153 | } 154 | 155 | if (receive(private_queue, &message) == -1) 156 | { 157 | perror("unable to register"); 158 | exit(1); 159 | } 160 | 161 | id = message.id; 162 | printf("successfully registered with id %d\n", id); 163 | } 164 | 165 | void sender() 166 | { 167 | char line[256]; 168 | char command[256]; 169 | char rest[256]; 170 | 171 | fgets(line, 1024, stdin); 172 | separate_command(line, command, rest); 173 | sender_handle_line(command, rest); 174 | } 175 | 176 | void handle_connect_from_server(message_t *message) 177 | { 178 | 179 | int friend; 180 | sscanf(message->text, "%d", &friend); 181 | if (friend != -1) 182 | { 183 | friend_queue = friend; 184 | printf("CONENCT with %d\n", friend_queue); 185 | printf("_____WELCOME IN CHAT_____\n"); 186 | return; 187 | } 188 | printf("CAN'T CONENCT with\n"); 189 | } 190 | void handle_message(message_t *message) 191 | { 192 | printf("_________\n"); 193 | char mess[256]; 194 | sprintf(mess, "%s", message->text); 195 | printf("F: %s\n", mess); 196 | printf("_________\n"); 197 | } 198 | 199 | void handle_disconnect_from_server(message_t *message) 200 | { 201 | friend_queue = -1; 202 | printf("DISCONNECTED"); 203 | } 204 | 205 | void catcher() 206 | { 207 | 208 | signal(SIGINT, handle_sigint); 209 | 210 | while (!is_empty(private_queue)) 211 | { 212 | message_t message; 213 | 214 | if (receive_no_wait(private_queue, &message) != -1) 215 | { 216 | 217 | switch (message.type) 218 | { 219 | case TYPE_STOP: 220 | printf("exiting\n"); 221 | exit(0); 222 | break; 223 | case TYPE_CONNECT: 224 | handle_connect_from_server(&message); 225 | break; 226 | case TYPE_MESSAGE: 227 | handle_message(&message); 228 | break; 229 | case TYPE_DISCONNECT: 230 | handle_disconnect_from_server(&message); 231 | break; 232 | default: 233 | break; 234 | } 235 | } 236 | } 237 | } 238 | 239 | int main(int argc, char *argv[]) 240 | { 241 | atexit(clean); 242 | signal(SOMETHING_HAPPEND, catcher); 243 | signal(SIGINT, handle_sigint); 244 | initialize(); 245 | struct sigaction sa; 246 | sigemptyset(&sa.sa_mask); 247 | sa.sa_flags = 0; 248 | sa.sa_handler = catcher; 249 | sigaction(SOMETHING_HAPPEND, &sa, NULL); 250 | while (1) 251 | { 252 | 253 | sender(); 254 | catcher(); 255 | } 256 | 257 | return 0; 258 | } --------------------------------------------------------------------------------