/*\ ||| Written By Fredrik Hübinette ||| All rights reserved. No warrenties, use at your own risk. ||| This source is distributed under the GNU GENERAL PUBLIC LICENCE, ||| see the file "COPYING" for more information. \*/ #include #include #include #include #include #include #include #include #include #include #include #include "plugger.h" /* * Helper functions */ void plugger_usleep(int usec) { struct timeval timeout; timeout.tv_sec=0; timeout.tv_usec=usec; select(0,0,0,0,&timeout); } int plugger_kill(int pid) { if(!kill(pid, SIGINT)) { /* we have failed to kill our children twice, * sleep on it and try again tomorrow.. */ D("killing %d\n",pid); plugger_usleep(4000); if(!kill(pid, SIGTERM)) { plugger_usleep(4000); if(!kill(pid, SIGTERM)) { /* We have failed to kill our children a third time - * wield nukes and try again. */ kill(pid, SIGKILL); } } } } int plugger_kill_group(int pid, int *status) { int e, s; static int signals[5] = { SIGINT, SIGTERM, SIGKILL, SIGKILL, SIGKILL }; for(s=0;s<5;s++) { D("Sending signal %d to %d\n",signals[s], -pid); if(kill(-pid, signals[s])) return 0; D("Waiting 1/10th of a second (in 0.02s increments)\n"); for(e=0;e<5;e++) { switch(waitpid(pid, status, WNOHANG)) { case -1: if(errno != EWOULDBLOCK && errno != EINTR) return 0; case 0: break; default: return 1; } plugger_usleep(20000); } } D("plugger_kill_group failed miserably!!!!!!\n"); return 0; } /* Check weather there is data to read on 'fd' */ int plugger_data_available(int fd) { fd_set tmp; struct timeval timeout; do { timeout.tv_sec=0; timeout.tv_usec=0; FD_ZERO(&tmp); FD_SET(fd, &tmp); } while(select(fd+1, &tmp, 0, 0, &timeout)<0 && errno==EINTR); return FD_ISSET(fd, &tmp); } int plugger_write(int fd, char *buffer, int len) { int written=0; while(written < len) { int i; do { i=write(fd,buffer + written, len-written); } while(i<0 && errno==EINTR); if(i<0) return written ? written : i; written+=i; } return written; } int plugger_read(int fd, char *buffer, int len) { int r=0; while(r < len) { int i; do { i=read(fd,buffer + r, len-r); } while(i<0 && errno==EINTR); if(i<0) return r ? r : i; r+=i; } return r; } char *plugger_strstr(char *s1,const char *s2) { for(;*s1;s1++) { const char *p1,*p2; for(p1=s1,p2=s2;*p2;p1++,p2++) if(*p2!=*p1) break; if(!*p2) return s1; } return NULL; }