void ekg_loop() { g_main_context_iteration(NULL, FALSE); { #ifdef WATCHES_FIXME { /* przejrzyj deskryptory */ list_t l; for (l = watches; l; l = l->next) { watch_t *w = l->data; if (!w) continue; if (!FD_ISSET(w->fd, &rd) && !FD_ISSET(w->fd, &wd)) { /* timeout checking */ if (w->timeout < 1 || (tv.tv_sec - w->started) < w->timeout) continue; w->removed = -1; if (w->buf) { int (*handler)(int, int, char*, void*) = w->handler; if (handler(2, w->fd, NULL, w->data) == -1 || w->removed == 1) { w->removed = 0; watch_free(w); continue; } } else { int (*handler)(int, int, int, void*) = w->handler; if (handler(2, w->fd, w->type, w->data) == -1 || w->removed == 1) { w->removed = 0; watch_free(w); continue; } } w->removed = 0; continue; } if (w->fd == 0) { session_t *s; for (s = sessions; s; s = s->next) { if (!s->connected || !s->autoaway) continue; if (session_int_get(s, "auto_back") == 2) command_exec(NULL, s, ("/_autoback"), 2); } } } } #endif } #undef tv return; }
int watch_remove(plugin_t *plugin, int fd, watch_type_t type) { int res = -1; watch_t *w; /* XXX, here can be deadlock feel warned. */ while ((w = watch_find(plugin, fd, type))) { watch_free(w); res = 0; } return res; }
void watch_handle(watch_t *w) { int (*handler)(int, int, int, void *); int res; if (!w || w->removed == -1) /* watch is running in another thread / context */ return; w->removed = -1; handler = w->handler; res = handler(0, w->fd, w->type, w->data); if (res == -1 || w->removed == 1) { w->removed = 0; watch_free(w); return; } w->started = time(NULL); w->removed = 0; }
/* ripped from irc plugin */ int watch_handle_write(watch_t *w) { int (*handler)(int, int, const char *, void *) = w->handler; int res = -1; int len = (w && w->buf) ? w->buf->len : 0; if (!w || w->removed == -1) return -1; /* watch is running in another thread / context */ if (w->transfer_limit == -1) return 0; /* transfer limit turned on, don't send anythink... XXX */ debug_io("[watch_handle_write] fd: %d in queue: %d bytes.... ", w->fd, len); if (!len) return -1; w->removed = -1; if (handler) { res = handler(0, w->fd, w->buf->str, w->data); } else { #ifdef NO_POSIX_SYSTEM res = send(w->fd, w->buf->str, len, 0 /* MSG_NOSIGNAL */); #else res = write(w->fd, w->buf->str, len); #endif } debug_io(" ... wrote:%d bytes (handler: 0x%x) ", res, handler); if (res == -1 && #ifdef NO_POSIX_SYSTEM (WSAGetLastError() != 666) #else 1 #endif ) { #ifdef NO_POSIX_SYSTEM debug("WSAError: %d\n", WSAGetLastError()); #else debug("Error: %s %d\n", strerror(errno), errno); w->removed = 0; watch_free(w); #endif return -1; } if (res > len) { /* use debug_fatal() */ /* debug_fatal() should do: * - print this info to all open windows with RED color * - change some variable 'ekg2_need_restart' to 1. * - @ ncurses if we have ekg2_need_restart set, and if colors turned on, change from blue to red.. * - and do other happy stuff. * * XXX, implement and use it. It should be used as ASSERT() */ debug_error("watch_write(): handler returned bad value, 0x%x vs 0x%x\n", res, len); res = len; } else if (res < 0) { debug_error("watch_write(): handler returned negative value other than -1.. XXX\n"); res = 0; } string_remove(w->buf, res); debug_io("left: %d bytes\n", w->buf->len); w->removed = 0; return res; }
/* * watch_handle_line() * * obs³uga deskryptorów przegl±danych WATCH_READ_LINE. */ void watch_handle_line(watch_t *w) { char buf[1024], *tmp; int ret, res = 0; int (*handler)(int, int, const char *, void *) = w->handler; if (!w || w->removed == -1) return; /* watch is running in another thread / context */ w->removed = -1; #ifndef NO_POSIX_SYSTEM ret = read(w->fd, buf, sizeof(buf) - 1); #else ret = recv(w->fd, buf, sizeof(buf) - 1, 0); if (ret == -1 && WSAGetLastError() == WSAENOTSOCK) { printf("recv() failed Error: %d, using ReadFile()", WSAGetLastError()); res = ReadFile(w->fd, &buf, sizeof(buf)-1, &ret, NULL); printf(" res=%d ret=%d\n", res, ret); } res = 0; #endif if (ret > 0) { buf[ret] = 0; string_append(w->buf, buf); #ifdef NO_POSIX_SYSTEM printf("RECV: %s\n", buf); #endif } if (ret == 0 || (ret == -1 && errno != EAGAIN)) string_append_c(w->buf, '\n'); while ((tmp = xstrchr(w->buf->str, '\n'))) { size_t strlen = tmp - w->buf->str; /* get len of str from begining to \n char */ char *line = xstrndup(w->buf->str, strlen); /* strndup() str with len == strlen */ /* we strndup() str with len == strlen, so we don't need to call xstrlen() */ if (strlen > 1 && line[strlen - 1] == '\r') line[strlen - 1] = 0; if ((res = handler(0, w->fd, line, w->data)) == -1) { xfree(line); break; } string_remove(w->buf, strlen + 1); xfree(line); } /* je¶li koniec strumienia, lub nie jest to ci±g³e przegl±danie, * zwolnij pamiêæ i usuñ z listy */ if (res == -1 || ret == 0 || (ret == -1 && errno != EAGAIN) || w->removed == 1) { int fd = w->fd; w->removed = 0; watch_free(w); close(fd); return; } w->removed = 0; }
/* * plugin_unregister() * * od³±cza wtyczkê. * * 0/-1 */ int plugin_unregister(plugin_t *p) { /* XXX eXtreme HACK warning * (mp) na razie jest tak. docelowo: wyladowywac pluginy tylko z * glownego programu (queriesami?) * to cos segfaultowalo (wczesniej czy pozniej), jesli bylo wywolane z * ncurses. niestety, problem pozostaje dla innych pluginow i takiego * np. rc. sie zrobi nast razem */ /* j/w If any plugin has backtrace here, and we try to remove it from memory. * ekg2 do SEGV. */ struct timer *t; session_t *s; query_t **ll; variable_t *v; command_t *c; list_t l; if (!p) return -1; /* XXX think about sequence of unloading....: currently: watches, timers, sessions, queries, variables, commands */ for (l = watches; l; l = l->next) { watch_t *w = l->data; if (w && w->plugin == p) watch_free(w); } for (t = timers; t; t = t->next) { if (t->plugin == p) t = timers_removei(t); } for (s = sessions; s; ) { session_t *next = s->next; if (s->plugin == p) session_remove(s->uid); s = next; } for (ll = queries; ll <= &queries[QUERY_EXTERNAL]; ll++) { query_t *q; for (q = *ll; q; ) { query_t *next = q->next; if (q->plugin == p) query_free(q); q = next; } } for (v = variables; v; v = v->next) { if (v->plugin == p) v = variables_removei(v); } for (c = commands; c; c = c->next) { if (c->plugin == p) c = commands_removei(c); } plugins_unlink(p); return 0; }