yasnd/daemon/yasnd-ipc.c

146 lines
3.2 KiB
C
Raw Normal View History

#include <sys/ipc.h>
#include <sys/msg.h>
#include "yasnd.h"
pid_t ipc_clone_pid;
pid_t ipc_sms_read_clone_pid=-1; // pid of thread, that checks for new incoming SMS
int qid=-1; // IPC queue id
int open_queue()
{
key_t keyval=ftok(".",'m');
int qid;
if((qid = msgget( keyval, IPC_CREAT | 0660 )) == -1)
{
log_event("Error opening/creating IPC message queue");
exit(EXIT_FAILURE);
}
return qid;
}
int send_message(int qid, mymsgbuf* qbuf)
{
int result;
/* The length is essentially the size of the structure minus sizeof(mtype) */
int length = sizeof(mymsgbuf) - sizeof(long);
if((result = msgsnd( qid, qbuf, length, 0)) == -1)
{
return -1;
}
return result;
}
int read_message(int qid, mymsgbuf* qbuf, long type)
{
int result;
int length = sizeof(mymsgbuf) - sizeof(long);
if((result = msgrcv( qid, qbuf, length, type, 0)) == -1)
{
return -1;
}
return result;
}
int remove_queue( int qid )
{
if( msgctl(qid, IPC_RMID, 0) == -1)
{
return -1;
}
return 0;
}
int ipc_queue_loop()
{
// set default signal handlers
signal(SIGTERM,SIG_DFL);
signal(SIGHUP,SIG_DFL);
//
mymsgbuf qbuf;
while(1)
{
int result=read_message(qid, &qbuf, 0);
if (result==-1)
{
log_event("Error: finishing IPC loop process...");
return 1;
}
char dbg_txt[150];
sprintf(dbg_txt,"Read IPC message - Type: %ld Text: %s", qbuf.mtype, qbuf.mtext);
log_debug(dbg_txt,DEBUG_ALL);
if (qbuf.mtype==SMS_RECEIVE_TYPE && sms_enable)
2011-12-20 17:02:34 +04:00
{
pid_t pid = fork();
if (pid < 0) {
log_event("Error: can not fork child :(");
exit(EXIT_FAILURE);
}
// If pid == 0, then we are in the child
if (pid == 0) {
gammu_read_sms();
exit(EXIT_SUCCESS);
}
// wait for SMS reading thread
// STUB: need to react on status, returned by thread
waitpid(pid,NULL,0);
}
if (qbuf.mtype==SMS_SEND_TYPE && sms_enable)
{
log_debug(qbuf.mtext,DEBUG_BASE);
2011-12-20 13:23:13 +04:00
pid_t pid = fork();
if (pid < 0) {
log_event("Error: can not fork child :(");
exit(EXIT_FAILURE);
}
// If pid == 0, then we are in the child
if (pid == 0) {
gammu_send_sms(qbuf.mtext);
exit(EXIT_SUCCESS);
}
// wait for SMS sending thread
// STUB: need to react on status, returned by thread
waitpid(pid,NULL,0);
}
}
}
int ipc_sms_reading_loop()
{
// set default signal handlers
signal(SIGTERM,SIG_DFL);
signal(SIGHUP,SIG_DFL);
//
while(1)
{
sleep(30); /* wait 30 seconds */
2011-12-20 17:02:34 +04:00
mymsgbuf qbuf;
qbuf.mtype=SMS_RECEIVE_TYPE;
qbuf.mtext[0]=(char)0;
send_message(qid,&qbuf);
}
}
void ipc_init()
{
qid = open_queue();
unsigned char ipc_child_stack[16384];
ipc_clone_pid=clone(ipc_queue_loop,ipc_child_stack+8192,CLONE_VM,NULL);
// start loop, that handles new incoming SMS
2011-12-20 17:02:34 +04:00
unsigned char sms_child_stack[16384];
ipc_sms_read_clone_pid=clone(ipc_sms_reading_loop,sms_child_stack+8192,CLONE_VM,NULL);
//
}
void ipc_free()
{
kill(ipc_clone_pid,SIGTERM);
waitpid(ipc_clone_pid,NULL,__WCLONE);
2011-12-20 17:02:34 +04:00
kill(ipc_sms_read_clone_pid,SIGTERM);
waitpid(ipc_sms_read_clone_pid,NULL,__WCLONE);
remove_queue(qid);
}