2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "fvwm/fvwm.h"
26 #include "execcontext.h"
27 /* end of for CMD_ARGS */
32 /* end of for debug message */
34 /* for get_current_read_file */
44 /* for module syncronous */
45 #include "libs/ftime.h"
46 #include "libs/System.c"
47 #include "libs/envvar.h"
48 #include "libs/Parse.h"
49 #include "libs/Strings.h"
50 #include "libs/wild.h"
51 #include "libs/fvwmsignal.h"
55 /* for positive write */
57 #include "module_list.h"
58 #include "module_interface.h"
60 * Use POSIX behaviour if we can, otherwise use SysV instead
61 * should this be here?
64 # define O_NONBLOCK O_NDELAY
67 #define MOD_NOGRABMASK(m) ((m)->xNoGrabMask)
68 #define MOD_SYNCMASK(m) ((m)->xSyncMask)
78 /* the linked list pointers to the first and last modules */
79 static fmodule_list module_list
= NULL
;
80 /* keep to-be-deleted modules in a deathrow until they are deleted safely. */
81 static fmodule_list death_row
= NULL
;
86 static fmodule
*module_alloc(void);
87 static void module_free(fmodule
*module
);
90 * list handling functions
92 static inline void module_list_insert(fmodule
*module
, fmodule_list
*list
);
93 static inline fmodule
*module_list_remove(fmodule
*module
, fmodule_list
*list
);
94 static inline void module_list_destroy(fmodule_list
*list
);
95 static inline int module_list_len(fmodule_list
*list
);
97 static void KillModuleByName(char *name
, char *alias
);
98 static char *get_pipe_name(fmodule
*module
);
99 static void DeleteMessageQueueBuff(fmodule
*module
);
101 static inline void msg_mask_set(
102 msg_masks_t
*msg_mask
, unsigned long m1
, unsigned long m2
);
103 static void set_message_mask(msg_masks_t
*mask
, unsigned long msg
);
106 void module_kill_all(void)
108 module_list_destroy(&module_list
);
113 static fmodule
*module_alloc(void)
117 module
= (fmodule
*)safemalloc(sizeof(fmodule
));
118 MOD_SET_CMDLINE(module
, 0);
119 MOD_READFD(module
) = -1;
120 MOD_WRITEFD(module
) = -1;
121 fqueue_init(&MOD_PIPEQUEUE(module
));
122 msg_mask_set(&MOD_PIPEMASK(module
), DEFAULT_MASK
, DEFAULT_MASK
);
123 msg_mask_set(&MOD_NOGRABMASK(module
), 0, 0);
124 msg_mask_set(&MOD_SYNCMASK(module
), 0, 0);
125 MOD_NAME(module
) = NULL
;
126 MOD_ALIAS(module
) = NULL
;
131 /* closes the pipes and frees every data associated with a module record */
132 static void module_free(fmodule
*module
)
138 close(MOD_WRITEFD(module
));
139 close(MOD_READFD(module
));
141 if (MOD_NAME(module
) != NULL
)
143 free(MOD_NAME(module
));
145 if (MOD_ALIAS(module
) != NULL
)
147 free(MOD_ALIAS(module
));
149 while (!FQUEUE_IS_EMPTY(&(MOD_PIPEQUEUE(module
))))
151 DeleteMessageQueueBuff(module
);
158 static inline void module_list_insert(fmodule
*module
, fmodule_list
*list
)
160 fmodule_store
*new_store
;
161 DBUG("module_list_insert", "inserting module");
166 new_store
= (fmodule_store
*)safemalloc(sizeof(fmodule_store
));
167 new_store
->module
= module
;
168 new_store
->next
= *list
;
174 static inline fmodule
*module_list_remove(fmodule
*module
, fmodule_list
*list
)
176 fmodule_store
**position
;
184 position
= list
; *position
!= NULL
;
185 position
= &((*position
)->next
))
187 if ((*position
)->module
== module
)
190 fmodule_store
*current
;
192 DBUG("module_list_remove", "Removing from module list");
194 *position
= (*position
)->next
;
201 /* module not found */
202 DBUG("module_list_remove", "Tried to remove a not listed module!");
207 static inline void module_list_destroy(fmodule_list
*list
)
209 fmodule_store
*current
;
212 for (current
= *list
; current
!= NULL
; current
= next
)
214 next
= current
->next
;
215 module_free(current
->module
);
223 static fmodule
*do_execute_module(
224 F_CMD_ARGS
, Bool desperate
, Bool do_listen_only
)
226 int fvwm_to_app
[2], app_to_fvwm
[2];
227 int i
, val
, nargs
= 0;
236 extern char *ModulePath
;
238 FvwmWindow
* const fw
= exc
->w
.fw
;
245 args
= (char **)safemalloc(7 * sizeof(char *));
247 /* if (eventp->type != KeyPress) */
261 action
= GetNextToken(action
, &cptr
);
266 arg1
= searchPath(ModulePath
, cptr
, EXECUTABLE_EXTENSION
, X_OK
);
269 /* If this function is called in 'desparate' mode this means
270 * fvwm is trying a module name as a last resort. In this case
271 * the error message is inappropriate because it was most
272 * likely a typo in a command, not a module name. */
276 ERR
, "executeModule",
277 "No such module '%s' in ModulePath '%s'",
282 #ifdef REMOVE_EXECUTABLE_EXTENSION
286 p
= arg1
+ strlen(arg1
) - strlen(EXECUTABLE_EXTENSION
);
287 if (strcmp(p
, EXECUTABLE_EXTENSION
) == 0)
294 /* I want one-ended pipes, so I open two two-ended pipes,
295 * and close one end of each. I need one ended pipes so that
296 * I can detect when the module crashes/malfunctions */
297 if (do_listen_only
== True
)
302 else if (pipe(fvwm_to_app
) != 0)
304 fvwm_msg(ERR
, "executeModule", "Failed to open pipe");
307 if (pipe(app_to_fvwm
) != 0)
309 fvwm_msg(ERR
, "executeModule", "Failed to open pipe2");
313 fvwm_to_app
[0] >= fvwmlib_max_fd
||
314 fvwm_to_app
[1] >= fvwmlib_max_fd
||
315 app_to_fvwm
[0] >= fvwmlib_max_fd
||
316 app_to_fvwm
[1] >= fvwmlib_max_fd
)
318 fvwm_msg(ERR
, "executeModule", "too many open fds");
322 /* all ok, create the space and fill up */
323 module
= module_alloc();
325 MOD_NAME(module
) = stripcpy(cptr
);
327 sprintf(arg2
, "%d", app_to_fvwm
[1]);
328 sprintf(arg3
, "%d", fvwm_to_app
[0]);
329 sprintf(arg5
, "%lx", (unsigned long)win
);
330 sprintf(arg6
, "%lx", (unsigned long)exc
->w
.wcontext
);
334 args
[3] = (char *)get_current_read_file();
341 for (nargs
= 6; action
= GetNextToken(action
, &token
), token
; nargs
++)
343 args
= (char **)saferealloc(
344 (void *)args
, (nargs
+ 2) * sizeof(char *));
346 if (MOD_ALIAS(module
) == NULL
)
348 const char *ptr
= skipModuleAliasToken(args
[nargs
]);
350 if (ptr
&& *ptr
== '\0')
352 MOD_ALIAS(module
) = stripcpy(args
[nargs
]);
358 /* Try vfork instead of fork. The man page says that vfork is better!
360 /* Also, had to change exit to _exit() */
361 /* Not everyone has vfork! */
365 /* This fork remains running fvwm */
366 /* close appropriate descriptors from each pipe so
367 * that fvwm will be able to tell when the app dies */
368 close(app_to_fvwm
[1]);
369 /* dont't care that this may be -1 */
370 close(fvwm_to_app
[0]);
372 /* add these pipes to fvwm's active pipe list */
373 MOD_WRITEFD(module
) = fvwm_to_app
[1];
374 MOD_READFD(module
) = app_to_fvwm
[0];
376 &MOD_PIPEMASK(module
), DEFAULT_MASK
, DEFAULT_MASK
);
378 if (DoingCommandLine
)
380 /* add to the list of command line modules */
381 DBUG("executeModule", "starting commandline module\n");
382 MOD_SET_CMDLINE(module
, 1);
385 /* make the PositiveWrite pipe non-blocking. Don't want to jam
386 * up fvwm because of an uncooperative module */
387 if (MOD_WRITEFD(module
) >= 0)
389 fcntl(MOD_WRITEFD(module
), F_SETFL
, O_NONBLOCK
);
391 /* Mark the pipes close-on exec so other programs
392 * won`t inherit them */
393 if (fcntl(MOD_READFD(module
), F_SETFD
, 1) == -1)
396 ERR
, "executeModule",
397 "module close-on-exec failed");
400 MOD_WRITEFD(module
) >= 0 &&
401 fcntl(MOD_WRITEFD(module
), F_SETFD
, 1) == -1)
404 ERR
, "executeModule",
405 "module close-on-exec failed");
407 /* module struct is completed, insert into the list */
408 module_list_insert(module
, &module_list
);
410 for (i
= 6; i
< nargs
; i
++)
420 /* this is the child */
421 /* this fork execs the module */
422 #ifdef FORK_CREATES_CHILD
423 /* dont't care that this may be -1 */
424 close(fvwm_to_app
[1]);
425 close(app_to_fvwm
[0]);
427 fvmm_deinstall_signals();
434 visualid
, "FVWM_VISUALID=%lx",
435 XVisualIDFromVisual(Pvisual
));
436 flib_putenv("FVWM_VISUALID", visualid
);
437 sprintf(colormap
, "FVWM_COLORMAP=%lx", Pcmap
);
438 flib_putenv("FVWM_COLORMAP", colormap
);
442 flib_unsetenv("FVWM_VISUALID");
443 flib_unsetenv("FVWM_COLORMAP");
446 /* Why is this execvp?? We've already searched the module
450 ERR
, "executeModule", "Execution of module failed: %s",
453 close(app_to_fvwm
[1]);
454 /* dont't care that this may be -1 */
455 close(fvwm_to_app
[0]);
456 #ifdef FORK_CREATES_CHILD
462 fvwm_msg(ERR
, "executeModule", "Fork failed");
464 for (i
= 6; i
< nargs
; i
++)
493 /* dont't care that these may be -1 */
494 close(fvwm_to_app
[0]);
495 close(fvwm_to_app
[1]);
496 close(app_to_fvwm
[0]);
497 close(app_to_fvwm
[1]);
502 fmodule
*executeModuleDesperate(F_CMD_ARGS
)
506 m
= do_execute_module(F_PASS_ARGS
, True
, False
);
511 void module_kill(fmodule
*module
)
514 module_list_remove(module
, &module_list
), &death_row
);
519 /* free modules in the deathrow */
520 void module_cleanup(void)
522 module_list_destroy(&death_row
);
527 /* void module_send(fmodule *module, unsigned long *ptr, int size) */
528 /* This used to be marked "fvwm_inline". I removed this
529 when I added the lockonsend logic. The routine seems too big to
530 want to inline. dje 9/4/98 */
531 extern int myxgrabcount
; /* defined in libs/Grab.c */
532 extern char *ModuleUnlock
; /* defined in libs/Module.c */
533 void PositiveWrite(fmodule
*module
, unsigned long *ptr
, int size
)
535 extern int moduleTimeout
;
542 if (MOD_WRITEFD(module
) == -1)
546 if (!IS_MESSAGE_IN_MASK(&(MOD_PIPEMASK(module
)), ptr
[1]))
551 /* a dirty hack to prevent FvwmAnimate triggering during Recapture */
552 /* would be better to send RecaptureStart and RecaptureEnd messages. */
553 /* If module is lock on send for iconify message and it's an
554 * iconify event and server grabbed, then return */
555 mask
.m1
= (MOD_NOGRABMASK(module
).m1
& MOD_SYNCMASK(module
).m1
);
556 mask
.m2
= (MOD_NOGRABMASK(module
).m2
& MOD_SYNCMASK(module
).m2
);
557 if (IS_MESSAGE_IN_MASK(&mask
, ptr
[1]) && myxgrabcount
!= 0)
562 /* DV: This was once the AddToMessageQueue function. Since it was only
563 * called once, put it in here for better performance. */
565 mqueue_object_type
*c
;
567 c
= (mqueue_object_type
*)malloc(
568 sizeof(mqueue_object_type
) + size
);
571 fvwm_msg(ERR
, "PositiveWrite", "malloc failed\n");
576 c
->data
= (unsigned long *)(c
+ 1);
577 memcpy((void*)c
->data
, (const void*)ptr
, size
);
578 fqueue_add_at_end(&(MOD_PIPEQUEUE(module
)), c
);
581 /* dje, from afterstep, for FvwmAnimate, allows modules to sync with
582 * fvwm. this is disabled when the server is grabbed, otherwise
583 * deadlocks happen. M_LOCKONSEND has been replaced by a separated
584 * mask which defines on which messages the fvwm-to-module
585 * communication need to be lock on send. olicha Nov 13, 1999 */
586 /* migo (19-Aug-2000): removed !myxgrabcount to sync M_DESTROY_WINDOW
588 /* dv (06-Jul-2002): added the !myxgrabcount again. Deadlocks *do*
589 * happen without it. There must be another way to fix
590 * M_DESTROY_WINDOW handling in FvwmEvent. */
591 /*if (IS_MESSAGE_IN_MASK(&(MOD_SYNCMASK(module)), ptr[1]))*/
594 &(MOD_SYNCMASK(module
)), ptr
[1]) && !myxgrabcount
)
597 int channel
= MOD_READFD(module
);
598 struct timeval timeout
;
600 fmodule_input
*input
;
602 FlushMessageQueue(module
);
608 * We give the read a long timeout; if the module
609 * fails to respond within this time then it deserves
612 * NOTE: rather than impose an arbitrary timeout on the
613 * user, we will make this a configuration parameter.
617 timeout
.tv_sec
= moduleTimeout
;
620 FD_SET(channel
, &readSet
);
622 /* Wait for input to arrive on just one
623 * descriptor, with a timeout (fvwmSelect <= 0)
624 * or read() returning wrong size is bad news
627 channel
+ 1, &readSet
, NULL
, NULL
,
629 /* retry if select() failed with EINTR */
630 } while (rc
< 0 && !isTerminated
&& (errno
== EINTR
));
639 input
= module_receive(module
);
642 module_input_expect(input
,
643 ModuleUnlockResponse
))
645 module_input_discard(input
);
650 module_input_execute(input
);
658 name
= get_pipe_name(module
);
659 /* Doh! Something has gone wrong - get rid of
661 fvwm_msg(ERR
, "PositiveWrite",
662 "Failed to read descriptor from"
664 "- data available=%c\n"
665 "- terminate signal=%c\n",
667 (FD_ISSET(channel
, &readSet
) ?
669 isTerminated
? 'Y' : 'N');
675 /* Execute all messages from the module until UNLOCK is
676 * received N.B. This may cause recursion if a command
677 * results in a sync message to another module, which
678 * in turn may send a command that results in another
679 * sync message to this module.
680 * Hippo: I don't think this will cause deadlocks, but
681 * the third time we get here the first times UNLOCK
682 * will be read and then on returning up the third
683 * level UNLOCK will be read at the first level. This
684 * could be difficult to fix without turning queueing
685 * on. Turning queueing on may be bad because it can
686 * be useful for modules to be able to inject commands
687 * from modules in a synchronous manner. e.g.
688 * FvwmIconMan can tell FvwmAnimate to do an animation
689 * when a window is de-iconified from the IconMan,
690 * queueing make s this happen too late. */
697 fmodule_input
*module_receive(fmodule
*module
)
703 fmodule_input
*input
= NULL
;
705 n
= read(MOD_READFD(module
), &win
, sizeof(Window
));
706 if (n
< sizeof(Window
))
708 /* exit silently, module should have died.. */
712 n
= read(MOD_READFD(module
), &size
, sizeof(size
));
713 if (n
< sizeof(size
))
716 ERR
, "module_receive",
717 "Fail to read command size (Module: %p, read: %i, "
718 "size: %i)", module
, n
, (int)sizeof(size
));
722 if (size
> MAX_MODULE_INPUT_TEXT_LEN
)
724 fvwm_msg(ERR
, "module_receive",
725 "Module(%p) command is too big (%ld), limit is %d",
726 module
, size
, MAX_MODULE_INPUT_TEXT_LEN
);
727 /* The rest of the output from this module is going to be
728 * scrambled so let's kill it rather than risk interpreting
733 /* allocate all storage at once */
734 /* also save space for the '\0' termination character */
735 input
= (fmodule_input
*)safemalloc(
736 sizeof(fmodule_input
) + sizeof(char)*(size
+ 1));
738 input
->module
= module
;
740 input
->command
= (char*)input
+ sizeof(fmodule_input
);
742 n
= read(MOD_READFD(module
), input
->command
, size
);
746 ERR
, "module_receive",
747 "Fail to read command (Module: %p, read: %i, size:"
748 " %ld)", module
, n
, size
);
751 input
->command
[n
] = '\0';
752 n
= read(MOD_READFD(module
), &cont
, sizeof(cont
));
753 if (n
< sizeof(cont
))
755 fvwm_msg(ERR
, "module_receive",
756 "Module %p, Size Problems (read: %d, size: %d)",
757 module
, n
, (int)sizeof(cont
));
762 /* this is documented as a valid way for a module to quit
763 * so let's not complain */
770 module_input_discard(input
);
774 /* frees the module input data struct */
775 void module_input_discard(fmodule_input
*input
)
784 /* returns true if the module command matches "expect", false otherwise */
785 Bool
module_input_expect(fmodule_input
*input
, char *expect
)
787 if (input
== NULL
|| input
->command
== NULL
|| expect
== NULL
)
792 if (strncasecmp(input
->command
, expect
, strlen(expect
)) == 0)
794 /* the module sent the expected string */
801 void module_list_itr_init(fmodule_list_itr
*itr
)
808 fmodule
*module_list_itr_next(fmodule_list_itr
*itr
)
816 module
= (*itr
)->module
;
822 int module_list_len(fmodule_list
*list
)
825 fmodule_store
*current
=*list
;
826 while (current
!= NULL
)
828 current
= current
->next
;
835 static void KillModuleByName(char *name
, char *alias
)
837 fmodule_list_itr moditr
;
844 module_list_itr_init(&moditr
);
845 while ( (module
= module_list_itr_next(&moditr
)) != NULL
)
848 MOD_NAME(module
) != NULL
&&
849 matchWildcards(name
, MOD_NAME(module
)) &&
852 matchWildcards(alias
, MOD_ALIAS(module
)))))
861 static char *get_pipe_name(fmodule
*module
)
865 if (MOD_NAME(module
) != NULL
)
867 if (MOD_ALIAS(module
) != NULL
)
870 MOD_NAME(module
), " ", MOD_ALIAS(module
));
874 name
= MOD_NAME(module
);
879 name
= CatString3("(null)", "", "");
886 * returns a pointer inside a string (just after the alias) if ok or NULL
888 char *skipModuleAliasToken(const char *string
)
890 #define is_valid_first_alias_char(ch) (isalpha(ch) || (ch) == '/')
891 #define is_valid_alias_char(ch) (is_valid_first_alias_char(ch) \
892 || isalnum(ch) || (ch) == '-' || \
893 (ch) == '.' || (ch) == '/')
895 if (is_valid_first_alias_char(*string
))
899 while (*string
&& is_valid_alias_char(*string
))
901 if (++len
> MAX_MODULE_ALIAS_LEN
)
907 return (char *)string
;
911 #undef is_valid_first_alias_char
912 #undef is_valid_alias_char
915 /* message mask handling - does this belong here? */
917 static inline void msg_mask_set(
918 msg_masks_t
*msg_mask
, unsigned long m1
, unsigned long m2
)
927 * Sets the mask to the specific value. If M_EXTENDED_MSG is set in mask, the
928 * function operates only on the extended messages, otherwise it operates only
929 * on normal messages.
931 static void set_message_mask(msg_masks_t
*mask
, unsigned long msg
)
933 if (msg
& M_EXTENDED_MSG
)
935 mask
->m2
= (msg
& ~M_EXTENDED_MSG
);
948 static void DeleteMessageQueueBuff(fmodule
*module
)
950 mqueue_object_type
*obj
;
952 if (fqueue_get_first(&(MOD_PIPEQUEUE(module
)), (void **)&obj
) == 1)
954 /* remove from queue */
955 fqueue_remove_or_operate_from_front(
956 &(MOD_PIPEQUEUE(module
)), NULL
, NULL
, NULL
, NULL
);
957 /* we don't need to free the obj->data here because it's in the
958 * same malloced block as the obj itself. */
965 void FlushMessageQueue(fmodule
*module
)
967 extern int moduleTimeout
;
968 mqueue_object_type
*obj
;
977 while (fqueue_get_first(&(MOD_PIPEQUEUE(module
)), (void **)&obj
) == 1)
979 dptr
= (char *)obj
->data
;
980 while (obj
->done
< obj
->size
)
982 a
= write(MOD_WRITEFD(module
), &dptr
[obj
->done
],
983 obj
->size
- obj
->done
);
988 /* the write returns EWOULDBLOCK or EAGAIN if the pipe
989 * is full. (This is non-blocking I/O). SunOS returns
990 * EWOULDBLOCK, OSF/1 returns EAGAIN under these
991 * conditions. Hopefully other OSes return one of these
992 * values too. Solaris 2 doesn't seem to have a man
993 * page for write(2) (!) */
994 else if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
)
997 struct timeval timeout
;
998 int channel
= MOD_WRITEFD(module
);
1003 /* Wait until the pipe accepts further
1005 timeout
.tv_sec
= moduleTimeout
;
1006 timeout
.tv_usec
= 0;
1008 FD_SET(channel
, &writeSet
);
1010 channel
+ 1, NULL
, &writeSet
,
1012 /* retry if select() failed with EINTR
1014 } while ((rc
< 0) && !isTerminated
&&
1021 if (!FD_ISSET(channel
, &writeSet
))
1025 name
= get_pipe_name(module
);
1026 /* Doh! Something has gone wrong - get
1027 * rid of the offender! */
1029 ERR
, "FlushMessageQueue",
1030 "Failed to write descriptor to"
1033 "- terminate signal=%c\n",
1034 name
, rc
, isTerminated
?
1036 module_kill(module
);
1041 /* pipe accepts further input; continue */
1044 else if (errno
!= EINTR
)
1046 module_kill(module
);
1051 DeleteMessageQueueBuff(module
);
1057 void FlushAllMessageQueues(void)
1059 fmodule_list_itr moditr
;
1062 module_list_itr_init(&moditr
);
1063 while ( (module
= module_list_itr_next(&moditr
)) != NULL
)
1065 FlushMessageQueue(module
);
1071 /* empty, only here so that the signal handling initialization code is the
1072 * same for modules and fvwm */
1073 RETSIGTYPE
DeadPipe(int sig
)
1078 void CMD_Module(F_CMD_ARGS
)
1080 do_execute_module(F_PASS_ARGS
, False
, False
);
1085 void CMD_ModuleListenOnly(F_CMD_ARGS
)
1087 do_execute_module(F_PASS_ARGS
, False
, True
);
1092 void CMD_KillModule(F_CMD_ARGS
)
1097 action
= GetNextToken(action
,&name
);
1103 GetNextToken(action
, &alias
);
1104 KillModuleByName(name
, alias
);
1113 void CMD_ModuleSynchronous(F_CMD_ARGS
)
1118 char *expect
= ModuleFinishedStartupResponse
;
1124 Bool need_ungrab
= False
;
1125 char *escape
= NULL
;
1133 token
= PeekToken(action
, &next
);
1134 if (StrEquals(token
, "expect"))
1136 token
= PeekToken(next
, &next
);
1139 expect
= alloca(strlen(token
) + 1);
1140 strcpy(expect
, token
);
1143 token
= PeekToken(action
, &next
);
1145 if (token
&& StrEquals(token
, "timeout"))
1147 if (GetIntegerArguments(next
, &next
, &sec
, 1) > 0 && sec
> 0)
1149 /* we have a delay, skip the number */
1154 fvwm_msg(ERR
, "executeModuleSync", "illegal timeout");
1161 /* no module name */
1165 module
= do_execute_module(F_PASS_ARGS
, False
, False
);
1168 /* executing the module failed, just return */
1172 /* Busy cursor stuff */
1173 if (Scr
.BusyCursor
& BUSY_MODULESYNCHRONOUS
)
1175 if (GrabEm(CRS_WAIT
, GRAB_BUSY
))
1179 /* wait for module input */
1180 start_time
= time(NULL
);
1184 struct timeval timeout
;
1187 /* A signal here could interrupt the select call. We would
1188 * then need to restart our select, unless the signal was
1189 * a "terminate" signal. Note that we need to reinitialise
1190 * all of select's parameters after it has returned. */
1194 FD_ZERO(&out_fdset
);
1196 FD_SET(MOD_READFD(module
), &in_fdset
);
1198 if (!FQUEUE_IS_EMPTY(&MOD_PIPEQUEUE(module
)))
1200 FD_SET(MOD_WRITEFD(module
), &out_fdset
);
1203 timeout
.tv_usec
= 1;
1204 num_fd
= fvwmSelect(
1205 fvwmlib_max_fd
, &in_fdset
, &out_fdset
, 0,
1207 } while (num_fd
< 0 && !isTerminated
);
1209 /* Exit if we have received a "terminate" signal */
1217 if (FD_ISSET(MOD_READFD(module
), &in_fdset
))
1219 fmodule_input
* input
;
1221 /* Check for module input. */
1222 input
= module_receive(module
);
1225 module_input_expect(input
,expect
))
1227 module_input_discard(input
);
1232 module_input_execute(input
);
1237 if ((MOD_WRITEFD(module
) >= 0) &&
1238 FD_ISSET(MOD_WRITEFD(module
), &out_fdset
))
1240 FlushMessageQueue(module
);
1245 if (difftime(time(NULL
), start_time
) >= sec
&& sec
)
1251 /* Check for "escape function" */
1252 if (FPending(dpy
) &&
1253 FCheckMaskEvent(dpy
, KeyPressMask
, &tmpevent
))
1260 context
= GetContext(
1261 NULL
, exc
->w
.fw
, &tmpevent
, &w
);
1262 if (exc
->w
.fw
!= NULL
)
1264 class = &(exc
->w
.fw
->class);
1265 name
= exc
->w
.fw
->name
.name
;
1272 escape
= CheckBinding(
1273 Scr
.AllBindings
, STROKE_ARG(0)
1274 tmpevent
.xkey
.keycode
, tmpevent
.xkey
.state
,
1275 GetUnusedModifiers(), context
, BIND_KEYPRESS
,
1279 if (!strcasecmp(escape
,"escapefunc"))
1289 UngrabEm(GRAB_BUSY
);
1295 /* mask handling - does this belong here? */
1297 void CMD_set_mask(F_CMD_ARGS
)
1301 if (exc
->m
.module
== NULL
)
1305 if (!action
|| sscanf(action
, "%lu", &val
) != 1)
1309 set_message_mask(&(MOD_PIPEMASK(exc
->m
.module
)), (unsigned long)val
);
1314 void CMD_set_sync_mask(F_CMD_ARGS
)
1318 if (exc
->m
.module
== NULL
)
1322 if (!action
|| sscanf(action
,"%lu",&val
) != 1)
1326 set_message_mask(&(MOD_SYNCMASK(exc
->m
.module
)), (unsigned long)val
);
1331 void CMD_set_nograb_mask(F_CMD_ARGS
)
1335 if (exc
->m
.module
== NULL
)
1339 if (!action
|| sscanf(action
,"%lu",&val
) != 1)
1343 set_message_mask(&(MOD_NOGRABMASK(exc
->m
.module
)), (unsigned long)val
);