sc_eloop.c (5247B)
1 // in order: pollfd (single entry), opaque (may be NULL), fdcb(descriptor_t*, void*) 2 int descriptor_add (struct pollfd fd, void* opaque, 3 int (*fdcb)(descriptor_t*, short, void*)) 4 { 5 descriptor_t *descriptor = NULL; 6 7 HASH_FIND_INT(Descriptortab, &(fd.fd), descriptor); 8 if (descriptor != NULL) return (errno = EEXIST, FALSE); 9 // Otherwise... 10 descriptor = malloc(sizeof(descriptor_t)); // strong pointer; if we cannot add this to the hash, we must free it 11 descriptor->fd = fd; 12 descriptor->opaque = opaque; 13 descriptor->fdcb = fdcb; 14 HASH_ADD_INT(Descriptortab, fd.fd, descriptor); 15 return 1; // if we are returning at all, we have succeeded. 16 } 17 18 // in order: descriptortab, pollfd (single entry) 19 // returns true on success, false on nonexistent 20 int descriptor_del (struct pollfd fd) 21 { 22 descriptor_t *descriptor = NULL; 23 24 HASH_FIND_INT(Descriptortab, &(fd.fd), descriptor); 25 if (descriptor == NULL) return FALSE; 26 // Otherwise... 27 HASH_DEL(Descriptortab, descriptor); 28 free(descriptor); 29 return TRUE; // if we are returning at all, we have succeeded. 30 } 31 32 // in order: processtab, process ID, opaque to be passed to the report callback, report callback 33 int protege_add (pid_t pid, void* opaque, 34 int (*pdiecb)(process_t*, int, void*)) 35 { 36 process_t *protege = NULL; 37 38 HASH_FIND(hh, Protegetab, &pid, sizeof(pid_t), protege); 39 if (protege != NULL) return (errno = EEXIST, FALSE); 40 // Otherwise... 41 protege = malloc(sizeof(descriptor_t)); // strong pointer; if we cannot add this to the hash, we must free it 42 protege->pid = pid; 43 protege->opaque = opaque; 44 protege->pdiecb = pdiecb; 45 HASH_ADD(hh, Protegetab, pid, sizeof(pid_t), protege); 46 return 1; // if we are returning at all, we have succeeded. 47 } 48 // in order: descriptortab, pollfd (single entry) 49 // returns true on success, false on nonexistent 50 int protege_del (pid_t pid) 51 { 52 process_t *protege = NULL; 53 54 HASH_FIND(hh, Protegetab, &(pid), sizeof(pid_t), protege); 55 if (protege == NULL) return (errno = ENOENT, FALSE); 56 HASH_DEL(Protegetab, protege); 57 free(protege); 58 return TRUE; 59 } 60 61 // in order: dnsqtab, process ID, opaque to be passed to the report callback, report callback 62 int dnsq_add (uint16_t dnsqid, void* opaque, void* opaque2, 63 int (*qcb)(skadns_t*, dnsq_t*, void*, void*)) 64 { 65 dnsq_t *dnsq = NULL; 66 67 HASH_FIND(hh, Dnsqtab, &dnsqid, sizeof(uint16_t), dnsq); 68 if (dnsq != NULL) return (errno = EEXIST, FALSE); 69 // Otherwise... 70 dnsq = malloc(sizeof(dnsq_t)); // strong pointer; if we cannot add this to the hash, we must free it 71 dnsq->dnsq = dnsqid; 72 dnsq->opaque = opaque; 73 dnsq->opaque2 = opaque2; 74 dnsq->qcb = qcb; 75 HASH_ADD(hh, Dnsqtab, dnsq, sizeof(uint16_t), dnsq); 76 return TRUE; // if we are returning at all, we have succeeded. 77 } 78 // in order: dnsqtab, pollfd (single entry) 79 // returns true on success, false on nonexistent 80 int dnsq_del (uint16_t dnsqid) 81 { 82 dnsq_t *dnsq = NULL; 83 84 HASH_FIND(hh, Dnsqtab, &(dnsqid), sizeof(uint16_t), dnsq); 85 if (dnsq == NULL) return (errno = ENOENT, FALSE); 86 HASH_DEL(Dnsqtab, dnsq); 87 free(dnsq); 88 return TRUE; 89 } 90 91 int run_fds (tain *deadline, tain *stamp) 92 { 93 pfdAlloc fds = TA_ZERO; // pollfd 94 descriptor_t *des = NULL, *tmp = NULL; 95 struct pollfd *pfds = NULL; size_t pfdsiz = 0; size_t i = 0; 96 int pollret = 0; 97 HASH_ITER(hh, Descriptortab, des, tmp) { 98 if (!pfdalloc_catpfd(&fds, (des->fd))) temp_nomem(); 99 des->fd.revents = 0; 100 ++pfdsiz; 101 } 102 if (pfdsiz == 0) temp_runfds(); 103 des = NULL; tmp = NULL; 104 pfds = (struct pollfd *)(fds.pfd); 105 pollret = iopause_stamp(pfds, pfdsiz, deadline, stamp); 106 // and then we wait for iopause to do its thing 107 // and then iopause wakes us up 108 switch (pollret) { 109 case 0: 110 // we literally have nothing to do. we return. this isn't an error state. 111 return pollret; 112 break; 113 case -1: 114 // errors AGAIN, FAULT, INTR, INVAL 115 switch (errno) { 116 case EAGAIN: 117 return 0; // we will just get called again 118 break; 119 case EFAULT: 120 temp_fault(); 121 break; 122 case EINTR: 123 temp_intr(); // an uncaught signal has come our way 124 break; 125 case EINVAL: 126 temp_bug(); // invalid data 127 break; 128 } 129 default : 130 for (i = 0; i < pfdsiz; i++) { 131 HASH_FIND_INT(Descriptortab, &(pfds[i].fd), des); 132 if (des == NULL) { 133 temp_finderr(); // could not find the file descriptor in our tables - what kind of wiseguy do we have on here? 134 } 135 if (((pfds[i]).revents & POLLNVAL) != 0) { 136 // file descriptor is not known to the system; bug 137 temp_bug(); 138 } else if ((pfds[i]).revents != 0) { 139 (*(des->fdcb))(des, (pfds[i]).revents, des->opaque); 140 } 141 } 142 } 143 // done with fds now? right, we return the number of FDs we processed. 144 free((fds.pfd)); 145 return pollret; 146 } 147 148 int handledeadprocess () 149 { 150 process_t *protege = NULL; 151 pid_t pid = 0; 152 int wstat; 153 while ((pid = wait_nohang(&wstat)) > 0) { 154 HASH_FIND(hh, Protegetab, &pid, sizeof(pid_t), protege); 155 if (protege == NULL) continue; // doesn't really matter 156 (*protege->pdiecb)(protege, wstat, protege->opaque); 157 protege_del(pid); 158 } 159 return TRUE; 160 } 161 162 int checksignals (descriptor_t *descr, short revents, void* unused) 163 { 164 int sig; 165 sig = selfpipe_read(); 166 167 switch (sig) { 168 case SIGCHLD: 169 return handledeadprocess(); 170 break; 171 default : 172 return FALSE;// Advanced wiseguy shit 173 } 174 }