rem: * So we better let /bin/sh to do that for us. -Dan
add: * So we better let /bin/sh to do that for us. Dan.
context: execCommand(WMenu *menu, WMenuEntry *entry){    char *cmdline;#if 0    char *path, *chr;#endif    cmdline = ExpandOptions(menu->frame->screen_ptr, (char*)entry->clientdata);#if 0    path = wstrdup(cmdline);    chr = strchr(path, ' ');    if (chr)	*chr = 0;        if (access(path, X_OK)!=0) {	path = realloc(path, strlen(cmdline)+128);	sprintf(path, _("Program \"%s\" not found or cannot be executed."),		cmdline);	wMessageDialog(menu->frame->screen_ptr, _("Error"), path, 		       _("OK"), NULL, NULL);	free(path);	free(cmdline);	return;    }        free(path);#endif    XGrabPointer(dpy, menu->frame->screen_ptr->root_win, True, 0,		 GrabModeAsync, GrabModeAsync, None, wCursor[WCUR_WAIT],		 CurrentTime);    XSync(dpy, 0);    if (cmdline) {        /* We should not use ParseCommand() here, because it does not handle         * correctly '~/' expansion and '>' redirection.         * While we can do '~/' expansion ourselves, we can do nothing about         * '>' redirection.         * So we better let /bin/sh to do that for us. -Dan	 * Ok. -Alfredo         */        if (fork()==0) {	    SetupEnvironment(menu->frame->screen_ptr);	    close(ConnectionNumber(dpy));#ifdef HAVE_SETPGID            setpgid(0, 0);#endif            execl("/bin/sh", "/bin/sh", "-c", cmdline, NULL);            exit(-1);        }	free(cmdline);    }    XUngrabPointer(dpy, CurrentTime);    XSync(dpy, 0);}