Instantly share code, notes, and snippets.

@ar-nelson /wmiir.js
Last active Dec 21, 2015

Embed
What would you like to do?
Completed node.js wmiir convenience library.
// 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