utility.py 2.64 KB
Newer Older
1 2 3
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
4
# Copyright (C) 2016-2018, AquilaNipalensis
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. Please read the COPYING file.
#

import os
import fcntl
import time
import socket
import subprocess

class execReply(int):
    def __init__(self, value):
20
        super(execReply, self).__init__(value)
21 22 23 24 25 26 27 28 29 30 31
        self.stdout = None
        self.stderr = None

def synchronized(func):
    """Syncronize method call with a per method lock.
    
    This decorator makes sure that only one instance of the script's
    method run in any given time.
    """
    class Handler:
        def handler(self, *args, **kwargs):
32
            lock = FileLock("/var/lock/subsys/%s.scom" % script())
33 34 35 36 37 38 39 40 41 42 43
            lock.lock()
            self.myfunc(*args, **kwargs)
            lock.unlock()
    h = Handler()
    h.myfunc = func
    return h.handler

def run(*cmd):
    """Run a command without running a shell"""
    command = []
    if len(cmd) == 1:
44
        if isinstance(cmd[0], str):
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
            command = cmd[0].split()
        else:
            command = cmd[0]
    else:
        command = cmd
    proc = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    reply = execReply(proc.wait())
    reply.stdout, reply.stderr = proc.communicate()
    return reply

def waitBus(unix_name, timeout=5, wait=0.1, stream=True):
    if stream:
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    else:
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    while timeout > 0:
        try:
            sock.connect(unix_name)
            return True
        except:
            timeout -= wait
        time.sleep(wait)
    return False

class FileLock:
    def __init__(self, filename):
        self.filename = filename
        self.fd = None

    def lock(self, shared=False, timeout=-1):
        _type = fcntl.LOCK_EX
        if shared:
            _type = fcntl.LOCK_SH
        if timeout != -1:
            _type |= fcntl.LOCK_NB

81
        self.fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT, 0o600)
82
        if self.fd == -1:
83
            raise IOError("Cannot create lock file")
84 85 86 87 88 89 90 91 92 93 94 95 96 97

        while True:
            try:
                fcntl.flock(self.fd, _type)
                return
            except IOError:
                if timeout > 0:
                    time.sleep(0.2)
                    timeout -= 0.2
                else:
                    raise

    def unlock(self):
        fcntl.flock(self.fd, fcntl.LOCK_UN)