launcher.cpp (3302B)
1 // Copyright (c) 2003 - 2009 Anselm R Garbe <anselm@garbe.us> 2 // See LICENSE for license details. 3 4 extern "C" { 5 #include <assert.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <sys/types.h> 9 #include <sys/wait.h> 10 #include <unistd.h> 11 #include <X11/Xlib.h> 12 } 13 14 #include <map> 15 16 #include "launcher.h" 17 18 #include "action.h" 19 #include "logger.h" 20 #include "kernel.h" 21 #include "monitor.h" 22 23 Launcher::Launcher() {} 24 Launcher::~Launcher() {} 25 26 void Launcher::exec(string command) { 27 28 Monitor *focusedMonitor = Kernel::instance()->focusedMonitor(); 29 30 if (fork() == 0) { 31 if (fork() == 0) { 32 setsid(); 33 34 close(ConnectionNumber(Kernel::instance()->display())); 35 36 putenv((char *)focusedMonitor->displayString().c_str()); 37 38 char **cmdArgs = Util::arguments(command); 39 40 LOGDEBUG("executing '" + command + "'"); 41 execvp(cmdArgs[0], cmdArgs); 42 LOGERROR("cannot execute '" + command + "'", true); 43 // exits WMI 44 } 45 exit(0); 46 } 47 wait(0); 48 } 49 50 void Launcher::execSeq(Action *caller, string command) { 51 52 MBindings *actionBindings = KERNEL->actionBindings(); 53 54 string cmd = command; 55 string actionName = ""; 56 string arguments = ""; 57 58 LOGDEBUG("sequence: got: " + cmd); 59 bool proceed = true; 60 for (string::iterator it = cmd.begin(); proceed; it++) { 61 62 proceed = it != cmd.end(); 63 if (!proceed || (*it == ',') ) { // proceed action 64 if (caller->id() == actionName) { // recursion detected 65 Logger::instance()->warning( 66 "sequence '" + actionName + 67 "' was called recursivly, stopped"); 68 return; 69 70 } 71 // argument fetching 72 unsigned int argCount = 0; 73 unsigned int argDelim = actionName.find_first_of('+'); 74 75 if (argDelim != string::npos) { 76 argCount++; // at least 1 argument 77 arguments = actionName.substr(argDelim + 1); 78 LOGDEBUG("sequence: got arguments: " + arguments); 79 actionName = actionName.substr(0, argDelim); 80 LOGDEBUG("sequence: found arguments: " + arguments); 81 LOGDEBUG("sequence: for action: " + actionName); 82 } 83 84 Action *action = Util::get(actionBindings, actionName); 85 if (!action) { 86 LOGWARN("unknown action '" + actionName + 87 "' cannot be performed sequentially"); 88 return; 89 } 90 if (action->promptsCount() != argCount) { 91 LOGWARN("action '" + actionName + 92 "' cannot be performed sequentially, because " 93 "to much or less given arguments."); 94 return; 95 } 96 if (!action->isValid()) { 97 LOGWARN("action '" + actionName + 98 "' cannot be performed because it" 99 " won't have any effect"); 100 return; 101 } 102 if (argCount) { 103 action->setArgument((char *)arguments.c_str()); 104 } 105 action->perform(); 106 actionName = ""; 107 } 108 else { 109 actionName += *it; 110 } 111 } 112 }