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'); |
When using the libc constants follow this commentary to figure out field order:
noida btw guys if short is 2 what is off_t and pid_t?
11:27 noida 8?
11:27 *** avikpal quit (Ping timeout: 121 seconds)
11:27 jdm noida: http://stackoverflow.com/questions/9073667/where-to-find-the-complete-definition-of-off-t-type
11:29 noida so they say blkcnt_t and off_t shall be signed integer types.
11:35 noida jdm in ctypes to get size of platform dependent signed integer do you go ctypes.size_t.size?
11:37 noida ah so maybe harshil__ is on 64bit system thats why he's getting these numbers:
11:37 noida FLOCK_L_LEN:16 L_TYPE:0 L_PID:24 L_WHENCE:2 L_START: 8
11:37 jdm noida: yep, makes sense
11:37 harshil__ yes my os is 64bit
11:37 noida super this is awesome!
11:38 noida so to find offset of field in structure i take that number and divide by size of the type?
11:39 jdm noida: no, you multiply the offset in bytes by *
11:39 jdm er, by 8
11:39 jdm actually I'm not sure what you
11:39 jdm you're asking
11:39 *** Fallen|away is now known as Fallen
11:39 noida these offsets are supposed to help me figure out how to create teh structure
11:40 noida for example in mac flock structure is this:https://gist.github.com/Noitidart/f05ffde7dcaffe792a4d#file-_ff-addon-snippet-fcntl-js-L40
11:40 jdm ah
11:40 noida and in ubuntu the flock structure has the same fields but in different order: see line 67 of that
11:41 jdm so the offset of a field will show how many bytes should have preceded it
11:41 noida oh!!
11:42 jdm if you sort them in ascending order, that's the field order
11:42 jdm and then you sort out the types that will take up that many bytes
11:42 noida ohhh!!!!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
for mac, i had to set
l_pid
toctpyes.int
otherwies it would throwctypes.errno == 22
which isEINVAL
weidr.