Overview
The server is the receiving end of the Minitalk communication system. It listens for UNIX signals (SIGUSR1 and SIGUSR2) and reconstructs the original message by interpreting each signal as a bit value.
Source Code Location
server.c - Lines 1-46
Architecture
The server uses a signal-driven architecture:- Displays its Process ID (PID) on startup
- Registers signal handlers for
SIGUSR1andSIGUSR2 - Enters an infinite loop waiting for signals
- Reconstructs characters bit-by-bit through the signal handler
- Outputs completed characters using
ft_printf
Signal Handler Function
handle_sigusr()
The signal received:
SIGUSR1 (representing bit 0) or SIGUSR2 (representing bit 1)Static Variables
The function maintains state across invocations using static variables:Character accumulator - Stores the character being built bit by bit. Resets to 0 after each complete character (8 bits).
Bit counter - Tracks how many bits have been received for the current character (0-7). Resets to 0 after reaching 8.
Bit Shifting Logic
Understanding the Bit Manipulation
Understanding the Bit Manipulation
The handler uses left-shift operations to build characters from individual bits:
After 8 bits,
SIGUSR1 Handler (Bit = 0)
- Shifts all existing bits in
cone position to the left - The rightmost bit becomes 0
- Example:
0b00000101becomes0b00001010
SIGUSR2 Handler (Bit = 1)
- Shifts all existing bits in
cone position to the left - Uses bitwise OR with 1 to set the rightmost bit to 1
- Example:
0b00000101becomes0b00001011
Complete Example
To receive the character ‘A’ (ASCII 65 =0b01000001):| Signal | Operation | Result (binary) | Result (decimal) |
|---|---|---|---|
| SIGUSR1 | c << 1 | 0b00000000 | 0 |
| SIGUSR2 | (c << 1) | 1 | 0b00000001 | 1 |
| SIGUSR1 | c << 1 | 0b00000010 | 2 |
| SIGUSR1 | c << 1 | 0b00000100 | 4 |
| SIGUSR1 | c << 1 | 0b00001000 | 8 |
| SIGUSR1 | c << 1 | 0b00010000 | 16 |
| SIGUSR1 | c << 1 | 0b00100000 | 32 |
| SIGUSR2 | (c << 1) | 1 | 0b01000001 | 65 (‘A’) |
i == 8 triggers output and reset.Character Output
- The accumulated character
cis printed usingft_printf - Both counters are reset for the next character
- The process repeats for subsequent characters
Main Function
main()
Initialization Sequence
Display PID
Uses
getpid() to retrieve the server’s process ID and displays it. The client needs this PID to send signals.Register Signal Handlers
Both The
SIGUSR1 and SIGUSR2 are registered to call handle_sigusr.signal() function signature:Signal Registration Details
User-defined signal 1. In Minitalk, this represents a 0 bit.
User-defined signal 2. In Minitalk, this represents a 1 bit.
Function pointer to the signal handler. Called automatically when the signal is received.
Dependencies
Included Headers
ft_printf.h
Custom printf implementation for formatted output
signal.h
POSIX signal handling functions and constants
System Calls Used
Returns the process ID of the calling process. Used to display the server’s PID for client connection.
Registers a signal handler function. Maps
SIGUSR1 and SIGUSR2 to handle_sigusr.Suspends the calling process until a signal is received. Returns -1 when interrupted by a signal handler.
Execution Flow
Key Features
Stateful Reception
Uses static variables to maintain state across signal handler invocations
Bit-by-Bit Assembly
Reconstructs characters from 8 individual signal transmissions
Non-Blocking
Uses
pause() for efficient CPU usage while waiting for signalsBinary Encoding
Maps SIGUSR1 to 0 and SIGUSR2 to 1 for binary data transmission
Limitations and Considerations
The server has no built-in timeout or termination mechanism. It must be manually terminated (e.g., with SIGINT/Ctrl+C).
Performance: The
pause() system call is CPU-efficient, suspending the process completely until a signal arrives.