141
|
1 import os |
|
2 import sys |
|
3 #import ctypes |
|
4 import time |
|
5 import select |
|
6 import logging |
|
7 |
|
8 L = logging.info |
|
9 W = logging.warning |
|
10 E = logging.error |
|
11 |
|
12 DEFAULT_TRIES = 3 |
|
13 READLINE_SELECT_TIMEOUT = 1 |
|
14 |
144
|
15 def EX(msg, *args, **kwargs): |
|
16 kwargs['exc_info'] = True |
|
17 logging.error(msg, *args, **kwargs) |
|
18 |
141
|
19 clock_gettime = None |
|
20 no_clock_gettime = True |
|
21 def monotonic_time(): |
|
22 global clock_gettime |
|
23 global no_clock_gettime |
|
24 if no_clock_gettime: |
|
25 return time.time() |
|
26 |
|
27 class timespec(ctypes.Structure): |
|
28 _fields_ = [ |
|
29 ('tv_sec', ctypes.c_long), |
|
30 ('tv_nsec', ctypes.c_long) |
|
31 ] |
|
32 if not clock_gettime: |
|
33 try: |
|
34 librt = ctypes.CDLL('librt.so.0', use_errno=True) |
|
35 clock_gettime = librt.clock_gettime |
|
36 clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)] |
|
37 except: |
|
38 W("No clock_gettime(), using fake fallback.") |
|
39 no_clock_gettime = True |
|
40 return time.time() |
|
41 |
|
42 t = timespec() |
|
43 CLOCK_MONOTONIC = 1 # see <linux/time.h> |
|
44 |
|
45 if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) != 0: |
|
46 errno_ = ctypes.get_errno() |
|
47 raise OSError(errno_, os.strerror(errno_)) |
|
48 return t.tv_sec + t.tv_nsec * 1e-9 |
|
49 |
|
50 # decorator, tries a number of times, returns None on failure, sleeps between |
|
51 # Must be used as "@retry()" if arguments are defaulted |
|
52 def retry(retries=DEFAULT_TRIES, try_time = 1): |
|
53 def inner(func): |
|
54 def new_f(*args, **kwargs): |
|
55 for i in range(retries): |
|
56 d = func(*args, **kwargs) |
|
57 if d is not None: |
|
58 return d |
|
59 time.sleep(try_time) |
|
60 return None |
|
61 |
|
62 new_f.func_name = func.func_name |
|
63 return new_f |
|
64 return inner |
|
65 |
|
66 def readline(sock): |
|
67 timeout = READLINE_SELECT_TIMEOUT |
|
68 buf = '' |
|
69 while True: |
|
70 (rlist, wlist, xlist) = select.select([sock], [], [], timeout) |
|
71 if sock not in rlist: |
|
72 # hit timeout |
|
73 return None |
|
74 |
|
75 c = sock.recv(1) |
|
76 if c == '': |
|
77 # lightblue timeout |
|
78 return None |
|
79 if c == '\r': |
|
80 continue |
|
81 |
|
82 buf += c |
|
83 if c == '\n': |
|
84 return buf |
|
85 |
|
86 # from http://blog.stalkr.net/2011/04/pctf-2011-32-thats-no-bluetooth.html |
|
87 def crc16(buff, crc = 0, poly = 0x8408): |
|
88 l = len(buff) |
|
89 i = 0 |
|
90 while i < l: |
|
91 ch = ord(buff[i]) |
|
92 uc = 0 |
|
93 while uc < 8: |
|
94 if (crc & 1) ^ (ch & 1): |
|
95 crc = (crc >> 1) ^ poly |
|
96 else: |
|
97 crc >>= 1 |
|
98 ch >>= 1 |
|
99 uc += 1 |
|
100 i += 1 |
|
101 return crc |
|
102 |
|
103 def cheap_daemon(): |
|
104 L("Daemonising.") |
|
105 sys.stdout.flush() |
|
106 sys.stderr.flush() |
|
107 out = file('/dev/null', 'a+') |
|
108 os.dup2(out.fileno(), sys.stdout.fileno()) |
|
109 os.dup2(out.fileno(), sys.stderr.fileno()) |
|
110 |
|
111 try: |
|
112 pid = os.fork() |
|
113 if pid > 0: |
|
114 sys.exit(0) |
|
115 except OSError, e: |
|
116 E("Bad fork()") |
|
117 sys.exit(1) |
|
118 |
|
119 os.setsid() |
|
120 |
|
121 try: |
|
122 pid = os.fork() |
|
123 if pid > 0: |
|
124 sys.exit(0) |
|
125 except OSError, e: |
|
126 E("Bad fork()") |
|
127 sys.exit(1) |
|
128 |
|
129 |