Search code examples
cemailterminalterminatemutt

C program is interrupted during the execution of “system” function


I have a problem with my C code, basically I need to send email via mutt program. It must be send when an interrupt comes up from GPIO pin. My sendMail function is listed below. I realized this by using system function. Main contains loop with logAlarm func which contains sendMail. The thing is when system(cmd) function finishes, the whole C program stops. For instance when i put sendMail function at the begining of the main it works and is sending email to my mailbox without stopping whole program, in the loop it manages to send it but it terminates program. I tried to using & sign to run it in background but it didnt help.

P.S i dont know if it matters but im also using system call from setitimer with 2 sec intervals to check few things but i guess it has no impact for this case.

Any ideas?

Thanks in advance :)

sendMail function:

void sendMail(char * msg, char * recipientMail){
 char cmd[100];
 char subject[30];
 char body[60];

 sprintf(body, "Intruder detected!!!\n%s", msg);
 strcpy(subject, "\"ALARM - SECURITY BREACH\"");
 sprintf(cmd,"echo \"%s\" | mutt -s %s %s &", body, subject, recipientMail);
 printf("%s\n\n", cmd);
 system(cmd);

}

Here is a piece of my main function:

while(1){

        sleep(1);

        if(prev_state == triggered && !emailDetach){
            if(!logAlarm()){
                printf("Error writing to log file!!!\n");
            }
            emailDetach = true;
        }
        //printf("Czas od poprzedniego alarmu: %d", millis() - alarmTriggeredTime);
        if((prev_state == triggered) && (millis() - alarmTriggeredTime >= ALARM_TIME)){

            digitalWrite(ALARM_ON_DIODE, LOW);
            digitalWrite(ALARM_OFF_DIODE, HIGH);
            //warunek czasowy osobno na syrene TODO
            if(!silentMode && (millis() - alarmTriggeredTime >= siren_alarm_time)){
                digitalWrite(SIREN, LOW);
            }
            prev_state = nottriggered;
        }

}

Solution

  • Good question. As per description, I consider that sendMail function works properly. I've not worked with mutt. But i've worked with system().

    What system does is, it forks a child process of your current process and executes the command using execve(). So the problem should be in the returning of the system.

    So, first you should check the return status of system function. If you are able to make printf() below the system(), then you're not having problem with system(). If you are not able get printf below the system(), then system() is killing your process. (by sending sigkill or similer signals, but not sigint or sigquit, since it is ignored by system()). You are creating a child process in the cmd itself (echo output piping to mutt). May be this should be root cause.

    If you find problem here, then the problem is critical, and you will find directions from the "NOTES" section of "man system", since you have implemented the same logic mentioned there. First just try to wait for conditions mentioned there. If you're still unable to do this, try to fork two new child process, run execl or any other exec family function ("man 3 exec") from that child process to run echo and mutt.

    If system() is ok, then check logAlarm(). is it giving the right arguments to the sendMail? if you are getting "Error writing to log file!!!", then entire sequence is ok.