Skip to content

Commit 183fc4f

Browse files
ensonicddemidov
authored andcommitted
Make sound commands cancelable. (#317)
Don't use a subshell to tokenize the commands. Using the subshell breaks terminate() and kill() - they would only stop the subshell. Closes #316
1 parent 9b900bb commit 183fc4f

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

ev3dev/core.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@
4545
import mmap
4646
import ctypes
4747
import re
48-
import stat
4948
import select
49+
import shlex
50+
import stat
5051
import time
5152
from os.path import abspath
5253
from struct import pack, unpack
53-
from subprocess import Popen, check_output
54+
from subprocess import Popen, check_output, PIPE
5455

5556
try:
5657
# This is a linux-specific module.
@@ -1794,13 +1795,13 @@ def list_sensors(name_pattern=Sensor.SYSTEM_DEVICE_NAME_CONVENTION, **kwargs):
17941795
For example, 'sensor*'. Default value: '*'.
17951796
keyword arguments: used for matching the corresponding device
17961797
attributes. For example, driver_name='lego-ev3-touch', or
1797-
address=['in1', 'in3']. When argument value is a list,
1798+
address=['in1', 'in3']. When argument value is a list,
17981799
then a match against any entry of the list is enough.
17991800
"""
18001801
class_path = abspath(Device.DEVICE_ROOT_PATH + '/' + Sensor.SYSTEM_CLASS_NAME)
1801-
return (Sensor(name_pattern=name, name_exact=True)
1802+
return (Sensor(name_pattern=name, name_exact=True)
18021803
for name in list_device_names(class_path, name_pattern, **kwargs))
1803-
1804+
18041805

18051806
# ~autogen generic-class classes.i2cSensor>currentClass
18061807

@@ -3276,7 +3277,7 @@ def beep(args=''):
32763277
.. _`linux beep music`: https://www.google.com/search?q=linux+beep+music
32773278
"""
32783279
with open(os.devnull, 'w') as n:
3279-
return Popen('/usr/bin/beep %s' % args, stdout=n, shell=True)
3280+
return Popen(shlex.split('/usr/bin/beep %s' % args), stdout=n)
32803281

32813282
@staticmethod
32823283
def tone(*args):
@@ -3340,16 +3341,18 @@ def play(wav_file):
33403341
Play wav file.
33413342
"""
33423343
with open(os.devnull, 'w') as n:
3343-
return Popen('/usr/bin/aplay -q "%s"' % wav_file, stdout=n, shell=True)
3344+
return Popen(shlex.split('/usr/bin/aplay -q "%s"' % wav_file), stdout=n)
33443345

33453346
@staticmethod
33463347
def speak(text, espeak_opts='-a 200 -s 130'):
33473348
"""
33483349
Speak the given text aloud.
33493350
"""
33503351
with open(os.devnull, 'w') as n:
3351-
cmd_line = '/usr/bin/espeak --stdout {0} "{1}" | /usr/bin/aplay -q'.format(espeak_opts, text)
3352-
return Popen(cmd_line, stdout=n, shell=True)
3352+
cmd_line = '/usr/bin/espeak --stdout {0} "{1}"'.format(espeak_opts, text)
3353+
espeak = Popen(shlex.split(cmd_line), stdout=PIPE)
3354+
play = Popen(['/usr/bin/aplay', '-q'], stdin=espeak.stdout, stdout=n)
3355+
return espeak
33533356

33543357
@staticmethod
33553358
def _get_channel():
@@ -3387,7 +3390,7 @@ def set_volume(pct, channel=None):
33873390
channel = Sound._get_channel()
33883391

33893392
cmd_line = '/usr/bin/amixer -q set {0} {1:d}%'.format(channel, pct)
3390-
Popen(cmd_line, shell=True).wait()
3393+
Popen(shlex.split(cmd_line)).wait()
33913394

33923395
@staticmethod
33933396
def get_volume(channel=None):

0 commit comments

Comments
 (0)