0

The program is a server that receives messages from the client by transmitting SIGUSR1 or SIGUSR2 signals and decrypts them using bitwise operations (but this is not important yet). The server shows the PID and then waits for a SIGUSR1 or SIGUSR2 signal.

  1. The question is simple: In main, in case of a signal, the ft_btoa handler function is launched WITHOUT ARGUMENTS. Then how does function "know" that the variable "sig" in the description of the ft_btoa function is a number of signal?
  2. Question - in what cases it is allowed to use signal, but not sigaction?

void    ft_btoa(int sig)
{
    static int  bit;
    static int  i;

    if (sig == SIGUSR1)
        i |= (0x01 << bit);
    bit++;
    if (bit == 8)
    {
        ft_printf("%c", i);
        bit = 0;
        i = 0;
    }
}

int main(int argc, char **argv)
{
    int pid;

    (void)argv;
    if (argc != 1)
    {
        ft_printf("Error\n");
        return (1);
    }
    pid = getpid();
    ft_printf("%d\n", pid);
    while (argc == 1)
    {
        signal(SIGUSR1, ft_btoa);
        signal(SIGUSR2, ft_btoa);
        pause ();
    }
    return (0);
}

I'm trying to understand how it works..

  • 1
    Please focus on one question - the first one, if I may recommend (for purely selfish reasons). Put the second question in a separate question post, which focuses on it. – Yunnosch Apr 19 '23 at 13:28
  • Note the discussion in [How to avoid using `printf()` in a signal handler?](https://stackoverflow.com/q/16891019/15168) and also [What is the difference between `sigaction()` and `signal()`?](https://stackoverflow.com/q/231912/15168) – Jonathan Leffler Apr 20 '23 at 01:10
  • You're allowed to use `signal()` in a hosted implementation of standard C. Standalone implementations are not required to support `signal()`. POSIX systems should support `sigaction()`, but if you're not working on a POSIX-ish system, it won't help you. When it is available, using `sigaction()` is generally the better choice — it gives you both better control and more precisely defined behaviour, whereas `signal()` is specified loosely because it had to match many divergent implementations (way back in 1989). C does not allow you to do much in a signal handler; POSIX is a lot more generous. – Jonathan Leffler Apr 20 '23 at 01:19

1 Answers1

0

You have a misunderstanding in "In main, in case of a signal, the ft_btoa handler function is launched WITHOUT ARGUMENTS."; it is not.

This signal(SIGUSR1, ft_btoa); is not a call, not to ft_btoa() to be precise.
It is a call to signal() giving the function named ft_btoa as a parameter.
The parameter means "at the appropriate time, call this function and give it the parameter which at that time makes sense".
For this to work, ft_btoa has to match the prototype expected by what is behind signal(), including accepting a parameter which matches what at the time of calling ft_btoa() (not signal()) needs to be carried as a parameter.

The call to ft_btoa(int) happens later and DOES give a parameter.

Judging from your comment, you are aware of the relevant context:

#include <signal.h>
/* you should include the appropriate header,
   which I assume you do, though your shown code does not */


typedef void (*sighandler_t) (int) ;
/* an appropriate sighandler function of type sighandler_t
   should accept a parameter of type int 
   (which will carry the corresponding value
    at the time when the sighandler is called)
   and return nothing */

sighandler_t signal(int signum, sighandler_t handler);
/* calling signal requires
   a signum parameter of type int
   a handler parameter of type sighandler_t, see above
   it will return a sighandler_t, which your shown code ignores
 */
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • This is from man for signal function (It is my signal number in bold?): SYNOPSIS #include typedef void (*sighandler_t) **(int)** ; sighandler_t signal(int signum, sighandler_t handler); – Leet1337 Apr 19 '23 at 13:32
  • Sorry, I do not get your comment. You seem to be quoting the part of the relevant header which represents "ft_btoa has to match the prototype expected by what is behind signal()". I.e. ft_btoa has to be a `sighandler_t`, it should accept an `int` parameter and return nothing. The bold part is a type, not a value. You may want to add that quote to your question. Better formatting, more info, as backgroud to your (hopefully single) question. – Yunnosch Apr 19 '23 at 13:38