зеркало из https://github.com/mozilla/gecko-dev.git
92 строки
2.4 KiB
JavaScript
92 строки
2.4 KiB
JavaScript
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||
|
/* jshint moz: true */
|
||
|
/* global Uint8Array, Components, dump */
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
this.EXPORTED_SYMBOLS = ['LogCapture'];
|
||
|
|
||
|
/**
|
||
|
* readLogFile
|
||
|
* Read in /dev/log/{{log}} in nonblocking mode, which will return -1 if
|
||
|
* reading would block the thread.
|
||
|
*
|
||
|
* @param log {String} The log from which to read. Must be present in /dev/log
|
||
|
* @return {Uint8Array} Raw log data
|
||
|
*/
|
||
|
let readLogFile = function(logLocation) {
|
||
|
if (!this.ctypes) {
|
||
|
// load in everything on first use
|
||
|
Components.utils.import('resource://gre/modules/ctypes.jsm', this);
|
||
|
|
||
|
this.lib = this.ctypes.open(this.ctypes.libraryName('c'));
|
||
|
|
||
|
this.read = this.lib.declare('read',
|
||
|
this.ctypes.default_abi,
|
||
|
this.ctypes.int, // bytes read (out)
|
||
|
this.ctypes.int, // file descriptor (in)
|
||
|
this.ctypes.voidptr_t, // buffer to read into (in)
|
||
|
this.ctypes.size_t // size_t size of buffer (in)
|
||
|
);
|
||
|
|
||
|
this.open = this.lib.declare('open',
|
||
|
this.ctypes.default_abi,
|
||
|
this.ctypes.int, // file descriptor (returned)
|
||
|
this.ctypes.char.ptr, // path
|
||
|
this.ctypes.int // flags
|
||
|
);
|
||
|
|
||
|
this.close = this.lib.declare('close',
|
||
|
this.ctypes.default_abi,
|
||
|
this.ctypes.int, // error code (returned)
|
||
|
this.ctypes.int // file descriptor
|
||
|
);
|
||
|
}
|
||
|
|
||
|
const O_READONLY = 0;
|
||
|
const O_NONBLOCK = 1 << 11;
|
||
|
|
||
|
const BUF_SIZE = 2048;
|
||
|
|
||
|
let BufType = this.ctypes.ArrayType(this.ctypes.char);
|
||
|
let buf = new BufType(BUF_SIZE);
|
||
|
let logArray = [];
|
||
|
|
||
|
let logFd = this.open(logLocation, O_READONLY | O_NONBLOCK);
|
||
|
if (logFd === -1) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
let readStart = Date.now();
|
||
|
let readCount = 0;
|
||
|
while (true) {
|
||
|
let count = this.read(logFd, buf, BUF_SIZE);
|
||
|
readCount += 1;
|
||
|
|
||
|
if (count <= 0) {
|
||
|
// log has return due to being nonblocking or running out of things
|
||
|
break;
|
||
|
}
|
||
|
for(let i = 0; i < count; i++) {
|
||
|
logArray.push(buf[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let logTypedArray = new Uint8Array(logArray);
|
||
|
|
||
|
this.close(logFd);
|
||
|
|
||
|
return logTypedArray;
|
||
|
};
|
||
|
|
||
|
let cleanup = function() {
|
||
|
this.lib.close();
|
||
|
this.read = this.open = this.close = null;
|
||
|
this.lib = null;
|
||
|
this.ctypes = null;
|
||
|
};
|
||
|
|
||
|
this.LogCapture = { readLogFile: readLogFile, cleanup: cleanup };
|