From 361ff25359715a1d1242b6854578ba93d002d80d Mon Sep 17 00:00:00 2001 From: short <> Date: Sun, 8 Apr 2001 09:55:42 +0000 Subject: [PATCH] Child receive-SMS processes' zombies are now properly collected on SIGCHLD receive-SMS improved to be able to batch receive a stream of SMSes - full modem reset/restart occured after each SMS before, SMSes could be lost Cosmetic: ", 0 part(s)" no longer written for regular text SMSes --- mdsms.c | 100 +++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 29 deletions(-) diff --git a/mdsms.c b/mdsms.c index c20097d..03f391f 100644 --- a/mdsms.c +++ b/mdsms.c @@ -38,6 +38,9 @@ static char rcsid[] ATTR_UNUSED = "$Id$"; #ifdef HAVE_SYS_TYPES_H #include #endif +#ifdef HAVE_SYS_WAIT_H +#include +#endif #ifdef HAVE_SYS_STAT_H #include #endif @@ -930,6 +933,8 @@ off_t o=d-fs->s; return(fs->s); } +static char devcmd_empty_return='\0'; /* returned as catch when only newlines found */ + static char *devcmd(const char *term,const char *catch,const char *send,...) ATTR_PRINTFORMAT(3,4); static char *devcmd(const char *term,const char *catch,const char *send,...) { @@ -1021,6 +1026,14 @@ err: got=read(devfd,buf+bufl,1); } if (got<=0) { + buf[bufl]='\0'; /* for strspn() below */ + if (!strcmp(term,"\n") && catch /* written to trap on 'devcmd("\n","+CMT:"," ")' */ + && bufl==strspn(buf,"\n" /* accept */)) { /* only newlines found */ + if (verbose>=2) + error(_(".Blank (%d newlines) input read, ignoring it"),bufl); + bufl=0; /* discard newlines */ + return(&devcmd_empty_return); + } if (wasalarm) error(_("Maximum response timeout (%lds) exceeded"),alarmtime); else error(_("^Couldn't read device data (ret=%d)"),got); goto err; @@ -1454,12 +1467,13 @@ fd_set rfds,xfds; assert(devfd>=0); retry: - errno=0; - + if (!immed && verbose>=2) + error(_(".Waiting for device incoming data..")); #ifdef HAVE_POLL ufd.fd=devfd; ufd.events=POLLIN; ufd.revents=0; + errno=0; i=poll(&ufd,1,(immed?0:-1)); #else /* HAVE_POLL */ #ifdef HAVE_FD_SETSIZE @@ -1469,9 +1483,12 @@ retry: #endif /* HAVE_FD_SETSIZE */ FD_ZERO(&rfds); FD_SET(devfd,&rfds); FD_ZERO(&xfds); FD_SET(devfd,&xfds); + errno=0; i=select(devfd+1,&rfds,NULL,&xfds,NULL); #endif /* HAVE_POLL */ if (immed && i==0) return(0); + if (i==-1 && errno==EINTR) + goto retry; /* silent retry, for example SIGCHLD could occur */ if (i!=1) error(_("^Failed (retval %d) while waiting for data, ignoring"),i); @@ -1616,6 +1633,19 @@ int i; #undef DIGIT2ASC } +static void signal_chld(int signo) +{ +int status; +pid_t pid; + + d2("signal_chld: signo=%d\n",signo); + while (0<(pid=waitpid(-1 /* ANY process */,&status,WNOHANG /* options */))) { + if (verbose>=2) + error(_(".Child process w/PID %d has exited, %s, status=%d"), + pid,(WIFEXITED(status)? _("normally") : _("abnormally")),(WIFEXITED(status) ? WEXITSTATUS(status) : -1)); + } +} + static void receive_text(char *bodyline) { char *buf,*s,*s1,*s2,*s3; @@ -1625,12 +1655,17 @@ int i; FILE *f; d2("receive_text: %s\n",bodyline); + signal(SIGCHLD,signal_chld); #if RECEIVE_TEST pid=0; #else pid=fork(); #endif - if (pid>0) return; /* parent context */ + if (pid>0) { + if (verbose>=2) + error(_(".Spawned child receive-SMS process w/PID %d"),pid); + return; /* parent context */ + } if (pid==-1) { error(_("Can't fork(2), process spawning may block receive")); } @@ -2137,38 +2172,42 @@ struct hexdata *hd; restore="\r\nAT+CNMI=,0"; devcmd(NULL,NULL,"\r\nAT+CNMI=,2"); devcmd(NULL,NULL,"\r\nAT+CSDH=0"); - unlockdevice(0); - /* Never bail-out when we got up to this point */ - if (maxretryn!=-1 && verbose>=1) - error(_(".Initialization successful, infinite retry count set")); - maxretryn=-1; + for (;;) { +continue_receive: + unlockdevice(0); + /* Never bail-out when we got up to this point */ + if (maxretryn!=-1 && verbose>=1) + error(_(".Initialization successful, infinite retry count set")); + maxretryn=-1; #if RECEIVE_TEST receive_headerparse(" \"+420602123456\",,\"99/10/25,03:21:03-00\""); receive_accept("TESTBODY"); exit(EXIT_SUCCESS); #endif - datawait(0); - if (!lockdevice(1)) { - if (verbose>=1) - error(_(".Dialout detected, waiting for lock..")); - lockdevice(0); - goto retryall; - } - d1("Lock-device succeeded\n"); - do { - d1("Reading a message for us...\n"); - if (!(s=devcmd("\n","+CMT:"," "))) + datawait(0); + if (!lockdevice(1)) { + if (verbose>=1) + error(_(".Dialout detected, waiting for lock..")); + lockdevice(0); goto retryall; - if (cmgf && !(i=receive_headerparse(s))) - error(_("Receive-header parsing failed on: %s"),s); - if (!(s=devcmd("\n","@"," "))) - goto retryall; - if (cmgf) { - if (i) receive_text(s); } - else receive_pdu(s); - } while (datawait(1)); - goto retryall; + d1("Lock-device succeeded\n"); + do { + d1("Reading a message for us...\n"); + if (!(s=devcmd("\n","+CMT:"," "))) + goto retryall; + if (s==&devcmd_empty_return) /* only newlines found */ + goto continue_receive; + if (cmgf && !(i=receive_headerparse(s))) + error(_("Receive-header parsing failed on: %s"),s); + if (!(s=devcmd("\n","@"," "))) + goto retryall; + if (cmgf) { + if (i) receive_text(s); + } + else receive_pdu(s); + } while (datawait(1)); + } /* return to 'continue receive' point */ break; default: assert(0); } @@ -2181,6 +2220,9 @@ struct hexdata *hd; } devcmd(NULL,NULL,"\r\nAT"); - logmsg(_("SMS sent (after %d retries), %d part(s)"),retrycnt,parts); + if (parts) + logmsg(_("SMS sent (after %d retries), %d part(s)"),retrycnt,parts); + else + logmsg(_("SMS sent (after %d retries)"),retrycnt); return(EXIT_SUCCESS); } -- 1.8.3.1