Last active
August 29, 2015 14:06
-
-
Save Noitidart/f05ffde7dcaffe792a4d to your computer and use it in GitHub Desktop.
_ff-addon-snippet-LibC_fcntl - Working on getting fcntl to work to detect if profile is locked. (js-ctypes)
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
Cu.import('resource://gre/modules/ctypes.jsm'); | |
Cu.import('resource://gre/modules/osfile.jsm'); | |
function doit() { | |
if (OS.Constants.Sys.Name == 'Darwin') { | |
var _libc = ctypes.open('libc.dylib'); | |
} else if (OS.Constants.Sys.Name == 'Linux') { | |
var _libc = ctypes.open('libc.so.6'); | |
} | |
var lockFilePath = OS.Path.join(OS.Constants.Path.profileDir, '.parentlock'); | |
var lockFilePath = '/Users/noi/Library/Application Support/Firefox/Profiles/6myop6y5.Unnamed Profile 1/.parentlock'; | |
var lockFilePath = '/home/noi/.mozilla/firefox/b51cfon3.Unnamed Profile 1/.parentlock'; //up1 | |
//var lockFilePath = '/home/noi/.mozilla/firefox/eb0nz6yr.Unnamed Profile 2/.parentlock'; //up2 | |
//var lockFilePath = '/home/noi/.mozilla/firefox/qydytdfk.default/.parentlock'; //main | |
//var lockFilePath = '/home/noi/.mozilla/firefox/q0rlb7ap.Unnamed Profile 1/.parentlock'; //dev | |
console.log(lockFilePath); | |
///////////////fcntl | |
if (OS.Constants.Sys.Name == 'Darwin') { | |
var F_GETLK = 7; | |
var F_RDLCK = 1; | |
var F_WRLCK = 3; | |
var F_UNLCK = 2; | |
/* https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man2/fcntl.2.html | |
* struct flock { | |
* off_t l_start; // starting offset | |
* off_t l_len; // len = 0 means until end of file | |
* pid_t l_pid; // lock owner | |
* short l_type; // lock type: read/write, etc. | |
* short l_whence; // type of l_start | |
* }; | |
*/ | |
//order matters: | |
// http://chat.stackexchange.com/transcript/message/17822233#17822233 | |
// https://ask.mozilla.org/question/1134/order-of-strcuture-matters-test-case-flock-for-use-by-fcntl/ | |
var flock = new ctypes.StructType('flock', [ | |
{'l_start': ctypes.unsigned_long}, | |
{'l_len': ctypes.unsigned_long}, | |
{'l_pid': ctypes.int}, | |
{'l_type': ctypes.unsigned_short}, | |
{'l_whence': ctypes.unsigned_short} | |
]); | |
} else if (OS.Constants.Sys.Name == 'Linux') { | |
var F_GETLK = 5; | |
var F_RDLCK = 0; | |
var F_WRLCK = 1; | |
var F_UNLCK = 2; | |
/* http://linux.die.net/man/2/fcntl | |
* typedef struct flock { | |
* ... | |
* short l_type; //Type of lock: F_RDLCK, F_WRLCK, F_UNLCK | |
* short l_whence; //How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END | |
* off_t l_start; //Starting offset for lock | |
* off_t l_len; //Number of bytes to lock | |
* pid_t l_pid; //PID of process blocking our lock (F_GETLK only) | |
* ... | |
* }; | |
*/ | |
//order matters: | |
// http://chat.stackexchange.com/transcript/message/17822233#17822233 | |
// https://ask.mozilla.org/question/1134/order-of-strcuture-matters-test-case-flock-for-use-by-fcntl/ | |
var flock = new ctypes.StructType('flock', [ | |
{'l_type': ctypes.unsigned_short}, | |
{'l_whence': ctypes.unsigned_short}, | |
{'l_start': ctypes.unsigned_long}, | |
{'l_len': ctypes.unsigned_long}, | |
{'l_pid': ctypes.int} | |
]); | |
} | |
//int fcntl(int fd, int cmd, ... /* arg */ ); | |
/* | |
* int fcntl(int fd, int cmd); | |
* int fcntl(int fd, int cmd, long arg); | |
* int fcntl(int fd, int cmd, struct flock *lock); | |
*/ | |
var fcntl = _libc.declare('fcntl', | |
ctypes.default_abi, | |
ctypes.int, | |
ctypes.int, | |
ctypes.int, | |
flock.ptr | |
); | |
//int open(const char *pathname, int flags, mode_t mode); | |
//https://github.com/downthemall/downthemall-mirror/blob/c8fd56c464b2af6b8dc7ddee1f9bbe6e9f6e8382/modules/manager/worker_posix.js#L35 | |
var openFd = _libc.declare( | |
"open", | |
ctypes.default_abi, | |
ctypes.int, // retval | |
ctypes.char.ptr, // path | |
ctypes.int // flags | |
); | |
var closeFd = _libc.declare( | |
"close", | |
ctypes.default_abi, | |
ctypes.int, // retval | |
ctypes.int // fd | |
); | |
var filepath = lockFilePath; | |
//filepath = OS.Path.join(OS.Constants.Path.desktopDir, 'new.txt'); | |
let fd = openFd(filepath, OS.Constants.libc.O_RDWR); //setting this to O_RDWR fixes errno of 9 on fcntl | |
if (fd == -1) { | |
//if file does not exist and O_CREAT was not set. errno is == 2 | |
//if file is a dangling symbolic link. errno is == 2 | |
console.error('failed to open file, fd:', fd, 'errno:', ctypes.errno); | |
return -1; | |
} else { | |
console.log('successfully opened, fd:', fd) | |
} | |
try { | |
var testlock = new flock(); | |
testlock.l_type = F_WRLCK; //can use F_RDLCK but keep openFd at O_RDWR, it just works | |
testlock.l_start = 0; | |
testlock.l_whence = OS.Constants.libc.SEEK_SET; | |
testlock.l_len = 0; | |
var rez = fcntl(fd, F_GETLK, testlock.address()); | |
console.log('rez:', rez); | |
if (rez != -1) { | |
//check testlock.l_type | |
console.log('testlock:', uneval(testlock)); | |
if (testlock.l_type == F_UNLCK) { | |
//can also test if testlock.l_pid is not 0 | |
console.info('file is NOT locked'); | |
} else if (testlock.l_type == F_WRLCK) { | |
console.info('file is WRITE LOCKED, it may be read locked too'); | |
} else if (testlock.l_type == F_RDLCK) { | |
console.info('file is NOT write locked but just READ LOCKED'); //we know this because testlock tested for write lock first | |
} else { | |
console.error('testlock.l_type is unknown, l_type:', testlock.l_type); | |
} | |
} else { | |
console.log('rez was -1, errno', ctypes.errno); | |
} | |
} finally { | |
var rez = closeFd(fd); | |
if (rez == 0) { | |
//console.log('succesfully closed, rez:', rez); | |
} else { | |
console.error('FAILED to close, rez:', rez, 'errno', ctypes.errno); | |
} | |
} | |
} | |
console.time('flock'); | |
doit(); | |
console.timeEnd('flock'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When using the libc constants follow this commentary to figure out field order: