2016-12-31 20 views
-1

У меня проблема с кодом C, в основном мне нужно отправить электронное письмо через программу mutt. Он должен быть отправлен, когда прерывание появляется из выводов GPIO. Моя функция sendMail указана ниже. Я понял это с помощью системы функции. Main содержит цикл с функцией logAlarm, который содержит sendMail. Дело в том, что система (cmd) функция отделки, вся программа C останавливается. Например, когда я помещал функцию sendMail в начале основной, она работает и отправляет электронную почту на мой почтовый ящик, не останавливая всю программу, в цикле, которую ему удается отправить, но она завершает программу. Я попытался использовать знак &, чтобы запустить его в фоновом режиме, но он не помог.Программа C прервана во время выполнения функции «system»

P.S Я не знаю, если это имеет значение, но im также использует системный вызов от setitimer с интервалом в 2 секунды, чтобы проверить несколько вещей, но я думаю, что это не влияет на этот случай.

Любые идеи?

Заранее спасибо :)

функции Sendmail:

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); 

} 

Вот кусок моей главной функции:

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; 
     } 

} 
+0

Что рассчитывает отладчик? Где он точно останавливается? См. [Ask] и укажите [mcve]. – Olaf

+0

system() синхронно, поэтому sendmail() не вернется, пока не закончится cmd. – Marichyasana

+0

благодарит @Olaf за использование отладчика: D. Это очень помогло, это была вина SIGSEGV. В одном случае переменная cmd была маленькой, и программа была сбойной. Благодаря! – Orzechix

ответ

0

Хороший вопрос. В соответствии с описанием я считаю, что функция sendMail работает правильно. Я не работал с mutt. Но я работал с system().

В какой системе это происходит, он создает дочерний процесс вашего текущего процесса и выполняет команду с помощью execve(). Поэтому проблема должна заключаться в возврате системы.

Итак, сначала вы должны проверить статус возврата системной функции. Если вы можете сделать printf() ниже системы(), то у вас не будет проблем с системой(). Если вы не можете получить printf ниже системы(), система() уничтожит ваш процесс. (путем отправки сигналов сигкилла или симулятора, но не сигнита или сигкита, так как он игнорируется системой()). Вы создаете дочерний процесс в самом CMD (выход эхо-выхода в mutt). Возможно, это должно быть основной причиной.

Если вы столкнулись с проблемой здесь, проблема будет критической, и вы найдете указания из раздела «ПРИМЕЧАНИЯ» в «man system», так как вы реализовали ту же логику, о которой упоминалось. Сначала попробуйте подождать упомянутых условий. Если вы все еще не можете этого сделать, попробуйте разбить два новых дочерних процесса, запустите execl или любую другую функцию семейства exec («man 3 exec») из этого дочернего процесса, чтобы запустить echo и mutt.

Если система() в порядке, то проверьте logAlarm(). это дает правильные аргументы SendMail? если вы получаете «Ошибка записи в файл журнала !!!», тогда вся последовательность в порядке.

+0

Большое спасибо за ваш anwser, я делаю больше исследований, а как @Olaf предложил в комментарии, я использовал команду strace для отладки, и я заметил, что системная команда вызывает SIGSEGV, которая завершает мою программу, поэтому моя программа нарушает память i Угадай? Мне нужно еще раз проверить код. Я скоро поставлю журналы – Orzechix

+0

...ошибка была в функции sendMail, переменная cmd была слишком мала, чтобы содержать большую строку .. и она вызывала SIGSEGV. Я не тестировал его для фиксированной длины сообщения, поэтому иногда это было нормально, потому что cmd var был меньше 100 символов, но в основной программе сообщение было больше 100 символов. Какой позор: D. – Orzechix