> For the complete documentation index, see [llms.txt](https://42-guide.gitbook.io/42-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://42-guide.gitbook.io/42-guide/core-curriculum/rank-02/integrations/check-the-code.md).

# Check the code

I have started from creating server  program, which prints out the pid number.<br>

#### Server Setup (`server.c` file):

* First, a server application is created that listens for incoming signals.
* The server processes these signals and assembles them into characters and, eventually, a string. (this part i wrote after finishing client program)

#### PID of the Server:

* The **PID** (Process ID) of the server is printed to the console. This is needed for the client to know where to send the signals. The client will send signals to the server using the server's PID.

### Original Code: `server.c`

```c
#include <minitalk.h>

void convert_bits(int signal)
{
    // Function to handle signal processing.
    // Add your implementation here for converting signal bits.
}

int	main(void)
{
    ft_printf("Feel free to use free version:)\n");
    ft_printf("Here is my PID: %d\n", getpid());
    signal(SIGUSR1, convert_bits);  // Registers the handler for SIGUSR1
    signal(SIGUSR2, convert_bits);  // Registers the handler for SIGUSR2
    while (1)
        pause();  // Waits for signals indefinitely
    return (0);
}
```

`And now i have moved for client part`\
\
The provided code is for a client-side application in a Unix-based system. It communicates with a server-side application using signals to send a string message, one bit at a time. Each character in the message is converted into bits, and for each bit, a signal (`SIGUSR1` or `SIGUSR2`) is sent to the server. This method of communication allows for the transmission of text over Unix signals.

#### Client (`client.c` file):

* After setting up the server and obtaining its PID, the next step is to create the client that sends a message to the server.
* The client takes in two arguments:
  * The first argument is the **PID** of the server.
  * The second argument is the **message** (string) that needs to be sent.
* The client then sends the message byte by byte, where each byte is broken down into 8 bits. For each bit, the client sends a `SIGUSR1` signal for `1` and a `SIGUSR2` signal for `0`.
* After the entire message is sent, a `\0` (null byte) is sent to signify the end of the message.

```c
// Main function that sends the entire message byte by byte to the server
int main(int argc, char **argv)
{
    unsigned char *msg;  // Pointer to the message
    int pid;  // Process ID of the server (the receiver)

    if (argc != 3)  // Ensure the correct number of arguments
    {
        ft_printf("Provide me with correct info :(\n");  // If not, print error message
        return (1);
    }
    pid = ft_atoi(argv[1]);  // Convert the first argument (PID) from string to integer
    if (pid < 0)  // Ensure the PID is not negative
        return (ft_printf("PID can not be negative!\n"), 1);  // If it is negative, print error message

    msg = (unsigned char *) argv[2];  // The second argument is the message to send

    while (*msg)  // Loop through the message until we reach the null terminator
    {
        send_bit(*(msg++), pid);  // Send each byte (character) of the message to the server
    }

    send_bit('\0', pid);  // Send the null byte (end of string) to signal the end of the message

    return (0);
}
```

}

#### Bitwise Signal Transmission:

* Each character is converted into its **binary representation** (8 bits).
* The client sends `SIGUSR1` for a bit `1` and `SIGUSR2` for a bit `0`. A short sleep (`usleep(500)`) is included to ensure the server has time to process the signal before the next one is sent.

#### Completion:

* Once the entire message has been sent, the client program exits.

### Important Notes:

* **PID Validity:** If an invalid PID is provided or if the `kill` system call fails, the program prints an error message and exits with a non-zero status.
* **Signal Handling:** The program relies on the Unix signals (`SIGUSR1` and `SIGUSR2`) for communication. Signals are a powerful but limited way to transfer data between processes in Unix-based systems.
* **Synchronization:** A small delay (`usleep(500)`) is added between signals to ensure that the server has enough time to handle each bit individually.

\#include "minitalk.h" // Includes necessary header file for functions like ft\_printf and ft\_atoi

// Function to send a single byte (8 bits) to the server by sending SIGUSR1 or SIGUSR2 for each bit void send\_bit(unsigned char bytes, int pid) { int i;

```c
#include "minitalk.h"  // Includes necessary header file for functions like ft_printf and ft_atoi

// Function to send a single byte (8 bits) to the server by sending SIGUSR1 or SIGUSR2 for each bit
void send_bit(unsigned char bytes, int pid)
{
    int i;

    i = 7;  // Start from the most significant bit (leftmost) of the byte
    while (i >= 0)  // Loop through all 8 bits of the byte
    {
        // Check if the current bit is 1
        if ((bytes >> i) & 1)
        {
            // If bit is 1, send SIGUSR1 to the server using kill() system call
            if ((kill(pid, SIGUSR1) == -1))
            {
                ft_printf("Invalid PID number!\n");
                exit(1);  // Exit if sending the signal fails
            }
        }
        else
        {
            // If bit is 0, send SIGUSR2 to the server
            if ((kill(pid, SIGUSR2) == -1))
            {
                ft_printf("Invalid PID number!\n");
                exit(1);  // Exit if sending the signal fails
            }
        }
        usleep(500);  // Sleep for 500 microseconds to give the server time to process
        i--;  // Move to the next bit (decrement the bit index)
    }
}
```

### Summary:

After creating the `server.c` file and printing out its PID, I moved on to creating the `client.c` file. The client sends a string to the server using Unix signals (`SIGUSR1` and `SIGUSR2`) to represent binary values of each character. The server, upon receiving the signals, will decode them and reconstruct the message. This communication method is particularly interesting because it relies solely on signals, making it a low-level form of inter-process communication (IPC).

Below i came back again, to finish my server.c, to convert back from bit to char.\
\
\#include "minitalk.h" // Includes the necessary header file for the program, likely containing function declarations like ft\_printf

// Global structure to hold the character being built and the bit count t\_msg g\_alpha = {0, 0}; // g\_alpha holds the current character ('c') and the number of bits received ('nobits')

// Function to convert incoming signal bits to characters void convert\_bits(int bits) { // If the received signal is SIGUSR1, we set the current bit in the character if (bits == SIGUSR1) g\_alpha.c |= (1 << (7 - g\_alpha.nobits)); // Set the (7 - nobits)-th bit to 1 (leftmost bit first)

```c
#include "minitalk.h"  // Includes the necessary header file for the program, likely containing function declarations like ft_printf

// Global structure to hold the character being built and the bit count
t_msg g_alpha = {0, 0};  // g_alpha holds the current character ('c') and the number of bits received ('nobits')

// Function to convert incoming signal bits to characters
void convert_bits(int bits)
{
    // If the received signal is SIGUSR1, we set the current bit in the character
    if (bits == SIGUSR1)
        g_alpha.c |= (1 << (7 - g_alpha.nobits));  // Set the (7 - nobits)-th bit to 1 (leftmost bit first)
    
    // If the received signal is SIGUSR2, we set the current bit to 0 (this is actually redundant as '0' does nothing here)
    else if (bits == SIGUSR2)
        g_alpha.c |= (0 >> (7 - g_alpha.nobits));  // This expression does nothing as it shifts 0 to the right (no effect)

    // Increment the bit counter
    g_alpha.nobits++;

    // If we've received 8 bits (one byte), process the character
    if (g_alpha.nobits == 8)
    {
        // Print the character formed from the bits
        ft_printf("%c", g_alpha.c);

        // If the received character is a null byte (indicating end of the string)
        if (!g_alpha.c)
        {
            ft_printf("\n");  // Print a newline
        }

        // Reset g_alpha to start receiving the next character
        g_alpha.c = 0;
        g_alpha.nobits = 0;
    }
}
```

### Function `convert_bits`:

* This is the signal handler for both `SIGUSR1` and `SIGUSR2`.
* Based on the received signal (`SIGUSR1` or `SIGUSR2`), it modifies the current bit in `g_alpha.c`.
* After receiving 8 bits (one byte), it prints the character using `ft_printf`. If the character is a null byte (`\0`), it prints a newline to mark the end of a message.
* It then resets `g_alpha` to prepare for the next byte.

### Main Function:

* Prints the **PID** of the program so that the sender knows where to send the signals.
* Registers `convert_bits` as the handler for both `SIGUSR1` and `SIGUSR2` signals using `signal()`.
* Uses `pause()` to keep the program running and waiting for signals indefinitely.

### How It Works:

* **Sender (client)** sends a series of `SIGUSR1` and `SIGUSR2` signals to the receiver (this program).
  * Each `SIGUSR1` represents a bit `1`, and each `SIGUSR2` represents a bit `0`.
* The `convert_bits` function accumulates the bits in `g_alpha.c` and processes them into a character when 8 bits are received.
* If a null byte (`\0`) is received, it prints a newline to indicate the end of the message.

The goal of this project isn’t to just finish it. It’s about learning and picking up new skills as you go. Take it one step at a time—use my code as a reference, but always experiment and make it your own.

If anything unclear  or you need help, feel free to hit me up! 😊\
\
Go to github -> [\[source code\]](https://github.com/mukhammadsiddiq/42Berlin-Guideline/tree/main/Minitalk)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://42-guide.gitbook.io/42-guide/core-curriculum/rank-02/integrations/check-the-code.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
