This project has been created as part of the 42 curriculum by hbani-at.
Minitalk is an inter-process communication (IPC) project that demonstrates signal-based communication between two processes. The project implements a simple client-server architecture where the client sends messages to the server using UNIX signals (SIGUSR1 and SIGUSR2) for bit-level communication.
Goal: To understand how signals work in UNIX systems and implement a practical IPC mechanism using signals to transmit data between processes.
Overview: The project consists of two programs:
- Server: A process that listens for incoming signals and reconstructs messages by accumulating bits received from clients
- Client: A process that sends a message to the server by converting each character into bits and transmitting them via signals
The communication protocol encodes each character as 8 bits, where SIGUSR1 represents a binary 1 and SIGUSR2 represents a binary 0. The server acknowledges each bit with a SIGUSR1 signal, ensuring reliable transmission.
Build the project using the provided Makefile:
makeThis will compile both the server and client programs, creating server and client executables in the current directory.
Starting the Server:
./serverThe server will start and display its PID. It will then wait indefinitely for incoming messages from clients.
Sending a Message via Client:
./client <server_pid> "<message>"Replace <server_pid> with the PID displayed by the server and <message> with the message you want to send.
Example:
# Terminal 1: Start the server
./server
# Output: 12345
# Terminal 2: Send a message
./client 12345 "Hello, World!"
# Terminal 1: Server displays
# Hello, World!Remove compiled binaries:
make cleanRemove all generated files:
make fcleanman 7 signal- Signal concepts and usageman 2 signal- Signal system call interfaceman 1 kill- Signal sending commandman 7 signal-safety- Signal-safe functionsman sigaction- Advanced signal handlingman sigemptyset- Initialize signal setman pgrep- Process search and filteringman pstree- Process tree displayman pause- Suspend process executionman sleep- Sleep for secondsman usleep- Sleep for microsecondsman malloc- Memory allocationman free- Free memoryman 2 exit- Exit process
- Global Variables in C
- Communicating between processes using signals
- Handling signals
- Sending and Handling Signals in C (kill, signal, sigaction)
- Sending and Intercepting a Signal in C
- Inter Process Communication (IPC)
- Methods in Inter process Communication
- Inter Process Communication wiki
- Synchronous vs. Asynchronous Communication
- User space and kernel space
No AI was used in the development of this project. All code was written manually to satisfy the 42 curriculum requirements for understanding signal-based inter-process communication.
A process is a running instance of an executable program. It includes:
- Address space
- Security credentials
- One or more threads
- A state
| State | Flag | Description |
|---|---|---|
| Running | R | Executing on a CPU or ready to run |
| Sleeping | S | Waiting for an event or resource (interruptible) |
| Uninterruptible | D | Waiting, cannot be interrupted |
| Stopped | T | Stopped by signal or for debugging |
| Zombie | Z | Process finished; parent must clean up |
A signal is a software interrupt delivered to a process. Signals report events such as errors, I/O events, expired timers, or manual commands.
| Signal | Name | Description |
|---|---|---|
| 1 | HUP | Hangup; reports terminal disconnection or requests config reload |
| 2 | INT | Interrupt; stops program (Ctrl+C) |
| 9 | KILL | Force kill; cannot be blocked or handled |
| 15 | TERM | Terminate; default clean shutdown signal |
| 18 | CONT | Resume a stopped process |
| 19 | STOP | Stop (suspend) process, uncatchable |
| 20 | TSTP | Terminal stop (Ctrl+Z); catchable |
| 30 | USR1 | User-defined signal 1 (used in Minitalk for binary 1) |
| 31 | USR2 | User-defined signal 2 (used in Minitalk for binary 0) |
Note: Signal names are portable across platforms, but numbers may vary. Use signal names (like
SIGKILL) instead of numbers when possible.
From Keyboard:
| Key Combo | Signal | Action |
|---|---|---|
| Ctrl+C | SIGINT | Terminate process |
| Ctrl+Z | SIGTSTP | Suspend process |
Using kill Command:
kill PID # Send default SIGTERM
kill -9 PID # SIGKILL (force kill)
kill -SIGTERM PID # Named signal
kill -SIGUSR1 PID # Send SIGUSR1
kill -SIGUSR2 PID # Send SIGUSR2Using pkill:
pkill -u bob # SIGTERM all bob's processes
pkill -SIGKILL -u bob # Force kill all bob's processesWhen a child process exits:
- It leaves a zombie (remains in process table)
- Parent must clean it up using
wait(), freeing resources - Does not consume CPU or memory, just a slot in the process table
ps aux # All processes
ps j # Job/process/session details
top # Real-time process monitoringExample output:
$ ps aux
USER PID %CPU %MEM ... STAT ... COMMAND
root 2 0.0 0.0 ... S ... [kthreadd]
student 3448 0.0 0.2 ... R+ ... ps aux- Monitor and Manage Linux Processes
- Jobs and Job Control in Linux
- Linux Job Control &, disown, and nohup
- Jobs from Red Hat
The project uses sigaction() for robust signal handling with SA_SIGINFO flag to receive sender PID information. This allows the server to:
- Receive signals from the client
- Extract the sender's PID using
siginfo_t - Acknowledge bit reception by sending SIGUSR1 back to the client
- Handle both SIGUSR1 and SIGUSR2 for bit values
Key signal handling concepts:
- Signal handlers are functions that execute when a signal is received
- sigaction() provides more control than the older
signal()function - SA_SIGINFO flag enables access to
siginfo_tstructure with sender information - sig_atomic_t ensures atomic access to volatile variables modified by signal handlers
Minitalk uses SIGUSR1 and SIGUSR2 to transmit binary data:
- SIGUSR1 = binary 1 (bit value is set)
- SIGUSR2 = binary 0 (bit value is cleared)
- Each character is transmitted MSB-first (bits 7 to 0)
- Null terminator ('\0') signals message end
- 400 microseconds delay between bits for reliability
- Acknowledgment: Server sends SIGUSR1 after each bit, confirming receipt
Transmission Example for 'A' (ASCII 65 = 01000001):
01000001 → SIGUSR2 SIGUSR1 SIGUSR2 SIGUSR2 SIGUSR2 SIGUSR1 SIGUSR2 SIGUSR1
server.c- Server implementation that receives and reconstructs messagesclient.c- Client implementation that sends messageserror.c- Error handling and validation functionsminitalk.h- Header file with type definitions and function declarationslibft/- Custom C library with utility functions