Completed node.js wmiir convenience library.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// wmiir controller module | |
// Adam R. Nelson | |
// August 2013 | |
var spawn = require('child_process').spawn; | |
// Spawns and returns a child process that runs `wmiir read`. | |
// The callback takes two parameters: (err, line). | |
// It is called once for each line in the file read. | |
// - err is any error that occurred, or null if no error occurred. | |
// - line is the last line read from the file. | |
exports.read = function(path, callback) { | |
// Start the process. | |
var child = spawn('wmiir', ['read', path]); | |
// Record the error stream, so that any error messages that wmiir produces | |
// can be passed on to the callback. | |
var stderr=""; | |
child.stderr.on('data', function(chunk) {stderr += chunk;}); | |
// If there's an error, pass it to the callback. | |
child.on('error', function(err) {if (callback) callback(err);}); | |
// Read from the process's stdout until a newline is encountered, then pass | |
// the line to the callback. | |
var line=""; | |
function handleData(chunk) { | |
try { | |
// Data from stdout is usually returned in the form of a Buffer, | |
// not a String. Make sure to convert it. | |
if (chunk instanceof Buffer) | |
chunk = chunk.toString(); | |
// If a newline is encountered, call the callback with everything | |
// that was read up until the newline. | |
var newline = chunk.indexOf('\n'); | |
if (newline > -1) { | |
if (callback) callback(null, line + chunk.slice(0, newline)); | |
line = ""; | |
var remaining = chunk.slice(newline+1); | |
if (remaining.length > 0) | |
handleData(remaining); | |
} else { | |
// Otherwise, store the output for later. | |
line += chunk; | |
} | |
} catch (e) { | |
if (callback) callback(e); | |
callback = null; | |
child.kill(); | |
} | |
} | |
child.stdout.on('data', handleData); | |
// If the process exits with a nonzero exit code, throw an error with the | |
// content of stderr, which should contain a message. | |
child.on('exit', function(code, signal) { | |
if (code !== 0) { | |
if (callback) callback(new Error(stderr)); | |
} | |
// Also, make sure to return the last line read, if there was one. | |
else if (line !== "") { | |
if (callback) callback(null, line); | |
} | |
}); | |
// Return the child process, as a handle in case we need to kill it. | |
return child; | |
}; | |
// Spawns and returns a child process that runs `wmiir write`. | |
// The given data is sent to this process's stdin. | |
// The callback takes one parameter: (err). | |
// - err is any error that occurred, or null if no error occurred. | |
exports.write = function(path, data, callback) { | |
// Some of this is the same as `read`, so I'll only comment the parts that | |
// are different. | |
var child = spawn('wmiir', ['write', path]); | |
var stderr=""; | |
child.stderr.on('data', function(line) {stderr += line;}); | |
child.on('error', function(err) {if (callback) callback(err);}); | |
child.on('exit', function(code, signal) { | |
if (code === 0) { | |
// If the process exits normally, execute the callback. | |
if (callback) callback(null); | |
} else { | |
if (callback) callback(new Error(stderr)); | |
} | |
}); | |
// Write the data to the file. | |
// This closes stdin, which should also terminate the child process. | |
child.stdin.end(data); | |
return child; | |
}; | |
// Spawns and returns a child process that runs `wmiir ls`. | |
// The callback takes two parameters: (err, results). | |
// - err is any error that occurred, or null if no error occurred. | |
// - results is the full output from the process's stdout. | |
exports.ls = function(path, callback) { | |
var child = spawn('wmiir', ['ls', path]); | |
var stdout = "", stderr=""; | |
child.stdout.on('data', function(chunk) {stdout += chunk;}); | |
child.stderr.on('data', function(chunk) {stderr += chunk;}); | |
child.on('error', function(err) {if (callback) callback(err);}); | |
child.on('exit', function(code, signal) { | |
if (code === 0) { | |
if (callback) callback(null, stdout); | |
} else { | |
if (callback) callback(new Error(stderr)); | |
} | |
}); | |
return child; | |
}; | |
// Spawns and returns a child process that runs `wmiir create`. | |
// The given data is sent to this process's stdin. | |
// The callback takes one parameter: (err). | |
// - err is any error that occurred, or null if no error occurred. | |
exports.create = function(path, data, callback) { | |
var child = spawn('wmiir', ['create', path]); | |
var stderr=""; | |
child.stderr.on('data', function(chunk) {stderr += chunk;}); | |
child.on('error', function(err) {if (callback) callback(err);}); | |
child.on('exit', function(code, signal) { | |
if (code === 0) { | |
if (callback) callback(null); | |
} else { | |
if (callback) callback(new Error(stderr)); | |
} | |
}); | |
child.stdin.end(data); | |
return child; | |
}; | |
// Spawns and returns a child process that runs `wmiir remove`. | |
// The callback takes one parameter: (err). | |
// - err is any error that occurred, or null if no error occurred. | |
exports.remove = function(path, callback) { | |
var child = spawn('wmiir', ['remove', path]); | |
var stderr=""; | |
child.stderr.on('data', function(chunk) {stderr += chunk;}); | |
child.on('error', function(err) {if (callback) callback(err);}); | |
child.on('exit', function(code, signal) { | |
if (code === 0) { | |
if (callback) callback(null); | |
} else { | |
if (callback) callback(new Error(stderr)); | |
} | |
}); | |
return child; | |
}; | |
// Uses `wmiir setsid` to spawn a process that is not connected to the running | |
// wmii instance (in other words, it does not die when wmii is killed). Does | |
// not take a callback or return a handle to this process. | |
exports.setsid = function(/* varargs */) { | |
var args = Array.prototype.slice.call(arguments); | |
spawn('wmiir', ['setsid', '-f'].concat(args), {env: process.env}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment