Reject to fork when stdin is a TTY
This commit is contained in:
parent
310dd05c5c
commit
3a50998567
1 changed files with 38 additions and 36 deletions
|
@ -1,38 +1,32 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# kitchentext: Read text from stdin and put it on the Kitchenlight.
|
# kitchentext: Read text from stdin and put it on the Kitchenlight.
|
||||||
|
#
|
||||||
|
# Author: Shy
|
||||||
|
|
||||||
def kitchentext(delay=200, single=False, wait=False, restore=False, poweron=False,
|
def kitchentext(delay=200, single=False, wait=False, restore=False,
|
||||||
verbose=False, debug=False):
|
poweron=False, verbose=False, debug=False):
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from c4ctrl import C4Interface, Kitchenlight
|
from c4ctrl import C4Interface, Kitchenlight
|
||||||
|
|
||||||
charwidth = { # Width of characters.
|
charwidth = { # Width of characters.
|
||||||
'a' : 5, 'A' : 5, 'b' : 4, 'B' : 5,
|
'a' : 5, 'A' : 5, 'b' : 4, 'B' : 5, 'c' : 3, 'C' : 5,
|
||||||
'c' : 3, 'C' : 5, 'd' : 4, 'D' : 5,
|
'd' : 4, 'D' : 5, 'e' : 4, 'E' : 5, 'f' : 3, 'F' : 5,
|
||||||
'e' : 4, 'E' : 5, 'f' : 3, 'F' : 5,
|
'g' : 3, 'G' : 5, 'h' : 3, 'H' : 5, 'i' : 1, 'I' : 5,
|
||||||
'g' : 3, 'G' : 5, 'h' : 3, 'H' : 5,
|
'j' : 2, 'J' : 5, 'k' : 3, 'K' : 5, 'l' : 3, 'L' : 5,
|
||||||
'i' : 1, 'I' : 5, 'j' : 2, 'J' : 5,
|
'm' : 5, 'M' : 5, 'n' : 4, 'N' : 5, 'o' : 3, 'O' : 5,
|
||||||
'k' : 3, 'K' : 5, 'l' : 3, 'L' : 5,
|
'p' : 3, 'P' : 5, 'q' : 3, 'Q' : 5, 'r' : 3, 'R' : 5,
|
||||||
'm' : 5, 'M' : 5, 'n' : 4, 'N' : 5,
|
's' : 4, 'S' : 5, 't' : 3, 'T' : 5, 'u' : 3, 'U' : 5,
|
||||||
'o' : 3, 'O' : 5, 'p' : 3, 'P' : 5,
|
'v' : 3, 'V' : 5, 'w' : 5, 'W' : 5, 'x' : 3, 'X' : 5,
|
||||||
'q' : 3, 'Q' : 5, 'r' : 3, 'R' : 5,
|
'y' : 3, 'Y' : 5, 'z' : 3, 'Z' : 5, '0' : 5, '1' : 4,
|
||||||
's' : 4, 'S' : 5, 't' : 3, 'T' : 5,
|
'2' : 5, '3' : 5, '4' : 5, '5' : 5, '6' : 5, '7' : 5,
|
||||||
'u' : 3, 'U' : 5, 'v' : 3, 'V' : 5,
|
'8' : 5, '9' : 5, '@' : 5, '=' : 3, '!' : 1, '"' : 3,
|
||||||
'w' : 5, 'W' : 5, 'x' : 3, 'X' : 5,
|
'_' : 5, '-' : 3, '.' : 2, ',' : 2, '*' : 5, ':' : 2,
|
||||||
'y' : 3, 'Y' : 5, 'z' : 3, 'Z' : 5,
|
'\'' : 1, '/' : 5, '(' : 2, ')' : 2, '{' : 3, '}' : 3,
|
||||||
'0' : 5, '1' : 4, '2' : 5, '3' : 5,
|
'[' : 2, ']' : 2, '<' : 3, '>' : 4, '+' : 5, '#' : 5,
|
||||||
'4' : 5, '5' : 5, '6' : 5, '7' : 5,
|
'$' : 5, '%' : 5, '$' : 5, '~' : 5, '?' : 3, ';' : 2,
|
||||||
'8' : 5, '9' : 5, '@' : 5, '=' : 3,
|
'\\' : 5, '^' : 3, '|' : 1, '`' : 2, ' ' : 3, '\t' : 5
|
||||||
'!' : 1, '"' : 3, '_' : 5, '-' : 3,
|
|
||||||
'.' : 2, ',' : 2, '*' : 5, ':' : 2,
|
|
||||||
'\'' : 1, '/' : 5, '(' : 2, ')' : 2,
|
|
||||||
'{' : 3, '}' : 3, '[' : 2, ']' : 2,
|
|
||||||
'<' : 3, '>' : 4, '+' : 5, '#' : 5,
|
|
||||||
'$' : 5, '%' : 5, '$' : 5, '~' : 5,
|
|
||||||
'?' : 3, ';' : 2, '\\' : 5, '^' : 3,
|
|
||||||
'|' : 1, '`' : 2, ' ' : 3, '\t' : 5
|
|
||||||
}
|
}
|
||||||
|
|
||||||
C4Interface.debug = debug
|
C4Interface.debug = debug
|
||||||
|
@ -44,7 +38,7 @@ def kitchentext(delay=200, single=False, wait=False, restore=False, poweron=Fals
|
||||||
# Store previous state.
|
# Store previous state.
|
||||||
if restore:
|
if restore:
|
||||||
c4 = C4Interface()
|
c4 = C4Interface()
|
||||||
safe = c4.pull([kl.topic, kl.powertopic])
|
saved_state = c4.pull([kl.topic, kl.powertopic])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
|
@ -52,7 +46,7 @@ def kitchentext(delay=200, single=False, wait=False, restore=False, poweron=Fals
|
||||||
try:
|
try:
|
||||||
text = sys.stdin.readline()
|
text = sys.stdin.readline()
|
||||||
except KeyboardInterrupt: # Exit a bit more graceful on CTRL-C.
|
except KeyboardInterrupt: # Exit a bit more graceful on CTRL-C.
|
||||||
verbose and sys.stderr.write("\rInterrupted by user\n")
|
verbose and print("\nInterrupted by user.", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if single and text.rstrip('\n') == "":
|
if single and text.rstrip('\n') == "":
|
||||||
|
@ -73,8 +67,9 @@ def kitchentext(delay=200, single=False, wait=False, restore=False, poweron=Fals
|
||||||
if wait:
|
if wait:
|
||||||
from time import sleep
|
from time import sleep
|
||||||
# How long shall we wait?
|
# How long shall we wait?
|
||||||
# Kitchenlight has 30 columns, each char uses 2-5 columns followed by an empty
|
# Kitchenlight has 30 columns, each char uses 2-5 columns
|
||||||
# one. The traversal of one column takes 30 * <delay> ms.
|
# followed by an empty one. The traversal of one column
|
||||||
|
# takes 30 * <delay> ms.
|
||||||
twidth = 0
|
twidth = 0
|
||||||
for c in text:
|
for c in text:
|
||||||
try:
|
try:
|
||||||
|
@ -86,14 +81,14 @@ def kitchentext(delay=200, single=False, wait=False, restore=False, poweron=Fals
|
||||||
sleep(wait_for)
|
sleep(wait_for)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
verbose and sys.stderr.write("\rInterrupted by user\n")
|
verbose and print("\nInterrupted by user.", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
# Always restore privious state if "restore" is set.
|
# Always restore privious state if "restore" is set.
|
||||||
if restore:
|
if restore:
|
||||||
re = []
|
re = []
|
||||||
for top in safe: re.append((top.topic, top.payload))
|
for top in saved_state: re.append((top.topic, top.payload))
|
||||||
c4.push(re)
|
c4.push(re)
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,7 +108,8 @@ if __name__ == "__main__":
|
||||||
help="wait until the text has been displayed")
|
help="wait until the text has been displayed")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-r", "--restore", action="store_true", default=False,
|
"-r", "--restore", action="store_true", default=False,
|
||||||
help="restore the Kitchenlight to its prior state after the text has been displayed (implies --wait)")
|
help="restore the Kitchenlight to its prior state after the text has \
|
||||||
|
been displayed (implies --wait)")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-p", "--power-on", action="store_true", default=False,
|
"-p", "--power-on", action="store_true", default=False,
|
||||||
help="turn on Kitchenlight if it is powered off")
|
help="turn on Kitchenlight if it is powered off")
|
||||||
|
@ -125,13 +121,19 @@ if __name__ == "__main__":
|
||||||
help="be (not much) more verbose")
|
help="be (not much) more verbose")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--debug", action="store_true",
|
"--debug", action="store_true",
|
||||||
help="display what would be send to the MQTT broker, but do not actually connect")
|
help="display what would be send to the MQTT broker, but do not \
|
||||||
|
actually connect")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.fork:
|
if args.fork:
|
||||||
import sys
|
import sys
|
||||||
from posix import fork
|
from posix import fork
|
||||||
|
|
||||||
|
if sys.stdin.isatty():
|
||||||
|
print("Error: cannot fork when stdin is connected to a terminal!",
|
||||||
|
file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
child_pid = fork()
|
child_pid = fork()
|
||||||
if child_pid != 0:
|
if child_pid != 0:
|
||||||
args.verbose and print("Forked to PID", child_pid)
|
args.verbose and print("Forked to PID", child_pid)
|
||||||
|
|
Loading…
Reference in a new issue