gpii-universal
Version:
Cross platform, core components of the GPII personalization infrastructure.
282 lines (263 loc) • 10.4 kB
JavaScript
/*!
GPII Process Reporter processes bridge, a component that encapsulates common
functions for retrieving information about OS processes with no requirement for
native (e.g., linux or windows) OS access.
Copyright 2014 Inclusive Design Research Centre, OCAD University
Licensed under the New BSD license. You may not use this file except in
compliance with this License.
You may obtain a copy of the License at
https://github.com/gpii/universal/LICENSE.txt
*/
"use strict";
var fluid = fluid || require("infusion");
var gpii = fluid.registerNamespace("gpii");
fluid.defaults("gpii.processes", {
gradeNames: ["fluid.component", "fluid.contextAware"],
contextAwareness: {
platform: {
checks: {
linux: {
contextValue: "{gpii.context.linux}",
gradeNames: "gpii.processes.linux"
},
windows: {
contextValue: "{gpii.context.windows}",
gradeNames: "gpii.processes.windows"
}
}
}
},
invokers: {
findSolutionsByCommands: {
funcName: "gpii.processes.findSolutionsByCommands",
args: ["{that}", "{arguments}.0"]
// array of command names
},
findSolutionsByPids: {
funcName: "gpii.processes.findSolutionsByPids",
args: ["{that}", "{arguments}.0"]
// array of pids (process ids)
},
findProcessByPid: {
funcName: "gpii.processes.findProcessByPid",
args: ["{that}", "{arguments}.0", "{arguments}.1"]
// pid, procArray [optional]
},
findProcessesByCommand: {
funcName: "gpii.processes.findProcessesByCommand",
args: ["{that}", "{arguments}.0", "{arguments}.1"]
// command, procArray [optional]
},
findFirstProcessByCommand: {
funcName: "gpii.processes.findFirstProcessByCommand",
args: ["{that}", "{arguments}.0", "{arguments}.1"]
// command, procArray [optional]
},
isRunning: {
funcName: "gpii.processes.isRunning",
args: ["{that}", "{arguments}.0"]
// state (string)
},
updateProcInfo: {
funcName: "gpii.processes.updateProcInfo",
args: ["{that}", "{arguments}.0"]
// process info structure
},
initProcInfoNotRunning: {
funcName: "gpii.processes.initProcInfoNotRunning",
args: ["{that}", "{arguments}.0"]
// command name (string)
},
getProcessPath: {
funcName: "gpii.processes.getProcessPath",
args: ["{that}", "{arguments}.0"]
// command name (string)
},
// Context aware invokers.
getProcessList : {
funcName: "gpii.processes.getProcessList",
args: ["{arguments}.0"]
// optional string or numeric identifier of the process
}
},
// True if process names are matched with differing case.
ignoreCase: false
});
/**
Return a list of process information objects corresponding to the names of each of the passed in commands. If
nothing is found, returns an empty array.
*
@param {Component} that - An instance of a processes component.
@param {Array<String>} commandNames - The names of the processes to inspect.
@return {Array} Array of procInfo objects for each command name. Empty if no processes are found.
*/
gpii.processes.findSolutionsByCommands = function (that, commandNames) {
return fluid.accumulate(commandNames, function (aCommand, matches) {
var procInfos = that.findProcessesByCommand(aCommand);
matches = matches.concat(procInfos);
return matches;
}, []);
};
/**
* Return an list of process information objects corresponding to the pids (process id numbers) passed in. If nothing
* is found, returns an empty array.
*
* @param {Component} that - An instance of a processes component.
* @param {Array<Number>} pids - The process ids of the processes to inspect.
* @return {Array<ProcInfo>} Array of procInfo objects for each pid. Empty if no corresponding processes are found.
*/
gpii.processes.findSolutionsByPids = function (that, pids) {
return fluid.accumulate(pids, function (aPid, matches) {
var found = that.findProcessByPid(aPid);
if (found !== null) {
matches.push(found);
}
return matches;
}, []);
};
/**
* Return a process information object corresponding to THE given process
* id (process id number). Returns null if there is no such process.
*
* @param {Component} that - An instance of a processes component.
* @param {Number} pid - The process id of the process to inspect.
* @param {Array<ProcInfo>} [procArray] - [optional] An array of process information objects to search.
* @return {ProcInfo} A process information object for the process with the given id. Returns null if there is no such process.
*/
gpii.processes.findProcessByPid = function (that, pid, procArray) {
if (!procArray) {
procArray = that.getProcessList(pid);
}
return fluid.find(procArray, function (procInfo) {
if (procInfo.pid === pid) {
return procInfo;
}
}, null);
};
/**
* Return the path of a running process.
*
* If the full path is not known (the process is running as another user), only the command is returned.
*
* @param {Component} that - an instance of a processes component.
* @param {Number} pid - the process id of the process.
* @return {String} - The full path of the process, or null if there's no matching process.
*/
gpii.processes.getProcessPath = function (that, pid) {
var proc = that.findProcessByPid(pid);
return proc && (proc.fullPath || proc.command);
};
/**
* Return a list of process information objects that match the given
* command name. Returns an empty array if not matching name is found.
*
* @param {Component} that - An instance of a processes component.
* @param {String} commandName - The name of the process to inspect.
* @param {Array<ProcInfo>} [procArray] - [optional] an array of process information objects to search.
* @return {Array<ProcInfo>} Array of procInfo objects matching the command name. Empty if no corresponding processes are found.
*/
gpii.processes.findProcessesByCommand = function (that, commandName, procArray) {
if (!procArray) {
procArray = that.getProcessList(commandName);
}
var commandNameLower = that.options.ignoreCase && commandName.toLowerCase();
return fluid.accumulate(procArray, function (aProcInfo, matchingProcs) {
var match = aProcInfo.command === commandName ||
(that.options.ignoreCase && aProcInfo.command.toLowerCase() === commandNameLower);
if (match) {
matchingProcs.push(aProcInfo);
}
return matchingProcs;
}, []);
};
/**
* Return the first process of an array of processes all with the same
* command name. If there are no matching names, return null.
*
* @param {Component} that - An instance of a processes component.
* @param {String} commandName - The name of the processe to inspect.
* @param {Array<ProcInfo>} [procArray] - [optional] An array of process information objects to search.
* @return {Object} A process information object for the process with the given id, null if there is no such process.
*/
gpii.processes.findFirstProcessByCommand = function (that, commandName, procArray) {
var commands = that.findProcessesByCommand(commandName, procArray);
if (commands.length > 0) {
return commands[0];
}
else {
return null;
}
};
// Map to reduce process state values into "Running" (= true) vs. "Not Running"
// (= false).
gpii.processes.stateToRunning = fluid.freezeRecursive({
"Running": true,
"Uninterruptible": true,
"Sleeping": true,
"Stopped": true,
"Zombie": false,
"NoSuchProcess": false
});
/**
* Determine if a process is running based on its native state.
*
* @param {Component} that - An instance of a processes component.
* @param {String} state - Native state of the process.
* @return {Boolean} Returns true if the process is running, false otherwise.
*/
gpii.processes.isRunning = function (that, state) {
return gpii.processes.stateToRunning[state];
};
/**
* Renew the information about a process, or create a new "no such process"
* information object.
*
* @param {Component} that - An instance of a processes component.
* @param {ProcInfo} procInfo - Latest information about a process.
* @return {ProcInfo} - Returns a new process information object about the process.
*/
gpii.processes.updateProcInfo = function (that, procInfo) {
var newProcInfo = null;
if (procInfo.state === "NoSuchProcess") {
newProcInfo =
that.findFirstProcessByCommand(procInfo.command);
}
else {
newProcInfo = that.findProcessByPid(procInfo.pid);
}
if (newProcInfo === null) {
newProcInfo =
that.initProcInfoNotRunning(procInfo.command);
}
return newProcInfo;
};
/**
* Create process information object for a not-running process.
*
* @param {Component} that - An instance of a processes component.
* @param {String} command - Name of the process.
* @return {ProcInfo} Returns a new process information object initialized as
* if the process is not running.
*/
gpii.processes.initProcInfoNotRunning = function (that, command) {
return fluid.freezeRecursive({
"command": command,
"pid": -1,
"ppid": -1,
"uid": -1,
"gid": -1,
"fullPath": "",
"argv": "",
"state": "NoSuchProcess"
});
};
/**
* Default function for the base 'gpii.processes' grade to return an empty list
* of process information objects.
*
* @param {Number|String} identifier - Optional process id number or command name of the process.
* @return {Array} Returns an empty list.
*/
gpii.processes.getProcessList = function (/* identifier */) {
return [];
};