-
"Cannot make pipe"
Hello all,
The following code sits in the background and serves up stats when asked. This is for me client program, an RRDTOOL implementation that graphs these stats. Problem is, after the server sits there for a little while (4 hourse maybe?), I get the following error:
Code:
sh: cannot make pipe
sh: cannot make pipe
sh: cannot make pipe
sh: cannot make pipe
sh: cannot make pipe
sh: cannot make pipe
ld.so.1: sh: fatal: /usr/lib/libgen.so.1: Too many open files
ld.so.1: sh: fatal: /usr/lib/libgen.so.1: Too many open files
(and then it seg-faults)
I assume that perhaps I've missed a step in cleanup somewhere, but where? By the way, sorry, I know this code is somewhat bad-looking.
Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
char results1[100];
char results2[100];
char results3[100];
char results4[100];
char results5[100];
char results6[100];
char results7[100];
int i;
void error(char *msg)
{
perror(msg);
exit(1);
}
char *strltrim (const char *s) {
const char *p = s;
//WATT_ASSERT (s != NULL);
while (p[0] && p[1] && isspace(*p))
p++;
return (char*)p;
}
char *strrtrim (char *s) {
size_t n;
//WATT_ASSERT (s != NULL);
n = strlen (s);
while (n) {
if (!isspace(s[--n]))
break;
s[n] = '\0';
}
return (s);
}
char *rip (char *s)
{
char *p;
if ((p = strrchr(s,'\n')) != NULL) *p = '\0';
if ((p = strrchr(s,'\r')) != NULL) *p = '\0';
return (s);
}
void cpustats ( int state )
{
/* State 0: run the cmd
* State 1: user
* State 2: sys
* State 3: run
* State 4: block
* State 5: Real Mem
* State 6: Used Mem
*/
char cmd[100],buf[100];
FILE *f;
if (state==0) {
system("vmstat 1 2 >/tmp/vmstat");
} else if (state==1) {
sprintf(cmd,"cat /tmp/vmstat |gawk '{ print $13 }'|tail -1>/tmp/cpuuser");
system(cmd);
f = fopen("/tmp/cpuuser","r");
fgets(buf,sizeof(buf),f);
fclose(f);
strncpy(results1,rip(strrtrim(buf)),sizeof(results1));
} else if (state==2) {
sprintf(cmd,"cat /tmp/vmstat |gawk '{ print $14 }'|tail -1>/tmp/cpusys");
system(cmd);
f = fopen("/tmp/cpusys","r");
fgets(buf,sizeof(buf),f);
fclose(f);
strncpy(results2,rip(strrtrim(buf)),sizeof(results2));
} else if (state==3) {
sprintf(cmd,"cat /tmp/vmstat |gawk '{ print $1 }' |tail -1>/tmp/cpurun");
system(cmd);
f = fopen("/tmp/cpurun","r");
fgets(buf,sizeof(buf),f);
fclose(f);
strncpy(results3,rip(strrtrim(buf)),sizeof(results3));
} else if (state==4) {
sprintf(cmd,"cat /tmp/vmstat |gawk '{ print $2 }' |tail -1>/tmp/cpublock");
system(cmd);
f = fopen("/tmp/cpublock","r");
fgets(buf,sizeof(buf),f);
fclose(f);
strncpy(results4,rip(strrtrim(buf)),sizeof(results4));
} else if (state==5) {
sprintf(cmd,"prtdiag -v |grep Memory |gawk '{ print $3 }' >/tmp/cpurealmem");
system(cmd);
f = fopen("/tmp/cpurealmem","r");
fgets(buf,sizeof(buf),f);
fclose(f);
strncpy(results5,rip(strrtrim(buf)),sizeof(results5));
//i=strlen(results5);
//results5[i]="0";
//results5[i+1]="0";
//results5[i+2]="0";
//results5[i+3]='\x00';
} else if (state==6) {
sprintf(cmd,"cat /tmp/vmstat |gawk '{ print $5 }' |tail -1>/tmp/cpuusedmem");
system(cmd);
f = fopen("/tmp/cpuusedmem","r");
fgets(buf,sizeof(buf),f);
fclose(f);
strncpy(results6,rip(strrtrim(buf)),sizeof(results6));
} else if (state==6) {
sprintf(cmd,"netstat -s |grep ListenDrop |gawk '{ print $3 }'>/tmp/cpudrops");
system(cmd);
f = fopen("/tmp/cpudrops","r");
fgets(buf,sizeof(buf),f);
fclose(f);
strncpy(results7,rip(strrtrim(buf)),sizeof(results7));
}
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
char buffer[256],wbuffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
for (;;) {
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
strcpy(buffer,rip(buffer));
bzero(wbuffer,256);
cpustats(0);
cpustats(1);
cpustats(2);
cpustats(3);
cpustats(4);
cpustats(5);
cpustats(6);
sprintf(wbuffer,"%s %s %s %s %s %s",results1,results2,results3,results4,results5,results6);
n = write(newsockfd,wbuffer,strlen(wbuffer));
if (n < 0) error("ERROR writing to socket");
}
return 0;
}
Thanks again,
-
You never close any sockets. You only make new ones.
Quzah.
-
where in the loop should I close them?
Thanks,
-
OK, I put a:
but then, after one connect, I get:
Code:
ERROR on accept: Bad file number
So where should I put this close()?
-
You don't close your origional socket. You close the new one once you're done with it. It's just like hanging up a phone. You don't leave the phone off the hook when you're done talking. You hang it up.
Then, when your server is all done, and is shutting down, you close the origional.
Quzah.
-