void FlushQueue(int module) { char *dptr; struct queue_buff_struct *d; int a; extern int errno; if ((pipeOn[module] <= 0) || (pipeQueue[module] == NULL)) return; while (pipeQueue[module] != NULL) { d = pipeQueue[module]; dptr = (char *) d->data; while (d->done < d->size) { a = write(writePipes[module], &dptr[d->done], d->size - d->done); if (a >= 0) d->done += a; /* the write returns EWOULDBLOCK or EAGAIN if the pipe is full. * (This is non-blocking I/O). SunOS returns EWOULDBLOCK, OSF/1 * returns EAGAIN under these conditions. Hopefully other OSes * return one of these values too. Solaris 2 doesn't seem to have * a man page for write(2) (!) */ else if ((errno == EWOULDBLOCK) || (errno == EAGAIN) || (errno == EINTR)) { return; } else { KillModule(module, 123); return; } } DeleteQueueBuff(module); } }
void KillModuleByName(char *name) { int i = 0; if (name == NULL) return; while (i < npipes) { if ((pipeName[i] != NULL) && (matchWildcards(name, pipeName[i]))) { KillModule(i, 10); } i++; } return; }
void HandleModuleInput(Window w, int channel) { char text[256]; int size; int cont, n; /* Already read a (possibly NULL) window id from the pipe, * Now read an fvwm bultin command line */ n = read(readPipes[channel], &size, sizeof(size)); if (n < sizeof(size)) { KillModule(channel, 1); return; } if (size > 255) { fvwm_msg(ERR, "HandleModuleInput", "Module command is too big (%d)", (void *) size); size = 255; } pipeOn[channel] = 1; n = read(readPipes[channel], text, size); if (n < size) { KillModule(channel, 2); return; } text[n] = 0; n = read(readPipes[channel], &cont, sizeof(cont)); if (n < sizeof(cont)) { KillModule(channel, 3); return; } if (cont == 0) { KillModule(channel, 4); } if (strlen(text) > 0) { extern int Context; FvwmWindow *tmp_win; /* first, check to see if module config line */ if (text[0] == '*') { AddToModList(text); return; } /* perhaps the module would like us to kill it? */ if (strncasecmp(text, "KillMe", 6) == 0) { KillModule(channel, 12); return; } /*Event.xany.type = ButtonRelease; hmmm... */ /* If a module does XUngrabPointer(), it can now get proper Popups */ if (strncasecmp(text, "popup", 5) == 0) Event.xany.type = ButtonPress; else Event.xany.type = ButtonRelease; Event.xany.window = w; if ((w == None) || (XFindContext(dpy, w, FvwmContext, (caddr_t *) &tmp_win) == XCNOENT)) { tmp_win = NULL; w = None; } if (tmp_win) { Event.xbutton.button = 1; Event.xbutton.x_root = tmp_win->frame_x; Event.xbutton.y_root = tmp_win->frame_y; Event.xbutton.x = 0; Event.xbutton.y = 0; Event.xbutton.subwindow = None; } else { Event.xbutton.button = 1; Event.xbutton.x_root = 0; Event.xbutton.y_root = 0; Event.xbutton.x = 0; Event.xbutton.y = 0; Event.xbutton.subwindow = None; } Context = GetContext(tmp_win, &Event, &w); ExecuteFunction(text, tmp_win, &Event, Context, channel); SendPacket(channel, M_FUNCTION_END, 1, 0, 0, 0, 0, 0, 0, 0); } return; }
/*************************************************************************** * * Waits for next X event, or for an auto-raise timeout. * ****************************************************************************/ int My_XNextEvent(Display *dpy, XEvent *event) { extern int fd_width, x_fd; fd_set in_fdset, out_fdset; Window targetWindow; int i; DBUG("My_XNextEvent","Routine Entered"); /* Do this IMMEDIATELY prior to select, to prevent any nasty * queued up X events from just hanging around waiting to be * flushed */ XFlush(dpy); if(XPending(dpy)) { DBUG("My_XNextEvent","taking care of queued up events & returning"); XNextEvent(dpy,event); StashEventTime(event); return 1; } DBUG("My_XNextEvent","no X events waiting - about to reap children"); /* Zap all those zombies! */ /* If we get to here, then there are no X events waiting to be processed. * Just take a moment to check for dead children. */ ReapChildren(); FD_ZERO(&in_fdset); FD_SET(x_fd,&in_fdset); FD_ZERO(&out_fdset); for(i=0; i<npipes; i++) { if(readPipes[i]>=0) { FD_SET(readPipes[i], &in_fdset); } if(pipeQueue[i]!= NULL) { FD_SET(writePipes[i], &out_fdset); } } DBUG("My_XNextEvent","waiting for module input/output"); XFlush(dpy); if (select((SELECT_TYPE_ARG1)fd_width, SELECT_TYPE_ARG234 &in_fdset, SELECT_TYPE_ARG234 &out_fdset, SELECT_TYPE_ARG234 0, SELECT_TYPE_ARG5 NULL) > 0) { /* Check for module input. */ for(i=0;i<npipes;i++) { if(readPipes[i] >= 0) { if(FD_ISSET(readPipes[i], &in_fdset)) { if( read(readPipes[i],&targetWindow, sizeof(Window)) >0 ) { DBUG("My_XNextEvent","calling HandleModuleInput"); HandleModuleInput(targetWindow,i); } else { DBUG("My_XNextEvent","calling KillModule"); KillModule(i,10); } } } if(writePipes[i] >= 0) { if(FD_ISSET(writePipes[i], &out_fdset)) { DBUG("My_XNextEvent","calling FlushQueue"); FlushQueue(i); } } } /* for */ } DBUG("My_XNextEvent","leaving My_XNextEvent"); return 0; }