Check-in [1e00cde4e2]
Overview
Comment: | new plugin: st2subprocess: Alternative process start (player/recording app) methods: subprocess.*, or exec/spawn, and win32 api methods. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
1e00cde4e2ab7f082a5eebb2e664199a |
User & Date: | mario on 2017-10-13 18:13:58 |
Other Links: | manifest | tags |
Context
2017-10-13
| ||
21:29 | Add a shell version, new flags; some more docs. check-in: 4061ff33a6 user: mario tags: trunk | |
18:13 | new plugin: st2subprocess: Alternative process start (player/recording app) methods: subprocess.*, or exec/spawn, and win32 api methods. check-in: 1e00cde4e2 user: mario tags: trunk | |
2017-10-09
| ||
16:40 | Fix undefined headers={} / miscombined .update() call check-in: 7607f02394 user: mario tags: trunk | |
Changes
Added contrib/st2subprocess.py version [3aa97fd8d5].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | # encoding: utf-8 # api: streamtuner2 # title: win32/subprocess # description: Utilizes subprocess spawning or win32 API instead of os.system # version: 0.2 # depends: streamtuner2 > 2.2.0, python >= 2.7 # priority: optional # config: # { name: cmd_spawn, type: select, select: "popen|call|execv|spawnv|pywin32|win32api|system", value: popen, description: Spawn method } # { name: cmd_flags, type: select, select: "none|nowait|detached|nowait0|all|sw_show", value: none, description: Process creation flags (win32) } # type: handler # category: io # # Overrides the action.run method with subprocess.Popen() and some # cmdline parsing. Which mostly makes sense on Windows to avoid some # `start` bugs, such as "http://.." arguments getting interpreted # independently. # # +------------------+-----+---------+-------+----------------------+ # | VARIANT | SYS | FLAGS | PATHS | NOTES | # +------------------+-----+---------+-------+----------------------+ # | subprocess.popen | * | all | base | Most versatile | # | subprocess.call | * | all | base& | May block Gtk thread | # | os.execv | w32 | none | full& | fork+exec | # | os.spawnv | lnx | nowait | full& | ? | # | w32proc.CreatePr | w32 | detachd | full | Few parameters used | # | win32api.WinExec | w32 | sw_show | base | Mostly like `start`? | # | system/default | * | none | base | normal action.run() | # +------------------+-----+---------+-------+----------------------+ # # Notes: # ยท Note that for Linux, you should decorate player commands with "&" and # use absolute paths for call/exec/spawn to work as expected. # ยท The flags are only supported on Windows, should be `none` for Linux. # ยท streamripper calls will always use the default action.run/os.system # ยท cmdline parsing may not reproduce the original arguments on Windows, # in particular if list2cmdline was used. # ยท Does not yet check for modules being load # ยท Testing mostly. Though might replace action.run someday. Command and # argument parsing is the holdup for not having this earlier. # import re import os import shlex from config import * from channels import FeaturePlugin import action try: import subprocess except: None try: import win32process except: None try: import win32api except: None # hook action.run class st2subprocess (FeaturePlugin): # alternative run methods flagmap = { "nowait": os.P_NOWAIT, "detached": 0x00000008, # https://stackoverflow.com/a/13593257/345031 "nowait0": os.P_NOWAITO, "all": 8 | os.P_NOWAIT | os.P_NOWAITO, "wait": os.P_WAIT, "none": 0, # https://docs.python.org/2.7/library/subprocess.html#subprocess.STARTUPINFO "sw_show": 5, # https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx } # swap out action.run() def init2(self, parent, *k, **kw): self.osrun = action.run action.run = self.action_run # override for exec method def action_run(self, cmd): # blacklist if re.search("streamripper|cmd\.exe", cmd): return self.osrun(cmd) # split args args = shlex.split(cmd) # undo win32 quoting damage if conf.windows and re.search('\^', cmd): args = [re.sub(r'\^(?=[()<>"&^])', '', s) for s in args] # flags flags = self.flagmap[conf.cmd_flags] if conf.windows and conf.cmd_flags in self.flagmap else 0 # debug log.EXEC("st2subprocess:", args, "creationflags=%s"%flags) #-- Popen โ https://docs.python.org/2/library/subprocess.html#popen-constructor if conf.cmd_spawn == "popen": log.POPEN( subprocess.Popen(args, creationflags=flags) ) #-- call โ https://docs.python.org/2/library/subprocess.html#replacing-os-system elif conf.cmd_spawn == "call": log.CALL( subprocess.call(args, creationflags=flags) ) #-- execv โ https://docs.python.org/2/library/os.html#os.execv elif conf.cmd_spawn == "execv": log.OS_EXECV( os.execv(args[0], args) if os.fork() == 0 else "..." ) #-- spawnv โ https://docs.python.org/2/library/os.html#os.spawnv elif conf.cmd_spawn == "spawnv": log.OS_SPAWNL( os.spawnv(flags, args[0], args) ) #-- pywin32 โ https://www.programcreek.com/python/example/8489/win32process.CreateProcess elif conf.cmd_spawn == "pywin32": log.WIN32PROCESS_CreateProcess( win32process.CreateProcess( None, cmd, None, None, 0, flags, None, None, win32process.STARTUPINFO() ) ) #-- win32api elif conf.cmd_spawn == "win32api": log.WIN32API_WinExec( win32api.WinExec(cmd, win32con.SW_SHOW) ) # fallback else: return self.osrun(cmd) |