mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 20:47:44 +00:00
160 lines
4.2 KiB
JavaScript
160 lines
4.2 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'];
|
|
|
|
const SYSTEM_PROPERTY_KEY_MAX = 32;
|
|
const SYSTEM_PROPERTY_VALUE_MAX = 92;
|
|
|
|
function debug(msg) {
|
|
dump('LogCapture.jsm: ' + msg + '\n');
|
|
}
|
|
|
|
let LogCapture = {
|
|
ensureLoaded: function() {
|
|
if (!this.ctypes) {
|
|
this.load();
|
|
}
|
|
},
|
|
|
|
load: function() {
|
|
// load in everything on first use
|
|
Components.utils.import('resource://gre/modules/ctypes.jsm', this);
|
|
|
|
this.libc = this.ctypes.open(this.ctypes.libraryName('c'));
|
|
|
|
this.read = this.libc.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.libc.declare('open',
|
|
this.ctypes.default_abi,
|
|
this.ctypes.int, // file descriptor (returned)
|
|
this.ctypes.char.ptr, // path
|
|
this.ctypes.int // flags
|
|
);
|
|
|
|
this.close = this.libc.declare('close',
|
|
this.ctypes.default_abi,
|
|
this.ctypes.int, // error code (returned)
|
|
this.ctypes.int // file descriptor
|
|
);
|
|
|
|
this.property_find_nth =
|
|
this.libc.declare("__system_property_find_nth",
|
|
this.ctypes.default_abi,
|
|
this.ctypes.voidptr_t, // return value: nullable prop_info*
|
|
this.ctypes.unsigned_int); // n: the index of the property to return
|
|
|
|
this.property_read =
|
|
this.libc.declare("__system_property_read",
|
|
this.ctypes.default_abi,
|
|
this.ctypes.void_t, // return: none
|
|
this.ctypes.voidptr_t, // non-null prop_info*
|
|
this.ctypes.char.ptr, // key
|
|
this.ctypes.char.ptr); // value
|
|
|
|
this.key_buf = this.ctypes.char.array(SYSTEM_PROPERTY_KEY_MAX)();
|
|
this.value_buf = this.ctypes.char.array(SYSTEM_PROPERTY_VALUE_MAX)();
|
|
},
|
|
|
|
cleanup: function() {
|
|
this.libc.close();
|
|
|
|
this.read = null;
|
|
this.open = null;
|
|
this.close = null;
|
|
this.property_find_nth = null;
|
|
this.property_read = null;
|
|
this.key_buf = null;
|
|
this.value_buf = null;
|
|
|
|
this.libc = null;
|
|
this.ctypes = null;
|
|
},
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
readLogFile: function(logLocation) {
|
|
this.ensureLoaded();
|
|
|
|
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;
|
|
},
|
|
|
|
/**
|
|
* Get all system properties as a dict with keys mapping to values
|
|
*/
|
|
readProperties: function() {
|
|
this.ensureLoaded();
|
|
let n = 0;
|
|
let propertyDict = {};
|
|
|
|
while(true) {
|
|
let prop_info = this.property_find_nth(n);
|
|
if(prop_info.isNull()) {
|
|
break;
|
|
}
|
|
|
|
// read the prop_info into the key and value buffers
|
|
this.property_read(prop_info, this.key_buf, this.value_buf);
|
|
let key = this.key_buf.readString();;
|
|
let value = this.value_buf.readString()
|
|
|
|
propertyDict[key] = value;
|
|
n++;
|
|
}
|
|
|
|
return propertyDict;
|
|
}
|
|
};
|
|
|
|
this.LogCapture = LogCapture;
|