int sconnect(char *addr,int port,char *laddr,int doproc,PSHANDLER hf,void *ha) { int idx,opt; struct sockaddr_in rem,loc; #define FAIL0(m) { clwarnx(m); return -1; } #define FAIL1(m) { sockerrmsg(m,0); return -1; } #define FAIL2(m) { sockerrmsg(m,0); goto free_sock; } #define FAIL3(m) { sockerrmsg(m,0); goto free_event; } #define FAILD(m) { sockerrmsg(m,1); return -1; } #ifdef WIN32 if (initsockets()<0) return -1; #endif if (!hf) return -1; for (idx=0;idx<NSOCK;idx++) if (!sockets[idx].inuse) break; if (idx==NSOCK) { clwarnx("too many open sockets"); return -1; } sockets[idx].handler=hf; sockets[idx].data=ha; sockets[idx].ilen=sockets[idx].olen=0; sockets[idx].lp=1; sockets[idx].lpevent=-1; sockets[idx].state=sNORMAL; sockets[idx].attr=7; sockets[idx].mode=SM_NORM; sockets[idx].opmode=doproc ? SM_NORM : SM_HALF; sockets[idx].type=RT_SOCK; sockets[idx].zsp=NULL; sockets[idx].rawin=sockets[idx].rawout=sockets[idx].procin=0; window_flush(); /* flush output before a long blocking operation */ memset(&rem,0,sizeof(rem)); rem.sin_family=AF_INET; rem.sin_port=htons((short)port); if ((rem.sin_addr.s_addr=inet_addr(addr))==INADDR_NONE) { struct hostent *hp=gethostbyname(addr); if (!hp) FAILD("can't get remote address"); memcpy(&rem.sin_addr,hp->h_addr,sizeof(rem.sin_addr)); } memcpy(&sockets[idx].remote,&rem,sizeof(sockets[idx].remote)); if (laddr) { int slen; char *cp,*buf; memset(&loc,0,sizeof(loc)); loc.sin_family=AF_INET; slen=strlen(laddr); for (cp=laddr+slen;cp>laddr;--cp) if (*cp==':') break; if (*cp==':') { buf=malloc(cp-laddr+1); if (!buf) FAIL0("out of memory"); memcpy(buf,laddr,cp-laddr); buf[cp-laddr]='\0'; ++cp; loc.sin_port=htons((short)atoi(cp)); } else buf=laddr; if ((loc.sin_addr.s_addr=inet_addr(buf))==INADDR_NONE) { struct hostent *hp=gethostbyname(buf); if (!hp) FAILD("can't get local address"); memcpy(&loc.sin_addr,hp->h_addr,sizeof(loc.sin_addr)); } if (buf!=laddr) free(buf); } if ((sockets[idx].sock=socket(PF_INET,SOCK_STREAM,0))<0) FAIL1("can't create socket"); if (laddr) if (bind(sockets[idx].sock,(struct sockaddr *)&loc,sizeof(loc))<0) FAIL2("can't bind socket"); #ifdef WIN32 if ((sockets[idx].event=CreateEvent(NULL,FALSE,FALSE,NULL))==NULL) { clwarn("can't create event"); goto free_sock; } if (WSAEventSelect(sockets[idx].sock,sockets[idx].event,FD_READ|FD_CLOSE|FD_CONNECT)) FAIL3("can't bind event to socket"); #endif #ifndef WIN32 { int flags=fcntl(sockets[idx].sock,F_GETFL,0); if (flags<0) FAIL3("can't get fd flags"); if (fcntl(sockets[idx].sock,F_SETFL,flags|O_NONBLOCK)<0) FAIL3("can't set fd flags"); } #endif opt=KERN_SOCKBUFSIZE; setsockopt(sockets[idx].sock,SOL_SOCKET,SO_RCVBUF,(void*)&opt,sizeof(opt)); /* ignore result */ if (connect(sockets[idx].sock,(struct sockaddr *)&rem,sizeof(rem))<0) { #ifdef WIN32 if (WSAGetLastError()!=WSAEWOULDBLOCK) #else if (errno!=EINPROGRESS) #endif FAIL3("can't connect to remote host"); sockets[idx].mode=SM_CONN; sockets[idx].inuse=1; } else { sockets[idx].inuse=1; if (sockets[idx].handler) sockets[idx].handler(idx,SCONN,sockets[idx].data,NULL,0); } return idx; free_event: #ifdef WIN32 CloseHandle(sockets[idx].event); #endif free_sock: closesocket(sockets[idx].sock); return -1; #undef FAIL0 #undef FAIL1 #undef FAIL2 #undef FAIL3 }
/* Try to get a good rough estimate of the free memory to speed up the calibration process */ unsigned int ActiveMemoryGetRoughlyFree(void) { FILE * file; char command[128]; char string[4096]; char * token; unsigned int field_free, memory_free; unsigned int index_token, free_value; strcpy(command, VMSTAT); if (strstr(command, "vmstat") == NULL) return 0; strcat(command, " 1 2"); field_free = 0; if ((file = popen(command, "r")) != NULL) { while (field_free == 0) { if (fgets(string, sizeof(string), file) != NULL) { token = strtok(string, VMSTAT_DELIM); index_token = 1; while ((token != NULL) && (field_free == 0)) { if ((field_free ==0) && (strcmp(token, VMSTAT_FREE) == 0)) field_free = index_token; index_token++; token = strtok(NULL, VMSTAT_DELIM); } } else break; } if (field_free == 0) FAIL2("ActiveMemoryGetRoughlyFree: Error in reading (%s): " "unable to find the field %s\n", command, VMSTAT_FREE); memory_free = 0; free_value = 0; sleep(1); while (fgets(string, sizeof(string), file) != NULL) { token = strtok(string, VMSTAT_DELIM); index_token = 1; while (token != NULL) { if (index_token == field_free) { if (sscanf(token, "%d", &free_value) != 1) { FAIL3("ActiveMemoryGetRoughlyFree: Error in reading (%s) from (%s):" "no valid FREE value in (%s)\n", command, string, token); } else memory_free = free_value*MEMSOR_UNIT; } index_token++; token = strtok(NULL, VMSTAT_DELIM); } } pclose(file); } else FAIL2("ActiveMemoryGetRoughlyFree: execution of %s failed (error %d)\n", command, errno); return memory_free; }
/* compute the total ammount of physical memory used it's the sum of the resident size of each processes this function parse the output of "PS PS_ARGS" */ unsigned int ActiveMemoryGetUsed(void) { FILE * file; char command[128]; char string[4096]; char * token; unsigned int field_status, field_rss, memory_used; unsigned int index_token, status_valid, rss_value; strcpy(command, PS); strcat(command, " "); strcat(command, PS_ARGS); if ((file = popen(command, "r")) != NULL) { field_status = 0; field_rss = 0; memory_used = 0; while ((field_status == 0) || (field_rss == 0)) { if (fgets(string, sizeof(string), file) != NULL) { token = strtok(string, PS_DELIM); index_token = 1; while (token != NULL) { if ((field_status ==0) && (strcmp(token, STATUS_FIELD) == 0)) field_status = index_token; if ((field_rss ==0) && (strcmp(token, RSS_FIELD) == 0)) field_rss = index_token; index_token++; token = strtok(NULL, PS_DELIM); } } else break; } if ((field_status == 0) || (field_rss == 0)) FAIL3("ActiveMemoryGetUsed: Error in reading (%s): " "unable to find the fields %s and %s\n", command, STATUS_FIELD, RSS_FIELD); memory_used = 0; while (fgets(string, sizeof(string), file) != NULL) { token = strtok(string, PS_DELIM); index_token = 1; status_valid = 0; while (token != NULL) { if (index_token == field_status) if (strpbrk(token, STATUS_VALID) != NULL) status_valid = 1; if ((status_valid) && (index_token == field_rss)) { if (sscanf(token, "%d", &rss_value) != 1) { FAIL3("ActiveMemoryGetUsed: Error in reading (%s) from (%s):" "no valid RSS value in (%s)\n", command, string, token); } else memory_used += rss_value*MEMSOR_UNIT; } index_token++; token = strtok(NULL, PS_DELIM); } } pclose(file); } else FAIL2("ActiveMemoryGetUsed: execution of %s failed (error %d)\n", command, errno); return memory_used; }
int RecvBytes(Socket sd, void *bytes, size_t byteSize, double timeOut) { double end; int isPipe; char *nextByte; fd_set readFds; int recvd; double start; int totalRecvd; struct timeval tout; void (*was)(int); isPipe = FD_ISSET(sd, &connectedPipes); FD_ZERO(&readFds); FD_SET(sd, &readFds); tout.tv_sec = (int)timeOut; tout.tv_usec = 0; start = CurrentTime(); was = signal(SIGALRM, RecvTimeOut); nextByte = (char *)bytes; for(totalRecvd = 0; totalRecvd < byteSize; totalRecvd += recvd) { recvd = 0; switch (select(FD_SETSIZE, &readFds, NULL, NULL, &tout)) { case -1: if(errno == EINTR) { end = CurrentTime(); if((int)(end - start) < timeOut) { tout.tv_sec = (int)(timeOut - (end - start)); continue; } } signal(SIGALRM, was); FAIL2("RecvBytes: select %d failed %s\n", sd, strerror(errno)); break; case 0: if(!isPipe) { end = CurrentTime(); SetPktTimeOut(sd, end - start, 1); } signal(SIGALRM, was); FAIL3("RecvBytes: timed out socket %d after %d/%fs\n", sd, tout.tv_sec, timeOut); break; default: SetRealTimer((unsigned int)timeOut); recvd = read(sd, nextByte, (size_t)(byteSize - totalRecvd)); RESETREALTIMER; if(recvd <= 0) { WARN3("RecvBytes: read() on descriptor %d returned %d (errno=%d).\n", sd, recvd, errno); if(!isPipe) { end = CurrentTime(); SetPktTimeOut(sd, end - start, 0); } signal(SIGALRM, was); FAIL5("RecvBytes: sd %d (addr:%s) failed with %s after %d of %d\n", sd, PeerName(sd), strerror(errno), totalRecvd, byteSize); } break; } nextByte += recvd; } return(1); }