commit 605d962fa8505b8e72384ec0c91c85f83da4d7d6
parent 2f4242279fb029b463a4b41a3dff2d5c39a970da
Author: Ellenor Bjornsdottir <ellenor@umbrellix.net>
Date: Sat, 31 Dec 2022 16:38:38 +0000
this is something. I don't know what it is. Trying to extract sc_eloop out i guess
Diffstat:
3 files changed, 184 insertions(+), 0 deletions(-)
diff --git a/.indent.pro b/.indent.pro
@@ -0,0 +1 @@
+-nfcb -di1 -ldi1 -l1000 -npsl -c1
diff --git a/TODO.md b/TODO.md
@@ -2,4 +2,13 @@
## Task list
+### Done
+ * import certain libraries
+
+### Todo
+
+ * implement iolib
+ * implement npthread
+ * implement petter of cute girls (ok that's a lie but I need pets help)
+ * change licence of portions I am entitled to do so with
diff --git a/src/eloop/sc_eloop.c b/src/eloop/sc_eloop.c
@@ -0,0 +1,174 @@
+// in order: pollfd (single entry), opaque (may be NULL), fdcb(descriptor_t*, void*)
+int descriptor_add (struct pollfd fd, void* opaque,
+ int (*fdcb)(descriptor_t*, short, void*))
+{
+ descriptor_t *descriptor = NULL;
+
+ HASH_FIND_INT(Descriptortab, &(fd.fd), descriptor);
+ if (descriptor != NULL) return (errno = EEXIST, FALSE);
+ // Otherwise...
+ descriptor = malloc(sizeof(descriptor_t)); // strong pointer; if we cannot add this to the hash, we must free it
+ descriptor->fd = fd;
+ descriptor->opaque = opaque;
+ descriptor->fdcb = fdcb;
+ HASH_ADD_INT(Descriptortab, fd.fd, descriptor);
+ return 1; // if we are returning at all, we have succeeded.
+}
+
+// in order: descriptortab, pollfd (single entry)
+// returns true on success, false on nonexistent
+int descriptor_del (struct pollfd fd)
+{
+ descriptor_t *descriptor = NULL;
+
+ HASH_FIND_INT(Descriptortab, &(fd.fd), descriptor);
+ if (descriptor == NULL) return FALSE;
+ // Otherwise...
+ HASH_DEL(Descriptortab, descriptor);
+ free(descriptor);
+ return TRUE; // if we are returning at all, we have succeeded.
+}
+
+// in order: processtab, process ID, opaque to be passed to the report callback, report callback
+int protege_add (pid_t pid, void* opaque,
+ int (*pdiecb)(process_t*, int, void*))
+{
+ process_t *protege = NULL;
+
+ HASH_FIND(hh, Protegetab, &pid, sizeof(pid_t), protege);
+ if (protege != NULL) return (errno = EEXIST, FALSE);
+ // Otherwise...
+ protege = malloc(sizeof(descriptor_t)); // strong pointer; if we cannot add this to the hash, we must free it
+ protege->pid = pid;
+ protege->opaque = opaque;
+ protege->pdiecb = pdiecb;
+ HASH_ADD(hh, Protegetab, pid, sizeof(pid_t), protege);
+ return 1; // if we are returning at all, we have succeeded.
+}
+// in order: descriptortab, pollfd (single entry)
+// returns true on success, false on nonexistent
+int protege_del (pid_t pid)
+{
+ process_t *protege = NULL;
+
+ HASH_FIND(hh, Protegetab, &(pid), sizeof(pid_t), protege);
+ if (protege == NULL) return (errno = ENOENT, FALSE);
+ HASH_DEL(Protegetab, protege);
+ free(protege);
+ return TRUE;
+}
+
+// in order: dnsqtab, process ID, opaque to be passed to the report callback, report callback
+int dnsq_add (uint16_t dnsqid, void* opaque, void* opaque2,
+ int (*qcb)(skadns_t*, dnsq_t*, void*, void*))
+{
+ dnsq_t *dnsq = NULL;
+
+ HASH_FIND(hh, Dnsqtab, &dnsqid, sizeof(uint16_t), dnsq);
+ if (dnsq != NULL) return (errno = EEXIST, FALSE);
+ // Otherwise...
+ dnsq = malloc(sizeof(dnsq_t)); // strong pointer; if we cannot add this to the hash, we must free it
+ dnsq->dnsq = dnsqid;
+ dnsq->opaque = opaque;
+ dnsq->opaque2 = opaque2;
+ dnsq->qcb = qcb;
+ HASH_ADD(hh, Dnsqtab, dnsq, sizeof(uint16_t), dnsq);
+ return TRUE; // if we are returning at all, we have succeeded.
+}
+// in order: dnsqtab, pollfd (single entry)
+// returns true on success, false on nonexistent
+int dnsq_del (uint16_t dnsqid)
+{
+ dnsq_t *dnsq = NULL;
+
+ HASH_FIND(hh, Dnsqtab, &(dnsqid), sizeof(uint16_t), dnsq);
+ if (dnsq == NULL) return (errno = ENOENT, FALSE);
+ HASH_DEL(Dnsqtab, dnsq);
+ free(dnsq);
+ return TRUE;
+}
+
+int run_fds (tain *deadline, tain *stamp)
+{
+ pfdAlloc fds = TA_ZERO; // pollfd
+ descriptor_t *des = NULL, *tmp = NULL;
+ struct pollfd *pfds = NULL; size_t pfdsiz = 0; size_t i = 0;
+ int pollret = 0;
+ HASH_ITER(hh, Descriptortab, des, tmp) {
+ if (!pfdalloc_catpfd(&fds, (des->fd))) temp_nomem();
+ des->fd.revents = 0;
+ ++pfdsiz;
+ }
+ if (pfdsiz == 0) temp_runfds();
+ des = NULL; tmp = NULL;
+ pfds = (struct pollfd *)(fds.pfd);
+ pollret = iopause_stamp(pfds, pfdsiz, deadline, stamp);
+ // and then we wait for iopause to do its thing
+ // and then iopause wakes us up
+ switch (pollret) {
+ case 0:
+ // we literally have nothing to do. we return. this isn't an error state.
+ return pollret;
+ break;
+ case -1:
+ // errors AGAIN, FAULT, INTR, INVAL
+ switch (errno) {
+ case EAGAIN:
+ return 0; // we will just get called again
+ break;
+ case EFAULT:
+ temp_fault();
+ break;
+ case EINTR:
+ temp_intr(); // an uncaught signal has come our way
+ break;
+ case EINVAL:
+ temp_bug(); // invalid data
+ break;
+ }
+ default :
+ for (i = 0; i < pfdsiz; i++) {
+ HASH_FIND_INT(Descriptortab, &(pfds[i].fd), des);
+ if (des == NULL) {
+ temp_finderr(); // could not find the file descriptor in our tables - what kind of wiseguy do we have on here?
+ }
+ if (((pfds[i]).revents & POLLNVAL) != 0) {
+ // file descriptor is not known to the system; bug
+ temp_bug();
+ } else if ((pfds[i]).revents != 0) {
+ (*(des->fdcb))(des, (pfds[i]).revents, des->opaque);
+ }
+ }
+ }
+ // done with fds now? right, we return the number of FDs we processed.
+ free((fds.pfd));
+ return pollret;
+}
+
+int handledeadprocess ()
+{
+ process_t *protege = NULL;
+ pid_t pid = 0;
+ int wstat;
+ while ((pid = wait_nohang(&wstat)) > 0) {
+ HASH_FIND(hh, Protegetab, &pid, sizeof(pid_t), protege);
+ if (protege == NULL) continue; // doesn't really matter
+ (*protege->pdiecb)(protege, wstat, protege->opaque);
+ protege_del(pid);
+ }
+ return TRUE;
+}
+
+int checksignals (descriptor_t *descr, short revents, void* unused)
+{
+ int sig;
+ sig = selfpipe_read();
+
+ switch (sig) {
+ case SIGCHLD:
+ return handledeadprocess();
+ break;
+ default :
+ return FALSE;// Advanced wiseguy shit
+ }
+}