mirror of https://github.com/cutefishos/appmotor
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
257 lines
6.4 KiB
Python
257 lines
6.4 KiB
Python
import os, os.path, glob
|
|
import subprocess
|
|
import commands
|
|
import time
|
|
import sys
|
|
import re
|
|
from subprocess import Popen
|
|
from os.path import basename
|
|
|
|
DEV_NULL = file("/dev/null","w")
|
|
|
|
def debug(*msg):
|
|
"""
|
|
Debug function
|
|
"""
|
|
sys.stderr.write('[DEBUG %s] %s\n' % (time.ctime(), \
|
|
' '.join([str(s) for s in msg]),))
|
|
|
|
def error(*msg):
|
|
"""
|
|
exit when error, give proper log
|
|
"""
|
|
sys.stderr.write('ERROR %s\n' % (' '.join([str(s) for s in msg]),))
|
|
sys.exit(1)
|
|
|
|
def remove_applauncherd_runtime_files():
|
|
"""
|
|
Removes files that applauncherd leaves behind after it has been stopped
|
|
"""
|
|
|
|
files = ["%s/applauncherd.lock" % (os.environ['HOME'])]
|
|
files += glob.glob('/tmp/boost*')
|
|
|
|
for f in files:
|
|
print "removing %s" % f
|
|
|
|
try:
|
|
os.remove(f)
|
|
except:
|
|
pass
|
|
|
|
def start_applauncherd():
|
|
handle = Popen(['initctl', 'start', 'xsession/applauncherd'],
|
|
stdout = DEV_NULL, stderr = DEV_NULL,
|
|
shell = False)
|
|
|
|
return handle.wait() == 0
|
|
|
|
def kill_applauncherd():
|
|
handle = Popen(['initctl', 'stop', 'xsession/applauncherd'],
|
|
stdout = DEV_NULL, stderr = DEV_NULL,
|
|
shell = False)
|
|
|
|
time.sleep(1)
|
|
|
|
remove_applauncherd_runtime_files()
|
|
|
|
return handle.wait()
|
|
|
|
def restart_applauncherd():
|
|
stop_applauncherd()
|
|
start_applauncherd()
|
|
|
|
def run_app_as_user(appname, out = DEV_NULL, err = DEV_NULL):
|
|
"""
|
|
Runs the specified command as a user.
|
|
"""
|
|
|
|
cmd = ['su', '-', 'meego', '-c']
|
|
|
|
if type(appname) == list:
|
|
cmd += appname
|
|
elif type(appname) == str:
|
|
cmd.append(appname)
|
|
else:
|
|
raise TypeError("List or string expected")
|
|
|
|
p = subprocess.Popen(cmd, shell = False,
|
|
stdout = out, stderr = err)
|
|
return p
|
|
|
|
def get_pid(appname):
|
|
temp = basename(appname)[:14]
|
|
st, op = commands.getstatusoutput("pgrep %s" % temp)
|
|
if st == 0:
|
|
return op
|
|
else:
|
|
return None
|
|
|
|
def get_newest_pid(appname):
|
|
temp = basename(appname)[:14]
|
|
st, op = commands.getstatusoutput("pgrep -n %s" % temp)
|
|
time.sleep(5)
|
|
if st == 0:
|
|
return op
|
|
else:
|
|
return None
|
|
|
|
def wait_for_app(app = None, timeout = 5, sleep = 0.5):
|
|
"""
|
|
Waits for an application to start. Checks periodically if
|
|
the app is running for a maximum wait set in timeout.
|
|
|
|
Returns the pid of the application if it was running before
|
|
the timeout finished, otherwise None is returned.
|
|
"""
|
|
|
|
pid = None
|
|
start = time.time()
|
|
|
|
while pid == None and time.time() < start + timeout:
|
|
pid = get_newest_pid(app)
|
|
|
|
if pid != None:
|
|
break
|
|
|
|
print "waiting %s secs for %s" % (sleep, app)
|
|
|
|
time.sleep(sleep)
|
|
|
|
return pid
|
|
|
|
|
|
def kill_process(appname=None, apppid=None, signum=9):
|
|
if apppid and appname:
|
|
return None
|
|
else:
|
|
if apppid:
|
|
st, op = commands.getstatusoutput("kill -%s %s" % (str(signum), str(apppid)))
|
|
if appname:
|
|
temp = basename(appname)[:14]
|
|
st, op = commands.getstatusoutput("pkill -%s %s" % (str(signum), temp))
|
|
|
|
try:
|
|
os.wait()
|
|
except Exception as e:
|
|
print e
|
|
|
|
def process_state(processid):
|
|
st, op = commands.getstatusoutput('cat /proc/%s/stat' %processid)
|
|
if st == 0:
|
|
return op
|
|
else:
|
|
debug(op)
|
|
return None
|
|
|
|
def get_creds(path = None, pid = None):
|
|
"""
|
|
Tries to retrieve credentials for a running application
|
|
using either the pid or path. Credentials are returned
|
|
as a string list.
|
|
"""
|
|
|
|
if path != None:
|
|
pid = get_pid(path)
|
|
|
|
if pid == None:
|
|
print 'invalid PID'
|
|
return None
|
|
|
|
handle = Popen(['/usr/bin/creds-get', '-p', str(pid)],
|
|
stdout = subprocess.PIPE)
|
|
|
|
op = handle.communicate()[0].strip()
|
|
handle.wait()
|
|
|
|
if handle.returncode != 0:
|
|
print 'error retrieving credentials'
|
|
return None
|
|
|
|
#self.assert_(handle.returncode == 0, "There was no such PID!")
|
|
debug("creds-get gave >>>>>\n%s\n<<<<<" % op)
|
|
|
|
creds = op.split("\n")[1:]
|
|
|
|
return creds
|
|
|
|
def launch_and_get_creds(path):
|
|
"""
|
|
Tries to launch an application and if successful, returns the
|
|
credentials the application has as a list.
|
|
"""
|
|
|
|
# try launch the specified application
|
|
handle = run_app_as_user(path)
|
|
|
|
# sleep for a moment to allow applauncherd to start the process
|
|
time.sleep(3)
|
|
|
|
# with luck, the process should have correct name by now
|
|
pid = get_pid(path)
|
|
|
|
debug("%s has PID %s" % (basename(path), pid,))
|
|
|
|
if pid == None:
|
|
print "couldn't launch %s" % basename(path)
|
|
return None
|
|
|
|
creds = get_creds(pid = pid)
|
|
|
|
kill_process(path)
|
|
|
|
return creds
|
|
|
|
def get_file_descriptor(booster, type):
|
|
"""
|
|
To test that file descriptors are closed before calling application main
|
|
"""
|
|
#get fd of booster before launching application
|
|
pid = commands.getoutput("pgrep '%s$'" %booster)
|
|
fd_info = commands.getoutput('ls -l /proc/%s/fd/' % str(pid))
|
|
fd_info = fd_info.split('\n')
|
|
init = {}
|
|
final = {}
|
|
|
|
for fd in fd_info:
|
|
if "->" in fd:
|
|
init[fd.split(" -> ")[0].split(' ')[-1]] = fd.split(" -> ")[-1]
|
|
print init
|
|
|
|
#launch application using booster
|
|
st = os.system('invoker --type=%s --no-wait /usr/bin/fala_ft_hello.launch' %type)
|
|
time.sleep(2)
|
|
|
|
#get fd of booster after launching the application
|
|
if st == 0:
|
|
fd_info = commands.getoutput('ls -l /proc/%s/fd/' % str(pid))
|
|
fd_info = fd_info.split('\n')
|
|
for fd in fd_info:
|
|
if "->" in fd:
|
|
final[fd.split(" -> ")[0].split(' ')[-1]] = fd.split(" -> ")[-1]
|
|
print final
|
|
pid = commands.getoutput('pgrep fala_ft_hello')
|
|
|
|
mykeys = init.keys()
|
|
count = 0
|
|
|
|
for key in mykeys:
|
|
try:
|
|
if init[key] != final[key]:
|
|
count = count + 1
|
|
except KeyError:
|
|
print "some key in init is not in final"
|
|
time.sleep(2)
|
|
print "The number of changed file descriptors %d" %count
|
|
kill_process(apppid=pid)
|
|
return count
|
|
|
|
def get_groups_for_user():
|
|
# get supplementary groups user belongs to (doesn't return
|
|
# the gid group)
|
|
p = run_app_as_user('id -Gn', out = subprocess.PIPE)
|
|
groups = p.communicate()[0].split()
|
|
p.wait()
|
|
|
|
return groups
|