def test_get_process_info(self): # Ensure that get_process_info() called for oud pid returns information # about ourselves. pinfo = platform.get_process_info(os.getpid()) self.assertIsInstance(pinfo, tuple) self.assertEqual(pinfo.exe, os.path.realpath(sys.executable)) self.assertEqual(pinfo.cmdline[1:], sys.argv) if hasattr(os, 'getuid'): self.assertEqual(pinfo.uid, os.getuid()) if hasattr(os, 'getgid'): self.assertEqual(pinfo.gid, os.getgid())
def lock_file(filename): """Lock the file *filename*. On success, an opaque object that can be passed to :meth:`unlock_file` is returned. On failure, an :class:`OSError` exception is raised. """ # This uses the lockf() primitive. It has two major drawbacks which is that # it is per process (making it harder to test) and that it releases the # lock as soon as *any* fd referring to the file is closed (making it # more fragile). However it works on NFS so on balance I think I can live # with the drawbacks. # See also: http://0pointer.de/blog/projects/locking.html lockname = '{0}-lock'.format(filename) flock = open(lockname, 'a+') try: fcntl.lockf(flock.fileno(), fcntl.LOCK_EX|fcntl.LOCK_NB) except IOError as e: if e.errno not in (errno.EACCES, errno.EAGAIN): flock.close() raise lockinfo = {} flock.seek(0) for line in flock: key, value = line.split(':') lockinfo[key.lower()] = value.strip() flock.close() pid = int(lockinfo['pid']) from bluepass import platform pinfo = platform.get_process_info(pid) pinfo = 'alive; cmdline={0!r}'.format(' '.join(pinfo.cmdline)) if pinfo else 'remote?' msg = '{0}: locked by process {1} ({2})'.format(filename, pid, pinfo) raise OSError(e.errno, msg) flock.truncate() flock.write('PID: {0}\n'.format(os.getpid())) flock.write('Command: {0}\n'.format(' '.join(sys.argv))) flock.write('Hostname: {0}\n'.format(socket.gethostname())) flock.flush() return flock