rkneal
asked on
getting errno=4, interupted system call, also get a EPIPE signal after runs for a few hours
can someone please help me on a few things.
1. Â When this code runs, i send data from client to this server code. Â I successfully send and get back data. But, as soon as the signal/alarm fire off once (right after the read_request), i get a errno=4, interupted system call, then when i try to write on the socket again i get "bad file number" on socket. Â Â If i get rid of the signal/alarm and go into an infinite loop after the read_request (thus never returning back to main), the writes work. Â Is it because i am closing the socket when i return, i've tried commenting that out and get same issue. Â Is the errno=4, interupted system call happening because of the signal/alarm interupt? Â
I'm trying to control the checkforupdates function by using the timer. When i receive any new requests on the socket, i want to turn it off, that is why see update_timer(0), update_timer(1) when go into read_request again.
2. When i run this code for a few hours, i end up getting EPIPE recieved signal. Â In my code i close socket if i get this and wait for another request. Â What causes this signal to occur, and should i handle it different than closing socket. Â When this occurs, i can tell the client to resume, and it takes off again, but that's not too robust for something that needs to run 24/7. Â I think i will write code on the client, that if i don't get back data for x amount of seconds, i will re-request data. Â I have a piece of data that changes every second to be used as a watchdog, so it should always be changing.
3. How do i know that the client socket has closed? Â Should i look for errors on the "write" statements to determine this. Â I want to stop looking and sending updates and go into wait mode if i close client.
Lots of questions, sorry for so long a post.
Bob
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "/wdpf/rel/ssw/shc/inc/SHC _err.h"
#include "/wdpf/rel/ssw/shc/inc/spd .h"
#include "pointServer.h"
#include <signal.h>
#include <unistd.h>
#define TRUE 1
#define FALSE 0
#define anaDB Â .01
#define MAXPOINTS 8000
#define RECBUFFSIZE Â 400000
#define SENDBUFFSIZE 400000
#define MAXRECORDSENDS 300
/* signal stuff */
void update_timer(int);
void cleanup();
#define SCANTIME Â 5
char debug_msg = FALSE;
int PORT;
void processRead(void);
typedef struct datarec {
      char pn[9];
  int rt;
  unsigned short digital_val;
  unsigned short old_digital_val;
      unsigned short digital_stat;
      unsigned short old_digital_stat;
      unsigned short gp_val;
      unsigned short old_gp_val;
      unsigned short gp_stat;
      unsigned short old_gp_stat;
      unsigned short gp_force_stat;
      unsigned short old_gp_force_stat;
      float av;
  float old_av;     Â
  unsigned short as;
      unsigned short old_as;
  long sid; } DATAREC;
/* struct datarec *indatap; */
struct datarec indatap[MAXPOINTS];
int numpoints;
FILE *data_lun;
int access_type = RUNTIME;
static char *wdpf_pdir;
long gp_sid = 0;
char gp_bit_num = 0;
char ina_flag;
char ext_flag;
char outbuff[SENDBUFFSIZE]; Â /* need to dynamically do this! later*/
char inbuff[RECBUFFSIZE];
int file_desc;
int status;
int msgsock;
Point_entry point_info;
char network_name[8];
unsigned char byte_val;
int optlen;
long sockstat;
main(int argc, char *argv[])
{
int sock,clientLen,serverLen;
struct sockaddr_in serverAddr, clientAddr;
int i;
char on=1;
int tcpsendbuff, tcprecbuff;
char ch;
if(debug_msg)
printf("\nprogram started...");
/** get program command flags **/
/** first argument is port number **/
if(argc <Â 2) {
 printf("\nincorrect calling parameters;  rt portID <d>  <d> = debug mode");
 exit(0); }
/** see if want to go into debug mode **/
while(--argc >0)
 if(strchr(argv[argc],'d')) {
  debug_msg = TRUE;
  printf("\nentering debug message mode\n"); }
/** turn off update interupt **/
update_timer(0);
/** get port number from command line **/
PORT = strtol(argv[1],NULL,10);
/** set up WDPF stuff **/
wdpf_pdir = (char *) getenv("WDPF_PDIR");
if(wdpf_pdir == NULL) {
 printf("\nunable to get WDPF_PDIR environment variable");
 exit(1); }
status = SHC_open_memory();
if(status != SHC_OK) {
 printf("\nSHC_open_memory error -- status = %d",status);
 exit(1); }
file_desc = SPD_open_file(wdpf_pdir,&a ccess_type );
if(file_desc <Â 0) {
 printf("\nSPD_open_file error -- %s status = %d",wdpf_pdir,file_desc);
 exit(1); }
/******************** set up socket interface with XP Â ***********************/
/** setup stream socket **/
if((sock = socket(AF_INET,SOCK_STREAM ,0)) <Â 0) {
  printf("\ncannot open stream socket");
  exit(1); }
if(debug_msg)
 printf("\ncreated sock, sock = %d..",sock);
/** set socket options **/
if(setsockopt(sock,SOL_SOC KET,SO_REU SEADDR,&on ,sizeof(on )) <Â 0) {
  printf("\ncannot set SO_REUSEADDR socket option");
  /* exit(1);*/ }
 Â
tcpsendbuff = 64384;
tcprecbuff = 64384;
if(setsockopt(sock,SOL_SOC KET,SO_SND BUF, (char *) &tcpsendbuff, sizeof(tcpsendbuff)) <Â 0) {
  printf("\ncannot set SO_SNDBUF socket option");
  exit(1); }
Â
if(setsockopt(sock,SOL_SOC KET,SO_RCV BUF, (char *) &tcprecbuff, sizeof(tcprecbuff)) <Â 0) {
  printf("\ncannot set SO_RCVBUF socket option");
  exit(1); }
optlen =sizeof(tcpsendbuff);
if(getsockopt(sock,SOL_SOC KET,SO_SND BUF, (char *) &tcpsendbuff, &optlen) <Â 0) {
  printf("\ncannot set SO_SNDBUF socket option");
  exit(1); }
if(debug_msg)
 printf("\nnew SO_SNDBUF len = %d",tcpsendbuff);
optlen =sizeof(tcprecbuff);
if(getsockopt(sock,SOL_SOC KET,SO_RCV BUF, (char *) &tcprecbuff, &optlen) <Â 0) {
  printf("\ncannot set SO_RCVBUF socket option");
  exit(1); }
if(debug_msg)
 printf("\nnew SO_RCVBUF len = %d",tcprecbuff);
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port=htons( PORT);
if(bind(sock,(struct sockaddr *) &serverAddr,sizeof(serverA ddr)) <Â 0) {
  printf("\ncannot bind stream socket error, port = %d",PORT);
  exit(1); }
if(debug_msg)
 printf("\nbind socket ok...");
serverLen = sizeof(serverAddr);
if(getsockname(sock,(struc t sockaddr *) &serverAddr,&serverLen) <0) {
  printf("getting socket name");
  exit(1); }
if(debug_msg)
 printf("\ngetsocketname ok...");
listen(sock,1);
if(debug_msg)
 printf("\nlistening for requests on socket %d...",PORT);
/* turn off alarming up front  */
signal(SIGINT, cleanup);
signal(SIGPIPE, SIG_IGN);
for(;;) {
do {
 clientLen= sizeof(clientAddr);
 msgsock = accept(sock, (struct sockaddr *) &clientAddr, &clientLen);
if(debug_msg) Â
printf("\nmsgsock=%d errno = %d errstr = %s",msgsock,errno,strerror (errno));
}while (msgsock <0 &&Â (errno == EINTR || errno == 32) );
if(msgsock <Â 0)
 if(debug_msg) {
  printf("\nsock accept error");
  exit (-1); }
Â
if(debug_msg)
 printf("\naccepted socket...");
i=readn(msgsock,inbuff, sizeof(inbuff));
if(debug_msg) {
 printf("\nreceived %d bytes",i);
 printf("\nstring = %s",inbuff); }
read_request();
close(msgsock);
}/* end for loop */
if(debug_msg)
printf("\nexiting do loop errno = %s",strerror(errno));
sockstat = close(msgsock);
exit(0);
}
/************************* ** end main ************************** ********/
/************************* ********** ********** ********** ********** ********** ********** ********** *********/
/** this function  used to read "n" bytes from socket **/
int
readn(fd,ptr,nbytes)
register int fd;
register char *ptr;
register int nbytes;
{
int nleft,nread;
char terminator[2];
nleft = nbytes;
do {
nread = read(fd,ptr,nleft);
strncpy(terminator,ptr+(st rlen(ptr)- 2),2);
Â
if(nread <Â 0)
  return(nread);
else if (nread == 0)
  break;
nleft -= nread;
ptr  += nread;
/* *ptr ='\0'; */
if(debug_msg)
 printf("\nterminator = %s", ptr+(strlen(ptr)-2));
if(!strcmp(terminator,"^^" ))
{
 break;
}
} while(1);
return(nread);
}
/************************* ********** ********** ********** ********** ********** ********** ********** *********/
/* used to write "n" bytes */
int
writen(fd,ptr,nbytes)
register int fd;
register char *ptr;
register int nbytes;
{
int nleft, nwritten;
nleft = nbytes;
while(nleft >0) {
Â
nwritten = write(fd,ptr,nleft);
Â
if(nwritten <=0)
  return(nwritten);
 nleft -= nwritten;
 ptr  += nwritten;
}
return(nbytes - nleft);
}
/************************* ********** ********** ********** ********** ********** ********** ********** *********/
/********** read inputs points ******/
read_request(void)
{
int i,j;
char cmdType[3];
int cmdNum;
int status;
int count;
char strcount[5];
char field_name[2];
strncpy(cmdType,inbuff+0,2 );
cmdNum = atoi(cmdType);
cmdType[2]='\0';
/* whole point records */
if(cmdNum==0) {
update_timer(0);
Â
strncpy(strcount,inbuff+2, 4);
strcount[4]='\0';
count = atoi(strcount);
numpoints = count;
if(debug_msg)
 printf("\nrequested to retreive %d points",count);
/* allocate memory based on number of points found */
/*indatap = malloc(count * sizeof(datarec)); */
if(debug_msg)
 printf("\nallocated %d memory structures for points",count);
j=6;
for (i = 1;i <=count; i++)
 {
strncpy(indatap[i].pn, inbuff+j,8);
j=j+8;
indatap[i].pn[8]='\0';
/* need to add error checking here later*/
status = SPD_get_sid(&file_desc,ind atap[i].pn ,&indatap[ i].sid,&gp _sid,&gp_b it_num,&ex t_flag,&in a_flag);
status = SPD_get_point_info(&file_d esc,&indat ap[i].sid, &point_inf o,network_ name);
indatap[i].rt = point_info.rec_type;
if(debug_msg)
 printf("\nrt = %d",indatap[i].rt);
if(debug_msg)
 printf("\npopulated dynamic structure for %s (index = %d) stat = %d",indatap[i].pn,i,status );
}
/* go and get whole point records if cmd type = 00*/
getpointrecords();
update_timer(1);
} /* end whole point record */
if(cmdNum== 2) {
update_timer(0);
strcpy(field_name,"CM");
byte_val = 14;
printf("\nnum points = %d",numpoints);
for(i=1;i<=numpoints;i++) Â {
status = SHC_change_byte_attribute( &indatap[i ].sid,&fie ld_name, &byte_val);
if(debug_msg)
 printf("\nwrote ack bit for pn = %s, stat = %d", indatap[i].pn,status);
 }
update_timer(1);
} /* end write ack bit */
}
int getpointrecords()
{
int i;
int k;
unsigned char point_record[300];
char hh[2];
char hdrStr[6];
int status;
int bytesSent;
long retMsgCount;
char tempbuff[300];
int sendCounter;
/* build ret msg string in format of [cmd][index]data^^ Â */ Â
outbuff[0]='\0';
hdrStr[0]='\0';
sendCounter = 0;
/* cmdtype = 00 for whole point record ret */
sprintf(hdrStr,"%2s","00") ; Â
hdrStr[2]='\0';
strcpy(outbuff,hdrStr);
if(debug_msg)
printf("\nnumpoints = %d",numpoints);
for (i = 1;i <= numpoints; i++)
 {
  strcat(outbuff,"(");
  sprintf(hdrStr,"%04d",i); Â
  hdrStr[4]='\0';
  strcat(outbuff,hdrStr);
  tempbuff[0]='\0';
  status = SHC_get_point_record(&inda tap[i].sid , &point_record);
  if(debug_msg)
  printf("\nretrieved record for %s (index = %d)",indatap[i].pn,i);
  for(k=0;k<128;k++) {
   sprintf(hh,"%02x",point_re cord[k]);
   strcat(tempbuff,hh);}
 Â
  strcat(outbuff,tempbuff);
  strcat(outbuff,")");
  if(sendCounter >= MAXRECORDSENDS) {
    outbuff[strlen(outbuff)] ='\0';
    bytesSent=writen(msgsock,( char *)outbuff,strlen(outbuff)) ;
   if(debug_msg  )
     printf("\ngoing to send back %d bytes",strlen(outbuff));
     /*  printf("\nstring = \n%s",outbuff);  */
      outbuff[0]='\0';
       sendCounter = 0; }
  else
       sendCounter = sendCounter +1;
 Â
} Â
/* tag ending message info */
  strcat(outbuff,"^^");
  retMsgCount = strlen(outbuff);
  outbuff[retMsgCount]='\0';
  /* send back the localbuff up to retMsgCount of len */
  if(debug_msg  ) {
   printf("\ngoing to send back %d bytes",retMsgCount);
   /* printf("\nstring = \n%s",outbuff); */ }
  bytesSent=writen(msgsock,( char *)outbuff,retMsgCount);
  if(debug_msg)
   printf("\nwriten errno = %d, %s sent %d bytes over network",errno,strerror(er rno),bytes Sent);
init_struct();
}
checkforchanges()
{
int i;
char *modestr;
int status;
int bytesSent;
char tmpstr[20];
/* exceptions sent as CMD(PN_TOKEN=VALUE), ... */
/* clear out buffer */
/* don't let another timer hit if already in here */
/* while(1) { Â Â */
outbuff[0]='\0';
strcpy(outbuff,"01");
for (i=1;i<=numpoints;i++)
 {
modestr="";
 switch(indatap[i].rt) {
 case RECORD_TYPE_AI:
 case RECORD_TYPE_AL:
 case RECORD_TYPE_AC:
 case RECORD_TYPE_AM:
 modestr="Analog";
 status = SHC_get_analog_val_stat(&i ndatap[i]. sid,&indat ap[i].av,& indatap[i] .as);
if(indatap[i].old_as != indatap[i].as) {
      strcat(outbuff,"(");
      strcat(outbuff,indatap[i]. pn);
      strcat(outbuff,"_AS=");
    sprintf(tmpstr,"%d",indata p[i].as);
    strcat(outbuff,tmpstr);
      strcat(outbuff,")");
 }
if(debug_msg &&Â indatap[i].old_as != indatap[i].as) Â
   printf("\nold as of %s = %d, new as val = %d",indatap[i].pn, indatap[i].old_as,indatap[ i].as);
indatap[i].old_as = indatap[i].as;
 break;
 case RECORD_TYPE_DI:
 case RECORD_TYPE_DL:
 case RECORD_TYPE_DC:
 case RECORD_TYPE_DM:
 modestr="Digital";
 status = SHC_get_digital_val_stat(& indatap[i] .sid,&gp_s id,&gp_bit _num,&inda tap[i].dig ital_val,& indatap[i] .digital_s tat);
/* for testing only */
indatap[1].old_digital_sta t = 99;
if(indatap[i].digital_stat != indatap[i].old_digital_sta t &&Â status == SHC_OK) {
      strcat(outbuff,"(");
      strcat(outbuff,indatap[i]. pn);
      strcat(outbuff,"_DS=");
    sprintf(tmpstr,"%d",indata p[i].digit al_stat & 0x01);
    strcat(outbuff,tmpstr);
      strcat(outbuff,")");
}
if(debug_msg &&Â indatap[i].digital_stat != indatap[i].old_digital_sta t)
        printf("\nold ds of %s = %d, new ds = %d",indatap[i].pn, indatap[i].old_digital_sta t,indatap[ i].digital _stat);
     Â
indatap[i].old_digital_sta t = indatap[i].digital_stat;
Â
break;
 break; }  /* end switch */
 }  /* next point, end for*/
 strcat(outbuff,"^^");
 outbuff[strlen(outbuff)]=' \0';
/* only send if string is greater than the default 00^^ */
if(strlen(outbuff) >Â 4) {
 bytesSent=writen(msgsock,( char *)outbuff,strlen(outbuff)) ;
  if(debug_msg)
   printf("\nwriten errno = %d, %s, sent %d bytes over network",errno,strerror(er rno),bytes Sent);
  }
if(errno == 32) {
if(debug_msg) Â
 printf("\nreceived EPIPE signal, closing socket, waiting...");
 close(msgsock);
 errno=0;
 return; }
/* Â sleep(SCANTIME); */
/* Â Â } Â Â while true */
}
Â
void update_timer(int signum)
{
if(signum == 0)
{ alarm(0);
 return;
}
if(debug_msg)
 printf("\nchecking for exceptions");
checkforchanges();
signal(SIGALRM,update_time r);
alarm(SCANTIME); Â
} Â
init_struct()
{
int i;
for(i=1;i<=numpoints;i++) {
    indatap[i].digital_val=0;
    indatap[i].old_digital_val =9;
      indatap[i].digital_stat=0;
      indatap[i].old_digital_sta t=9;
      indatap[i].gp_val=0;
      indatap[i].old_gp_val=9;
      indatap[i].gp_stat=0;
      indatap[i].old_gp_stat=9;
      indatap[i].gp_force_stat=0 ;
      indatap[i].old_gp_force_st at=9;
      indatap[i].av=0.00;
    indatap[i].old_av=99999.00 ;     Â
}
}
void cleanup(int sig_num)
{
 signal(SIGINT,cleanup);
 printf("\nexit gracefully\n\n\n...");
 fflush(stdout);
 sockstat = close(msgsock); Â
exit(0);
}
1. Â When this code runs, i send data from client to this server code. Â I successfully send and get back data. But, as soon as the signal/alarm fire off once (right after the read_request), i get a errno=4, interupted system call, then when i try to write on the socket again i get "bad file number" on socket. Â Â If i get rid of the signal/alarm and go into an infinite loop after the read_request (thus never returning back to main), the writes work. Â Is it because i am closing the socket when i return, i've tried commenting that out and get same issue. Â Is the errno=4, interupted system call happening because of the signal/alarm interupt? Â
I'm trying to control the checkforupdates function by using the timer. When i receive any new requests on the socket, i want to turn it off, that is why see update_timer(0), update_timer(1) when go into read_request again.
2. When i run this code for a few hours, i end up getting EPIPE recieved signal. Â In my code i close socket if i get this and wait for another request. Â What causes this signal to occur, and should i handle it different than closing socket. Â When this occurs, i can tell the client to resume, and it takes off again, but that's not too robust for something that needs to run 24/7. Â I think i will write code on the client, that if i don't get back data for x amount of seconds, i will re-request data. Â I have a piece of data that changes every second to be used as a watchdog, so it should always be changing.
3. How do i know that the client socket has closed? Â Should i look for errors on the "write" statements to determine this. Â I want to stop looking and sending updates and go into wait mode if i close client.
Lots of questions, sorry for so long a post.
Bob
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "/wdpf/rel/ssw/shc/inc/SHC
#include "/wdpf/rel/ssw/shc/inc/spd
#include "pointServer.h"
#include <signal.h>
#include <unistd.h>
#define TRUE 1
#define FALSE 0
#define anaDB Â .01
#define MAXPOINTS 8000
#define RECBUFFSIZE Â 400000
#define SENDBUFFSIZE 400000
#define MAXRECORDSENDS 300
/* signal stuff */
void update_timer(int);
void cleanup();
#define SCANTIME Â 5
char debug_msg = FALSE;
int PORT;
void processRead(void);
typedef struct datarec {
      char pn[9];
  int rt;
  unsigned short digital_val;
  unsigned short old_digital_val;
      unsigned short digital_stat;
      unsigned short old_digital_stat;
      unsigned short gp_val;
      unsigned short old_gp_val;
      unsigned short gp_stat;
      unsigned short old_gp_stat;
      unsigned short gp_force_stat;
      unsigned short old_gp_force_stat;
      float av;
  float old_av;     Â
  unsigned short as;
      unsigned short old_as;
  long sid; } DATAREC;
/* struct datarec *indatap; */
struct datarec indatap[MAXPOINTS];
int numpoints;
FILE *data_lun;
int access_type = RUNTIME;
static char *wdpf_pdir;
long gp_sid = 0;
char gp_bit_num = 0;
char ina_flag;
char ext_flag;
char outbuff[SENDBUFFSIZE]; Â /* need to dynamically do this! later*/
char inbuff[RECBUFFSIZE];
int file_desc;
int status;
int msgsock;
Point_entry point_info;
char network_name[8];
unsigned char byte_val;
int optlen;
long sockstat;
main(int argc, char *argv[])
{
int sock,clientLen,serverLen;
struct sockaddr_in serverAddr, clientAddr;
int i;
char on=1;
int tcpsendbuff, tcprecbuff;
char ch;
if(debug_msg)
printf("\nprogram started...");
/** get program command flags **/
/** first argument is port number **/
if(argc <Â 2) {
 printf("\nincorrect calling parameters;  rt portID <d>  <d> = debug mode");
 exit(0); }
/** see if want to go into debug mode **/
while(--argc >0)
 if(strchr(argv[argc],'d'))
  debug_msg = TRUE;
  printf("\nentering debug message mode\n"); }
/** turn off update interupt **/
update_timer(0);
/** get port number from command line **/
PORT = strtol(argv[1],NULL,10);
/** set up WDPF stuff **/
wdpf_pdir = (char *) getenv("WDPF_PDIR");
if(wdpf_pdir == NULL) {
 printf("\nunable to get WDPF_PDIR environment variable");
 exit(1); }
status = SHC_open_memory();
if(status != SHC_OK) {
 printf("\nSHC_open_memory error -- status = %d",status);
 exit(1); }
file_desc = SPD_open_file(wdpf_pdir,&a
if(file_desc <Â 0) {
 printf("\nSPD_open_file error -- %s status = %d",wdpf_pdir,file_desc);
 exit(1); }
/******************** set up socket interface with XP Â ***********************/
/** setup stream socket **/
if((sock = socket(AF_INET,SOCK_STREAM
  printf("\ncannot open stream socket");
  exit(1); }
if(debug_msg)
 printf("\ncreated sock, sock = %d..",sock);
/** set socket options **/
if(setsockopt(sock,SOL_SOC
  printf("\ncannot set SO_REUSEADDR socket option");
  /* exit(1);*/ }
 Â
tcpsendbuff = 64384;
tcprecbuff = 64384;
if(setsockopt(sock,SOL_SOC
  printf("\ncannot set SO_SNDBUF socket option");
  exit(1); }
Â
if(setsockopt(sock,SOL_SOC
  printf("\ncannot set SO_RCVBUF socket option");
  exit(1); }
optlen =sizeof(tcpsendbuff);
if(getsockopt(sock,SOL_SOC
  printf("\ncannot set SO_SNDBUF socket option");
  exit(1); }
if(debug_msg)
 printf("\nnew SO_SNDBUF len = %d",tcpsendbuff);
optlen =sizeof(tcprecbuff);
if(getsockopt(sock,SOL_SOC
  printf("\ncannot set SO_RCVBUF socket option");
  exit(1); }
if(debug_msg)
 printf("\nnew SO_RCVBUF len = %d",tcprecbuff);
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr
serverAddr.sin_port=htons(
if(bind(sock,(struct sockaddr *) &serverAddr,sizeof(serverA
  printf("\ncannot bind stream socket error, port = %d",PORT);
  exit(1); }
if(debug_msg)
 printf("\nbind socket ok...");
serverLen = sizeof(serverAddr);
if(getsockname(sock,(struc
  printf("getting socket name");
  exit(1); }
if(debug_msg)
 printf("\ngetsocketname ok...");
listen(sock,1);
if(debug_msg)
 printf("\nlistening for requests on socket %d...",PORT);
/* turn off alarming up front  */
signal(SIGINT, cleanup);
signal(SIGPIPE, SIG_IGN);
for(;;) {
do {
 clientLen= sizeof(clientAddr);
 msgsock = accept(sock, (struct sockaddr *) &clientAddr, &clientLen);
if(debug_msg) Â
printf("\nmsgsock=%d errno = %d errstr = %s",msgsock,errno,strerror
}while (msgsock <0 &&Â (errno == EINTR || errno == 32) );
if(msgsock <Â 0)
 if(debug_msg) {
  printf("\nsock accept error");
  exit (-1); }
Â
if(debug_msg)
 printf("\naccepted socket...");
i=readn(msgsock,inbuff, sizeof(inbuff));
if(debug_msg) {
 printf("\nreceived %d bytes",i);
 printf("\nstring = %s",inbuff); }
read_request();
close(msgsock);
}/* end for loop */
if(debug_msg)
printf("\nexiting do loop errno = %s",strerror(errno));
sockstat = close(msgsock);
exit(0);
}
/*************************
/*************************
/** this function  used to read "n" bytes from socket **/
int
readn(fd,ptr,nbytes)
register int fd;
register char *ptr;
register int nbytes;
{
int nleft,nread;
char terminator[2];
nleft = nbytes;
do {
nread = read(fd,ptr,nleft);
strncpy(terminator,ptr+(st
Â
if(nread <Â 0)
  return(nread);
else if (nread == 0)
  break;
nleft -= nread;
ptr  += nread;
/* *ptr ='\0'; */
if(debug_msg)
 printf("\nterminator = %s", ptr+(strlen(ptr)-2));
if(!strcmp(terminator,"^^"
{
 break;
}
} while(1);
return(nread);
}
/*************************
/* used to write "n" bytes */
int
writen(fd,ptr,nbytes)
register int fd;
register char *ptr;
register int nbytes;
{
int nleft, nwritten;
nleft = nbytes;
while(nleft >0) {
Â
nwritten = write(fd,ptr,nleft);
Â
if(nwritten <=0)
  return(nwritten);
 nleft -= nwritten;
 ptr  += nwritten;
}
return(nbytes - nleft);
}
/*************************
/********** read inputs points ******/
read_request(void)
{
int i,j;
char cmdType[3];
int cmdNum;
int status;
int count;
char strcount[5];
char field_name[2];
strncpy(cmdType,inbuff+0,2
cmdNum = atoi(cmdType);
cmdType[2]='\0';
/* whole point records */
if(cmdNum==0) {
update_timer(0);
Â
strncpy(strcount,inbuff+2,
strcount[4]='\0';
count = atoi(strcount);
numpoints = count;
if(debug_msg)
 printf("\nrequested to retreive %d points",count);
/* allocate memory based on number of points found */
/*indatap = malloc(count * sizeof(datarec)); */
if(debug_msg)
 printf("\nallocated %d memory structures for points",count);
j=6;
for (i = 1;i <=count; i++)
 {
strncpy(indatap[i].pn, inbuff+j,8);
j=j+8;
indatap[i].pn[8]='\0';
/* need to add error checking here later*/
status = SPD_get_sid(&file_desc,ind
status = SPD_get_point_info(&file_d
indatap[i].rt = point_info.rec_type;
if(debug_msg)
 printf("\nrt = %d",indatap[i].rt);
if(debug_msg)
 printf("\npopulated dynamic structure for %s (index = %d) stat = %d",indatap[i].pn,i,status
}
/* go and get whole point records if cmd type = 00*/
getpointrecords();
update_timer(1);
} /* end whole point record */
if(cmdNum== 2) {
update_timer(0);
strcpy(field_name,"CM");
byte_val = 14;
printf("\nnum points = %d",numpoints);
for(i=1;i<=numpoints;i++) Â {
status = SHC_change_byte_attribute(
if(debug_msg)
 printf("\nwrote ack bit for pn = %s, stat = %d", indatap[i].pn,status);
 }
update_timer(1);
} /* end write ack bit */
}
int getpointrecords()
{
int i;
int k;
unsigned char point_record[300];
char hh[2];
char hdrStr[6];
int status;
int bytesSent;
long retMsgCount;
char tempbuff[300];
int sendCounter;
/* build ret msg string in format of [cmd][index]data^^ Â */ Â
outbuff[0]='\0';
hdrStr[0]='\0';
sendCounter = 0;
/* cmdtype = 00 for whole point record ret */
sprintf(hdrStr,"%2s","00")
hdrStr[2]='\0';
strcpy(outbuff,hdrStr);
if(debug_msg)
printf("\nnumpoints = %d",numpoints);
for (i = 1;i <= numpoints; i++)
 {
  strcat(outbuff,"(");
  sprintf(hdrStr,"%04d",i); Â
  hdrStr[4]='\0';
  strcat(outbuff,hdrStr);
  tempbuff[0]='\0';
  status = SHC_get_point_record(&inda
  if(debug_msg)
  printf("\nretrieved record for %s (index = %d)",indatap[i].pn,i);
  for(k=0;k<128;k++) {
   sprintf(hh,"%02x",point_re
   strcat(tempbuff,hh);}
 Â
  strcat(outbuff,tempbuff);
  strcat(outbuff,")");
  if(sendCounter >= MAXRECORDSENDS) {
    outbuff[strlen(outbuff)] ='\0';
    bytesSent=writen(msgsock,(
   if(debug_msg  )
     printf("\ngoing to send back %d bytes",strlen(outbuff));
     /*  printf("\nstring = \n%s",outbuff);  */
      outbuff[0]='\0';
       sendCounter = 0; }
  else
       sendCounter = sendCounter +1;
 Â
} Â
/* tag ending message info */
  strcat(outbuff,"^^");
  retMsgCount = strlen(outbuff);
  outbuff[retMsgCount]='\0';
  /* send back the localbuff up to retMsgCount of len */
  if(debug_msg  ) {
   printf("\ngoing to send back %d bytes",retMsgCount);
   /* printf("\nstring = \n%s",outbuff); */ }
  bytesSent=writen(msgsock,(
  if(debug_msg)
   printf("\nwriten errno = %d, %s sent %d bytes over network",errno,strerror(er
init_struct();
}
checkforchanges()
{
int i;
char *modestr;
int status;
int bytesSent;
char tmpstr[20];
/* exceptions sent as CMD(PN_TOKEN=VALUE), ... */
/* clear out buffer */
/* don't let another timer hit if already in here */
/* while(1) { Â Â */
outbuff[0]='\0';
strcpy(outbuff,"01");
for (i=1;i<=numpoints;i++)
 {
modestr="";
 switch(indatap[i].rt) {
 case RECORD_TYPE_AI:
 case RECORD_TYPE_AL:
 case RECORD_TYPE_AC:
 case RECORD_TYPE_AM:
 modestr="Analog";
 status = SHC_get_analog_val_stat(&i
if(indatap[i].old_as != indatap[i].as) {
      strcat(outbuff,"(");
      strcat(outbuff,indatap[i].
      strcat(outbuff,"_AS=");
    sprintf(tmpstr,"%d",indata
    strcat(outbuff,tmpstr);
      strcat(outbuff,")");
 }
if(debug_msg &&Â indatap[i].old_as != indatap[i].as) Â
   printf("\nold as of %s = %d, new as val = %d",indatap[i].pn, indatap[i].old_as,indatap[
indatap[i].old_as = indatap[i].as;
 break;
 case RECORD_TYPE_DI:
 case RECORD_TYPE_DL:
 case RECORD_TYPE_DC:
 case RECORD_TYPE_DM:
 modestr="Digital";
 status = SHC_get_digital_val_stat(&
/* for testing only */
indatap[1].old_digital_sta
if(indatap[i].digital_stat
      strcat(outbuff,"(");
      strcat(outbuff,indatap[i].
      strcat(outbuff,"_DS=");
    sprintf(tmpstr,"%d",indata
    strcat(outbuff,tmpstr);
      strcat(outbuff,")");
}
if(debug_msg &&Â indatap[i].digital_stat != indatap[i].old_digital_sta
        printf("\nold ds of %s = %d, new ds = %d",indatap[i].pn, indatap[i].old_digital_sta
     Â
indatap[i].old_digital_sta
Â
break;
 break; }  /* end switch */
 }  /* next point, end for*/
 strcat(outbuff,"^^");
 outbuff[strlen(outbuff)]='
/* only send if string is greater than the default 00^^ */
if(strlen(outbuff) >Â 4) {
 bytesSent=writen(msgsock,(
  if(debug_msg)
   printf("\nwriten errno = %d, %s, sent %d bytes over network",errno,strerror(er
  }
if(errno == 32) {
if(debug_msg) Â
 printf("\nreceived EPIPE signal, closing socket, waiting...");
 close(msgsock);
 errno=0;
 return; }
/* Â sleep(SCANTIME); */
/* Â Â } Â Â while true */
}
Â
void update_timer(int signum)
{
if(signum == 0)
{ alarm(0);
 return;
}
if(debug_msg)
 printf("\nchecking for exceptions");
checkforchanges();
signal(SIGALRM,update_time
alarm(SCANTIME); Â
} Â
init_struct()
{
int i;
for(i=1;i<=numpoints;i++) {
    indatap[i].digital_val=0;
    indatap[i].old_digital_val
      indatap[i].digital_stat=0;
      indatap[i].old_digital_sta
      indatap[i].gp_val=0;
      indatap[i].old_gp_val=9;
      indatap[i].gp_stat=0;
      indatap[i].old_gp_stat=9;
      indatap[i].gp_force_stat=0
      indatap[i].old_gp_force_st
      indatap[i].av=0.00;
    indatap[i].old_av=99999.00
}
}
void cleanup(int sig_num)
{
 signal(SIGINT,cleanup);
 printf("\nexit gracefully\n\n\n...");
 fflush(stdout);
 sockstat = close(msgsock); Â
exit(0);
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
How do you know that the connection has been closed?
If you are trying to read from a connection which has been closed, read() returns 0 or -1 (correct me if I am wrong), and if you are trying to write to a non-existing connection, you get an EPIPE error.
When an interrupt comes, and you have not handled it properly the default action happens which may be closing the socket and thats why you are getting the bad file descriptor.
Could not check the code since it is too big.
If you are trying to read from a connection which has been closed, read() returns 0 or -1 (correct me if I am wrong), and if you are trying to write to a non-existing connection, you get an EPIPE error.
When an interrupt comes, and you have not handled it properly the default action happens which may be closing the socket and thats why you are getting the bad file descriptor.
Could not check the code since it is too big.
in your cleanup() function should be the last command
Also, why do you reinstall the signal handler when you exit anyway?