-1

So iam developing a program that when receive a signal kill -SIGUSR1 PID, need to output to stdout the following line:

2020-10-09T18:01:27+01:00, and this is the time, when programm was launched, so I need to get this time when the signal is received! I am using siginfo

I dont need to know how to print, I need to know how to get the time when the program was launched!

act.sa_sigaction = signalManagement;

sigemptyset(&act.sa_mask);

act.sa_flags |= SA_SIGINFO; 
act.sa_flags |= SA_RESTART; 


if (sigaction(SIGUSR1 , &act, NULL) < 0){
    ERROR(1, "sigaction - SIGUSR1 ");
}

and my signal function is:

void signalManagement(int sig, siginfo_t *siginfo, void *context) 
{
    (void)context;
    int aux;
    aux = errno;

    if(sig == SIGUSR1 ){
      //* I need code where to show the output "2020-10-09T18:01:27+01:00", example when programm was launched
    }

    errno = aux;
}
  • So actually, your question has nothing to do with signals and you just want to know how to display the time when the program was started? – user253751 Oct 09 '20 at 17:09
  • @user253751 As the title says, it's signal management! After receiving the signal, the date / time the program was started is sent to stdout. However I am not able to access it through siginfo-> si_tid –  Oct 09 '20 at 17:11
  • 3
    Calling your signal handler function `signal()` is obviously a terrible idea. – EOF Oct 09 '20 at 17:12
  • @EOF But this is a project, and my teacher, want the management of signal in a function –  Oct 09 '20 at 17:14
  • You can handle signals if you want, but you can't *name* your signal handler "signal", because `signal()` is **already** used by POSIX for the older (terribly broken) variant of the function manipulating signal handlers (the newer, less-broken version of which is `sigaction()`). – EOF Oct 09 '20 at 17:17
  • @EOF Yes, on my new code, I dont have that, that was my old code! So, I dont know how to send to stdout the example –  Oct 09 '20 at 17:21
  • @prt05 Why would siginfo->si_tid have the date and time the program was started? si_tid is the ID number of a timer when the signal is sent by a timer. – user253751 Oct 09 '20 at 17:23
  • 1
    `write(STDOUT_FILENO, "2020-10-09T18:01:27+01:00", sizeof("2020-10-09T18:01:27+01:00"));` – EOF Oct 09 '20 at 17:23
  • @EOF without the trailing null character – user253751 Oct 09 '20 at 17:23
  • @user253751 Pretty sure nobody is going to care about the null. If you do, replace `sizeof()` with `strlen()`. – EOF Oct 09 '20 at 17:25
  • @EOF um, everyone cares about printing garbage onto the screen. – user253751 Oct 09 '20 at 17:26
  • @user253751 I don't think null is a graphical character (or even printable?) so nobody will even notice. – EOF Oct 09 '20 at 17:27
  • Thats ok, my problem its not printing its where can I go, to get the date/hour where program was iniciated –  Oct 09 '20 at 17:33
  • @prt05 The general concern is doing a lot of stuff in a signal handler, so less is more. The proper way to handle this is to put something in your `main()` routine that runs right at startup and `sprintf`s the time into a buffer, so you can easily `write()` it during the signal handler. Fetching the process start time after the fact is possible but it's much more work and not really safe to do in a signal handler. – Steve Friedl Oct 09 '20 at 17:46
  • Also, you probably don't want `exit()` in your signal handler unless you want to end the entire program, and in any case **nothing** executes after `exit` – Steve Friedl Oct 09 '20 at 18:05
  • @SteveFriedl I already handle the signal SIGINT, and on this signal I need to finish the program so that why the exit(0) its there, because I have copied for the other function! But I will remove it from this one –  Oct 09 '20 at 19:46
  • @SteveFriedl "The proper way to handle this is to put something in your main() routine that runs right at startup and sprintfs the time into a buffer, so you can easily write() it during the signal handler." Thats a good idead! I will try it thanks for that one :) –  Oct 09 '20 at 19:47
  • @SteveFriedl Do you know how can I get the time on my Main, and put it to a buffer, bacause I need a equal output as the example –  Oct 09 '20 at 19:51
  • I do not understand, what exactly do you want to print? You want to print _exactly_ the string `2020-10-09T18:01:27+01:00` or do you want to print the time of signal receival formatted in `YYYY-MM-DDThh-mm-ss+zz:zz` format or do you want to print the startup time of your application in that format? And _where_ do you want to print it? – KamilCuk Oct 09 '20 at 20:13
  • @KamilCuk So I run my programm and it will wait for a signal and when I receive the signal it prints the time that programm was launched, not the time of signal receival, but the time when programm was launched formatted in `YYYY-MM-DDThh-mm-ss+zz:z` –  Oct 09 '20 at 20:17
  • @KamilCuk So like SteveFried said, I can save the date and hour on a buf, on my main when I run the code! But I dont know the how to concatenate the string with that format –  Oct 09 '20 at 20:19
  • That's `YYYY-MM-DDThh:mm:ss+zz:zz` :p – KamilCuk Oct 09 '20 at 20:21
  • @KamilCuk Yes, but I need a function that get time of computer, and then I put that format –  Oct 09 '20 at 20:29

2 Answers2

2

I need to know how to get the time when the program was launched!

So store the time at your program startup and print it when receiving the signal.

#include <time.h>
#include <stdio.h>
#include <stddef.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
static sig_atomic_t sigusr1_received = 0;
static void sigusr1_handler(int v) {
    ++sigusr1_received;
}
int main() {
    struct tm startuptime = *localtime((time_t[1]){time(0)});
    signal(SIGUSR1, sigusr1_handler);
    while (1) {
        pause();
        if (sigusr1_received) {
            --sigusr1_received;
            char buf[200];
            strftime(buf, sizeof(buf), "%FT%X%z", &startuptime);
            printf("%s\n", buf);
        }
    }
}

Adding the additional : two characters from the back is left as an exerciser to others. One could also call strftime once at program startup and call write(3) from signal handler. Like so:

#include <time.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
static char buf[200];
void sigusr1_handler(int v) {
    write(STDOUT_FILENO, buf, strlen(buf));
}
int main() {
    strftime(buf, sizeof(buf), "%FT%X%z\n", localtime((time_t[1]){time(0)}));
    signal(SIGUSR1, sigusr1_handler);
    while (1) {
        pause();
    }
}
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Start learning C with a [good C book](https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list). Such, and many more topics, should be well explained in sections related to string manipulations. It's simple - move two characters to the right, insert a `:` in a proper position. Remember about terminating null byte. – KamilCuk Oct 09 '20 at 20:52
  • thanks for the help creating the fucntion, I already move the 2 characters and it worked thanks for the help! –  Oct 09 '20 at 21:52
-3

You can print it like this:

printf("2020-10-09T18:01:27+01:00\n");

However, if your signal handler happened inside of another printf call, you're calling printf inside of printf which might crash. You could use write (on Linux) which can't be interrupted this way:

const char *message = "2020-10-09T18:01:27+01:00\n";
write(STDOUT_FILENO, message, strlen(message));
user253751
  • 57,427
  • 7
  • 48
  • 90
  • my problem its now how to print, its where I go to get the date and time when program was executed! Like the string that I give was a example –  Oct 09 '20 at 17:34
  • Then why don't you ask how to get the date and time when the program was executed, instead of asking how to print? – user253751 Oct 09 '20 at 17:48
  • 1
    They're a new contributor: please be nice. – Steve Friedl Oct 09 '20 at 17:50
  • 1
    @SteveFriedl Being new doesn't excuse lack of common sense. Ask the question you want to know the answer to. Don't ask a different question. I *asked* if the question was actually not about the signals and the answer was: no, it's about signals. – user253751 Oct 09 '20 at 17:51
  • It was my bad sorry for that! Thanks for your time! Apreciate that –  Oct 09 '20 at 19:48