├── include ├── minitalk.h └── minitalk_bonus.h ├── printf ├── Makefile ├── ft_printf_ptr.c ├── ft_printf_number_hex.c ├── ft_printf.h ├── ft_printf_unsigned_int.c ├── ft_printf_int_decimal.c └── ft_printf.c ├── src ├── server.c ├── server_bonus.c ├── client.c └── client_bonus.c ├── Makefile └── README.md /include/minitalk.h: -------------------------------------------------------------------------------- 1 | #ifndef MINITALK_H 2 | # define MINITALK_H 3 | 4 | # include "../printf/ft_printf.h" 5 | # include 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /include/minitalk_bonus.h: -------------------------------------------------------------------------------- 1 | #ifndef MINITALK_BONUS_H 2 | # define MINITALK_BONUS_H 3 | 4 | # include "../printf/ft_printf.h" 5 | # include 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /printf/Makefile: -------------------------------------------------------------------------------- 1 | SRCS = ft_printf.c ft_printf_number_hex.c\ 2 | ft_printf_ptr.c ft_printf_unsigned_int.c \ 3 | ft_printf_int_decimal.c 4 | 5 | OBJS = ${SRCS:.c=.o} 6 | NAME = libftprintf.a 7 | LIBC = ar rcs 8 | CC = cc 9 | RM = rm -f 10 | CFLAGS = -Wall -Wextra -Werror 11 | 12 | ${NAME}: ${OBJS} 13 | @${LIBC} ${NAME} ${OBJS} 14 | 15 | all: ${NAME} 16 | 17 | clean: 18 | @${RM} ${OBJS} 19 | 20 | fclean: clean 21 | @${RM} ${NAME} 22 | 23 | re: fclean all 24 | 25 | .PHONY : all clean fclean re 26 | -------------------------------------------------------------------------------- /src/server.c: -------------------------------------------------------------------------------- 1 | #include "../include/minitalk.h" 2 | 3 | void ft_btoa(int sig) 4 | { 5 | static int bit; 6 | static int i; 7 | 8 | if (sig == SIGUSR1) 9 | i |= (0x01 << bit); 10 | bit++; 11 | if (bit == 8) 12 | { 13 | ft_printf("%c", i); 14 | bit = 0; 15 | i = 0; 16 | } 17 | } 18 | 19 | int main(int argc, char **argv) 20 | { 21 | int pid; 22 | 23 | (void)argv; 24 | if (argc != 1) 25 | { 26 | ft_printf("Error\n"); 27 | return (1); 28 | } 29 | pid = getpid(); 30 | ft_printf("%d\n", pid); 31 | while (argc == 1) 32 | { 33 | signal(SIGUSR1, ft_btoa); 34 | signal(SIGUSR2, ft_btoa); 35 | pause (); 36 | } 37 | return (0); 38 | } 39 | -------------------------------------------------------------------------------- /printf/ft_printf_ptr.c: -------------------------------------------------------------------------------- 1 | #include "ft_printf.h" 2 | 3 | int len_ptr(uintptr_t nb) 4 | { 5 | int len; 6 | 7 | len = 0; 8 | while (nb != 0) 9 | { 10 | len++; 11 | nb = nb / 16; 12 | } 13 | return (len); 14 | } 15 | 16 | void ft_put_ptr(uintptr_t nb) 17 | { 18 | if (nb >= 16) 19 | { 20 | ft_put_ptr(nb / 16); 21 | ft_put_ptr(nb % 16); 22 | } 23 | else 24 | { 25 | if (nb <= 9) 26 | ft_putchar((nb + '0')); 27 | else 28 | ft_putchar((nb - 10 + 'a')); 29 | } 30 | } 31 | 32 | int ft_putptr(uintptr_t ptr) 33 | { 34 | int char_printed; 35 | 36 | char_printed = 0; 37 | char_printed += write(1, "0x", 2); 38 | if (ptr == 0) 39 | char_printed += write(1, "0", 1); 40 | else 41 | { 42 | ft_put_ptr(ptr); 43 | char_printed += len_ptr(ptr); 44 | } 45 | return (char_printed); 46 | } 47 | -------------------------------------------------------------------------------- /printf/ft_printf_number_hex.c: -------------------------------------------------------------------------------- 1 | #include "ft_printf.h" 2 | 3 | int hex_len(unsigned int num) 4 | { 5 | int len; 6 | 7 | len = 0; 8 | while (num != 0) 9 | { 10 | len ++; 11 | num = num / 16; 12 | } 13 | return (len); 14 | } 15 | 16 | void ft_put_hex(unsigned int num, const char format) 17 | { 18 | if (num >= 16) 19 | { 20 | ft_put_hex(num / 16, format); 21 | ft_put_hex(num % 16, format); 22 | } 23 | else 24 | { 25 | if (num <= 9) 26 | ft_putchar((num + '0')); 27 | else 28 | { 29 | if (format == 'x') 30 | ft_putchar((num - 10 + 'a')); 31 | if (format == 'X') 32 | ft_putchar((num - 10 + 'A')); 33 | } 34 | } 35 | } 36 | 37 | int ft_puthex(unsigned int num, const char format) 38 | { 39 | if (num == 0) 40 | return (write(1, "0", 1)); 41 | else 42 | ft_put_hex(num, format); 43 | return (hex_len(num)); 44 | } 45 | -------------------------------------------------------------------------------- /printf/ft_printf.h: -------------------------------------------------------------------------------- 1 | #ifndef FT_PRINTF_H 2 | # define FT_PRINTF_H 3 | # define FT_PRINTF_H 4 | # include 5 | # include 6 | # include 7 | 8 | void ft_put_hex(unsigned int num, const char format); 9 | void ft_put_ptr(uintptr_t nb); 10 | int ft_len(int n); 11 | int hex_len(unsigned int num); 12 | int len_ptr(uintptr_t nb); 13 | int ft_unsigned_len(unsigned int nb); 14 | int ft_putchar(int c); 15 | int ft_putstr(char *str); 16 | int ft_putnbr(int n); 17 | int ft_puthex(unsigned int num, const char format); 18 | int ft_putptr(uintptr_t ptr); 19 | int ft_putunsigned(unsigned int nb); 20 | int ft_conversion(va_list vl, const char format); 21 | int ft_printf(const char *format, ...); 22 | char *ft_char(char *s, unsigned int number, int len); 23 | char *ft_itoa(int n); 24 | char *ft_uitoa(unsigned int nb); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/server_bonus.c: -------------------------------------------------------------------------------- 1 | #include "../include/minitalk_bonus.h" 2 | 3 | void ft_btoa(int sig, siginfo_t *info, void *context) 4 | { 5 | static int bit; 6 | static int i; 7 | 8 | (void)context; 9 | if (sig == SIGUSR1) 10 | i |= (0x01 << bit); 11 | bit++; 12 | if (bit == 8) 13 | { 14 | if (i == 0) 15 | kill(info->si_pid, SIGUSR2); 16 | ft_printf("%c", i); 17 | bit = 0; 18 | i = 0; 19 | } 20 | } 21 | 22 | int main(int argc, char **argv) 23 | { 24 | int pid; 25 | struct sigaction act; 26 | 27 | (void)argv; 28 | if (argc != 1) 29 | { 30 | ft_printf("Error\n"); 31 | return (1); 32 | } 33 | pid = getpid(); 34 | ft_printf("%d\n", pid); 35 | act.sa_sigaction = ft_btoa; 36 | sigemptyset(&act.sa_mask); 37 | act.sa_flags = 0; 38 | while (argc == 1) 39 | { 40 | sigaction(SIGUSR1, &act, NULL); 41 | sigaction(SIGUSR2, &act, NULL); 42 | pause(); 43 | } 44 | return (0); 45 | } 46 | -------------------------------------------------------------------------------- /printf/ft_printf_unsigned_int.c: -------------------------------------------------------------------------------- 1 | #include "ft_printf.h" 2 | 3 | int ft_unsigned_len(unsigned int nb) 4 | { 5 | int len; 6 | 7 | len = 0; 8 | while (nb != 0) 9 | { 10 | len++; 11 | nb = nb / 10; 12 | } 13 | return (len); 14 | } 15 | 16 | char *ft_uitoa(unsigned int nb) 17 | { 18 | char *str; 19 | int len; 20 | 21 | len = ft_unsigned_len(nb); 22 | str = (char *)malloc(sizeof(char) * (len + 1)); 23 | if (!str) 24 | return (0); 25 | str[len] = '\0'; 26 | while (nb != 0) 27 | { 28 | str[len - 1] = nb % 10 + 48; 29 | nb = nb / 10; 30 | len--; 31 | } 32 | return (str); 33 | } 34 | 35 | int ft_putunsigned(unsigned int nb) 36 | { 37 | int char_printed; 38 | char *str; 39 | 40 | char_printed = 0; 41 | if (nb == 0) 42 | char_printed += write(1, "0", 1); 43 | else 44 | { 45 | str = ft_uitoa(nb); 46 | char_printed += ft_putstr(str); 47 | free(str); 48 | } 49 | return (char_printed); 50 | } 51 | -------------------------------------------------------------------------------- /printf/ft_printf_int_decimal.c: -------------------------------------------------------------------------------- 1 | #include "ft_printf.h" 2 | 3 | char *ft_char(char *s, unsigned int number, int len) 4 | { 5 | while (number > 0) 6 | { 7 | s[len--] = 48 + (number % 10); 8 | number = number / 10; 9 | } 10 | return (s); 11 | } 12 | 13 | int ft_len(int n) 14 | { 15 | int len; 16 | 17 | len = 0; 18 | if (n <= 0) 19 | len = 1; 20 | while (n != 0) 21 | { 22 | len++; 23 | n = n / 10; 24 | } 25 | return (len); 26 | } 27 | 28 | char *ft_itoa(int n) 29 | { 30 | char *s; 31 | int len; 32 | unsigned int number; 33 | int sign; 34 | 35 | sign = 1; 36 | len = ft_len(n); 37 | s = (char *)malloc(sizeof(char) * (len + 1)); 38 | if (!(s)) 39 | return (NULL); 40 | s[len--] = '\0'; 41 | if (n == 0) 42 | s[0] = '0'; 43 | if (n < 0) 44 | { 45 | sign *= -1; 46 | number = n * -1; 47 | s[0] = '-'; 48 | } 49 | else 50 | number = n; 51 | s = ft_char(s, number, len); 52 | return (s); 53 | } 54 | 55 | int ft_putnbr(int n) 56 | { 57 | int len; 58 | char *num; 59 | 60 | num = ft_itoa(n); 61 | len = ft_putstr(num); 62 | free(num); 63 | return (len); 64 | } 65 | -------------------------------------------------------------------------------- /src/client.c: -------------------------------------------------------------------------------- 1 | #include "../include/minitalk.h" 2 | 3 | static int ft_atoi(const char *str) 4 | { 5 | int i; 6 | int sign; 7 | unsigned long int result; 8 | 9 | i = 0; 10 | sign = 1; 11 | result = 0; 12 | while (str[i] == 32 || (str[i] >= 9 && str[i] <= 13)) 13 | i++; 14 | if (str[i] == '-') 15 | { 16 | sign = -1; 17 | i++; 18 | } 19 | else if (str[i] == '+') 20 | i++; 21 | while (str[i] >= '0' && str[i] <= '9') 22 | { 23 | result *= 10; 24 | result += str[i] - '0'; 25 | i++; 26 | } 27 | return (result * sign); 28 | } 29 | 30 | void ft_atob(int pid, char c) 31 | { 32 | int bit; 33 | 34 | bit = 0; 35 | while (bit < 8) 36 | { 37 | if ((c & (0x01 << bit))) 38 | kill(pid, SIGUSR1); 39 | else 40 | kill(pid, SIGUSR2); 41 | usleep(500); 42 | bit++; 43 | } 44 | } 45 | 46 | int main(int argc, char **argv) 47 | { 48 | int pid; 49 | int i; 50 | 51 | i = 0; 52 | if (argc == 3) 53 | { 54 | pid = ft_atoi(argv[1]); 55 | while (argv[2][i] != '\0') 56 | { 57 | ft_atob(pid, argv[2][i]); 58 | i++; 59 | } 60 | } 61 | else 62 | { 63 | ft_printf("Error\n"); 64 | return (1); 65 | } 66 | return (0); 67 | } 68 | -------------------------------------------------------------------------------- /src/client_bonus.c: -------------------------------------------------------------------------------- 1 | #include "../include/minitalk_bonus.h" 2 | 3 | void confirm_msg(int signal) 4 | { 5 | if (signal == SIGUSR2) 6 | ft_printf("message recieved\n"); 7 | } 8 | 9 | static int ft_atoi(const char *str) 10 | { 11 | int i; 12 | int sign; 13 | unsigned long int result; 14 | 15 | i = 0; 16 | sign = 1; 17 | result = 0; 18 | while (str[i] == 32 || (str[i] >= 9 && str[i] <= 13)) 19 | i++; 20 | if (str[i] == '-') 21 | { 22 | sign = -1; 23 | i++; 24 | } 25 | else if (str[i] == '+') 26 | i++; 27 | while (str[i] >= '0' && str[i] <= '9') 28 | { 29 | result *= 10; 30 | result += str[i] - '0'; 31 | i++; 32 | } 33 | return (result * sign); 34 | } 35 | 36 | void ft_atob(int pid, char c) 37 | { 38 | int bit; 39 | 40 | bit = 0; 41 | while (bit < 8) 42 | { 43 | if ((c & (0x01 << bit))) 44 | kill(pid, SIGUSR1); 45 | else 46 | kill(pid, SIGUSR2); 47 | usleep(500); 48 | bit++; 49 | } 50 | } 51 | 52 | int main(int argc, char **argv) 53 | { 54 | int pid; 55 | int i; 56 | 57 | i = 0; 58 | if (argc == 3) 59 | { 60 | pid = ft_atoi(argv[1]); 61 | while (argv[2][i] != '\0') 62 | { 63 | ft_atob(pid, argv[2][i]); 64 | i++; 65 | } 66 | signal(SIGUSR2, confirm_msg); 67 | ft_atob(pid, '\0'); 68 | } 69 | else 70 | { 71 | ft_printf("Error\n"); 72 | return (1); 73 | } 74 | return (0); 75 | } 76 | -------------------------------------------------------------------------------- /printf/ft_printf.c: -------------------------------------------------------------------------------- 1 | #include "ft_printf.h" 2 | 3 | int ft_putchar(int c) 4 | { 5 | write(1, &c, 1); 6 | return (1); 7 | } 8 | 9 | int ft_putstr(char *str) 10 | { 11 | int i; 12 | 13 | i = 0; 14 | if (str == NULL) 15 | { 16 | write(1, "(null)", 6); 17 | return (6); 18 | } 19 | while (str[i]) 20 | { 21 | write(1, &str[i], 1); 22 | i++; 23 | } 24 | return (i); 25 | } 26 | 27 | int ft_conversion(va_list vl, const char format) 28 | { 29 | int char_printed; 30 | 31 | char_printed = 0; 32 | if (format == 'c') 33 | char_printed += ft_putchar(va_arg(vl, int)); 34 | else if (format == 's') 35 | char_printed += ft_putstr(va_arg(vl, char *)); 36 | else if (format == 'p') 37 | char_printed += ft_putptr(va_arg(vl, uintptr_t)); 38 | else if (format == 'd' || format == 'i') 39 | char_printed += ft_putnbr(va_arg(vl, int)); 40 | else if (format == 'u') 41 | char_printed += ft_putunsigned(va_arg(vl, unsigned int)); 42 | else if (format == 'x' || format == 'X') 43 | char_printed += ft_puthex(va_arg(vl, unsigned int), format); 44 | else if (format == '%') 45 | char_printed += ft_putchar('%'); 46 | return (char_printed); 47 | } 48 | 49 | int ft_printf(const char *format, ...) 50 | { 51 | int i; 52 | va_list vl; 53 | int char_printed; 54 | 55 | i = 0; 56 | char_printed = 0; 57 | va_start(vl, format); 58 | while (format[i]) 59 | { 60 | if (format[i] == '%') 61 | { 62 | char_printed += ft_conversion(vl, format[i + 1]); 63 | i++; 64 | } 65 | else 66 | char_printed += ft_putchar(format[i]); 67 | i++; 68 | } 69 | va_end(vl); 70 | return (char_printed); 71 | } 72 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | NAMEC = client 3 | NAMES = server 4 | BONUS_NAMEC = client_bonus 5 | BONUS_NAMES = server_bonus 6 | PRINTF = libftprintf.a 7 | SRCC_FILES = client.c 8 | SRCS_FILES = server.c 9 | BONUSC_FILES = client_bonus.c 10 | BONUSS_FILES = server_bonus.c 11 | SRC_DIR = src/ 12 | SRCC = $(addprefix $(SRC_DIR), $(SRCC_FILES)) 13 | SRCS = $(addprefix $(SRC_DIR), $(SRCS_FILES)) 14 | BONUSC = $(addprefix $(SRC_DIR), $(BONUSC_FILES)) 15 | BONUSS = $(addprefix $(SRC_DIR), $(BONUSS_FILES)) 16 | OBJC = ${SRCC:.c=.o} 17 | OBJS = ${SRCS:.c=.o} 18 | OBJBC = ${BONUSC:.c=.o} 19 | OBJBS = ${BONUSS:.c=.o} 20 | CC = cc 21 | CFLAGS = -Wall -Werror -Wextra 22 | INCLUDE = -I include 23 | RM = rm -rf 24 | 25 | all: $(NAMEC) $(NAMES) 26 | 27 | $(NAMEC) : $(OBJC) 28 | @make -C printf 29 | $(CC) $(CFLAGS) $(OBJC) $(INCLUDE) printf/$(PRINTF) -o $(NAMEC) 30 | 31 | $(NAMES) : $(OBJS) 32 | @make -C printf 33 | $(CC) $(CFLAGS) $(OBJS) $(INCLUDE) printf/$(PRINTF) -o $(NAMES) 34 | 35 | bonus : $(BONUS_NAMEC) $(BONUS_NAMES) 36 | 37 | $(BONUS_NAMEC) : $(OBJBC) 38 | @make -C printf 39 | $(CC) $(CFLAGS) $(OBJBC) $(INCLUDE) printf/$(PRINTF) -o $(BONUS_NAMEC) 40 | 41 | $(BONUS_NAMES) : $(OBJBS) 42 | @make -C printf 43 | $(CC) $(CFLAGS) $(OBJBS) $(INCLUDE) printf/$(PRINTF) -o $(BONUS_NAMES) 44 | 45 | clean : 46 | @make clean -C printf 47 | ${RM} ${OBJC} 48 | ${RM} ${OBJS} 49 | ${RM} ${OBJBC} 50 | ${RM} ${OBJBS} 51 | 52 | fclean : clean 53 | @make fclean -C printf 54 | ${RM} $(NAMEC) 55 | ${RM} $(NAMES) 56 | ${RM} $(BONUS_NAMEC) 57 | ${RM} $(BONUS_NAMES) 58 | ${RM} $(PRINTF) 59 | 60 | re : fclean all 61 | 62 | .PHONY: all bonus clean fclean re -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 1337-minitalk-42 2 | Small data exchange program using UNIX signals. 3 | 4 | # Resources 5 | https://www.geeksforgeeks.org/inter-process-communication-ipc/?ref=lbp
6 | https://www.man7.org/linux/man-pages/man7/signal.7.html
7 | https://en.wikipedia.org/wiki/Signal_(IPC)
8 | https://www.tutorialspoint.com/unix_system_calls/sigaction.htm
9 | https://people.kth.se/~johanmon/ose/assignments/signals.pdf
10 | https://pubs.opengroup.org/onlinepubs/007904875/functions/sigaction.html
11 | https://stackoverflow.com/questions/231912/what-is-the-difference-between-sigaction-and-signal
12 | https://www.ibm.com/docs/en/i/7.2?topic=ssw_ibm_i_72/apis/sigactn.htm
13 | http://manpagesfr.free.fr/man/man2/sigaction.2.html
14 | https://www.dummytextgenerator.com/#jump
15 | https://excerpts.numilog.com/books/9782212677607-extrait.pdf
16 | https://en.wikipedia.org/wiki/Thread_(computing)
17 | https://www.man7.org/linux/man-pages/man5/core.5.html
18 | https://www.geeksforgeeks.org/introduction-of-process-management/?ref=lbp
19 | https://en.wikipedia.org/wiki/Process_(computing)
20 | https://man7.org/linux/man-pages/man2/kill.2.html
21 | https://www.tutorialspoint.com/unix/unix-signals-traps.htm
22 | https://linuxhint.com/signal_handlers_c_programming_language/
23 | https://decimal.info/hex-to-decimal/1/how-to-convert-0X10-to-decimal.html
24 | https://www.rapidtables.com/convert/number/ascii-to-binary.html
25 | https://www.mkssoftware.com/docs/man5/siginfo_t.5.asp
26 | https://sites.uclouvain.be/SystInfo/notes/Theorie/Fichiers/fichiers-signaux.html
27 | https://www.tutorialspoint.com/unix/unix-processes.htm
28 | http://convertalot.com/bitwise_operators.html
29 | https://doc.lagout.org/LPI/LINUX%20Préparation%20à%20la%20certification%20LPIC-1%20%28LPI%20101%20LPI%20102%29%202ème%20Edition.pdf
30 | https://bitwisecmd.com
31 | https://jameshfisher.com/2017/01/13/c-sigaction/
32 | https://man7.org/linux/man-pages/man2/sigaction.2.html
33 | https://miro.com/app/board/uXjVOY6DYx8=/?invite_link_id=689990184473
34 | https://leeters.netlify.app/what-you-need-to-know-about-minitalk/
35 | https://www.youtube.com/watch?v=L3XuR-iRysU
36 | https://askcodez.com/gestion-du-signal-et-sigemptyset.html
37 | 38 | # Books 39 | C en action. -Yves Mettier
40 | Développement système sous Linux: Ordonnancement multi-tâche, gestion mémoire, communications, programmation réseau. - Christophe Blaess
41 | --------------------------------------------------------------------------------