blob: ed6fea53ff5824832aa15ec54385db017aa77163 [file] [log] [blame]
Tor Norbye3a2425a2013-11-04 10:16:08 -08001import os
2import shlex
3import sys
4import pydev_log
5import traceback
6
Tor Norbye0ecdb502014-02-19 09:43:01 -08007helpers = os.path.dirname(__file__).replace('\\', '/')
Tor Norbye3a2425a2013-11-04 10:16:08 -08008
9def is_python(path):
10 if path.endswith("'") or path.endswith('"'):
11 path = path[1:len(path)-1]
12 filename = os.path.basename(path).lower()
13 for name in ['python', 'jython', 'pypy']:
14 if filename.find(name) != -1:
15 return True
16
17 return False
18
19def patch_args(args):
20 try:
21 pydev_log.debug("Patching args: %s"% str(args))
22
23 import sys
24 new_args = []
25 i = 0
26 if len(args) == 0:
27 return args
28
29 if is_python(args[0]):
30 try:
31 indC = args.index('-c')
32 except ValueError:
33 indC = -1
34
35 if indC != -1:
36 import pydevd
37 host, port = pydevd.dispatch()
38
39 if port is not None:
Tor Norbye8668e1b2013-12-20 09:14:04 -080040 new_args.extend(args)
41 new_args[indC + 1] = "import sys; sys.path.append('%s'); import pydevd; pydevd.settrace(host='%s', port=%s, suspend=False); %s"%(helpers, host, port, args[indC + 1])
42 return new_args
Tor Norbye3a2425a2013-11-04 10:16:08 -080043 else:
44 new_args.append(args[0])
45 else:
46 pydev_log.debug("Process is not python, returning.")
47 return args
48
49 i = 1
50 while i < len(args):
51 if args[i].startswith('-'):
52 new_args.append(args[i])
53 else:
54 break
55 i+=1
56
57 if args[i].endswith('pydevd.py'): #no need to add pydevd twice
58 return args
59
60 for x in sys.original_argv:
61 if sys.platform == "win32" and not x.endswith('"'):
62 arg = '"%s"'%x
63 else:
64 arg = x
65 new_args.append(arg)
66 if x == '--file':
67 break
68
69 while i < len(args):
70 new_args.append(args[i])
71 i+=1
72
73 return new_args
74 except:
75 traceback.print_exc()
76 return args
77
78
79def args_to_str(args):
80 quoted_args = []
81 for x in args:
82 if x.startswith('"') and x.endswith('"'):
83 quoted_args.append(x)
84 else:
85 quoted_args.append('"%s"' % x)
86
87 return ' '.join(quoted_args)
88
89def remove_quotes(str):
90 if str.startswith('"') and str.endswith('"'):
91 return str[1:-1]
92 else:
93 return str
94
95def str_to_args(str):
96 return [remove_quotes(x) for x in shlex.split(str)]
97
98def patch_arg_str_win(arg_str):
99 new_arg_str = arg_str.replace('\\', '/')
100 args = str_to_args(new_arg_str)
101 if not is_python(args[0]):
102 return arg_str
Tor Norbye8668e1b2013-12-20 09:14:04 -0800103 arg_str = args_to_str(patch_args(args))
104 pydev_log.debug("New args: %s"% arg_str)
105 return arg_str
Tor Norbye3a2425a2013-11-04 10:16:08 -0800106
107def monkey_patch_module(module, funcname, create_func):
108 if hasattr(module, funcname):
109 original_name = 'original_' + funcname
110 if not hasattr(module, original_name):
111 setattr(module, original_name, getattr(module, funcname))
112 setattr(module, funcname, create_func(original_name))
113
114
115def monkey_patch_os(funcname, create_func):
116 monkey_patch_module(os, funcname, create_func)
117
118
119def warn_multiproc():
120 import pydev_log
121
122 pydev_log.error_once(
123 "New process is launching. Breakpoints won't work.\n To debug that process please enable 'Attach to subprocess automatically while debugging' option in the debugger settings.\n")
124
125
126def create_warn_multiproc(original_name):
127
128 def new_warn_multiproc(*args):
129 import os
130
131 warn_multiproc()
132
133 return getattr(os, original_name)(*args)
134 return new_warn_multiproc
135
136def create_execl(original_name):
137 def new_execl(path, *args):
138 '''
139os.execl(path, arg0, arg1, ...)
140os.execle(path, arg0, arg1, ..., env)
141os.execlp(file, arg0, arg1, ...)
142os.execlpe(file, arg0, arg1, ..., env)
143 '''
144 import os
145 args = patch_args(args)
146 return getattr(os, original_name)(path, *args)
147 return new_execl
148
149def create_execv(original_name):
150 def new_execv(path, args):
151 '''
152os.execv(path, args)
153os.execvp(file, args)
154 '''
155 import os
156 return getattr(os, original_name)(path, patch_args(args))
157 return new_execv
158
159def create_execve(original_name):
160 """
161os.execve(path, args, env)
162os.execvpe(file, args, env)
163 """
164 def new_execve(path, args, env):
165 import os
166 return getattr(os, original_name)(path, patch_args(args), env)
167 return new_execve
168
169
170def create_spawnl(original_name):
171 def new_spawnl(mode, path, *args):
172 '''
173os.spawnl(mode, path, arg0, arg1, ...)
174os.spawnlp(mode, file, arg0, arg1, ...)
175 '''
176 import os
177 args = patch_args(args)
178 return getattr(os, original_name)(mode, path, *args)
179 return new_spawnl
180
181def create_spawnv(original_name):
182 def new_spawnv(mode, path, args):
183 '''
184os.spawnv(mode, path, args)
185os.spawnvp(mode, file, args)
186 '''
187 import os
188 return getattr(os, original_name)(mode, path, patch_args(args))
189 return new_spawnv
190
191def create_spawnve(original_name):
192 """
193os.spawnve(mode, path, args, env)
194os.spawnvpe(mode, file, args, env)
195 """
196 def new_spawnve(mode, path, args, env):
197 import os
198 return getattr(os, original_name)(mode, path, patch_args(args), env)
199 return new_spawnve
200
201def create_CreateProcess(original_name):
202 """
203CreateProcess(*args, **kwargs)
204 """
205 def new_CreateProcess(appName, commandLine, *args):
206 try:
207 import _subprocess
208 except ImportError:
209 import _winapi as _subprocess
210 return getattr(_subprocess, original_name)(appName, patch_arg_str_win(commandLine), *args)
211 return new_CreateProcess
212
213def create_CreateProcessWarnMultiproc(original_name):
214 """
215CreateProcess(*args, **kwargs)
216 """
217 def new_CreateProcess(*args):
218 try:
219 import _subprocess
220 except ImportError:
221 import _winapi as _subprocess
222 warn_multiproc()
223 return getattr(_subprocess, original_name)(*args)
224 return new_CreateProcess
225
226def create_fork(original_name):
227 def new_fork():
228 import os
229 child_process = getattr(os, original_name)() # fork
230 if not child_process:
231 import pydevd
232
233 pydevd.settrace_forked()
234 return child_process
235 return new_fork
236
237def patch_new_process_functions():
238#os.execl(path, arg0, arg1, ...)
239#os.execle(path, arg0, arg1, ..., env)
240#os.execlp(file, arg0, arg1, ...)
241#os.execlpe(file, arg0, arg1, ..., env)
242#os.execv(path, args)
243#os.execve(path, args, env)
244#os.execvp(file, args)
245#os.execvpe(file, args, env)
246 monkey_patch_os('execl', create_execl)
247 monkey_patch_os('execle', create_execl)
248 monkey_patch_os('execlp', create_execl)
249 monkey_patch_os('execlpe', create_execl)
250 monkey_patch_os('execv', create_execv)
251 monkey_patch_os('execve', create_execve)
252 monkey_patch_os('execvp', create_execv)
253 monkey_patch_os('execvpe', create_execve)
254
255#os.spawnl(mode, path, ...)
256#os.spawnle(mode, path, ..., env)
257#os.spawnlp(mode, file, ...)
258#os.spawnlpe(mode, file, ..., env)
259#os.spawnv(mode, path, args)
260#os.spawnve(mode, path, args, env)
261#os.spawnvp(mode, file, args)
262#os.spawnvpe(mode, file, args, env)
263
264 monkey_patch_os('spawnl', create_spawnl)
265 monkey_patch_os('spawnle', create_spawnl)
266 monkey_patch_os('spawnlp', create_spawnl)
267 monkey_patch_os('spawnlpe', create_spawnl)
268 monkey_patch_os('spawnv', create_spawnv)
269 monkey_patch_os('spawnve', create_spawnve)
270 monkey_patch_os('spawnvp', create_spawnv)
271 monkey_patch_os('spawnvpe', create_spawnve)
272
273 if sys.platform != 'win32':
274 monkey_patch_os('fork', create_fork)
275 else:
276 #Windows
277 try:
278 import _subprocess
279 except ImportError:
280 import _winapi as _subprocess
281 monkey_patch_module(_subprocess, 'CreateProcess', create_CreateProcess)
282
283
284def patch_new_process_functions_with_warning():
285 monkey_patch_os('execl', create_warn_multiproc)
286 monkey_patch_os('execle', create_warn_multiproc)
287 monkey_patch_os('execlp', create_warn_multiproc)
288 monkey_patch_os('execlpe', create_warn_multiproc)
289 monkey_patch_os('execv', create_warn_multiproc)
290 monkey_patch_os('execve', create_warn_multiproc)
291 monkey_patch_os('execvp', create_warn_multiproc)
292 monkey_patch_os('execvpe', create_warn_multiproc)
293 monkey_patch_os('spawnl', create_warn_multiproc)
294 monkey_patch_os('spawnle', create_warn_multiproc)
295 monkey_patch_os('spawnlp', create_warn_multiproc)
296 monkey_patch_os('spawnlpe', create_warn_multiproc)
297 monkey_patch_os('spawnv', create_warn_multiproc)
298 monkey_patch_os('spawnve', create_warn_multiproc)
299 monkey_patch_os('spawnvp', create_warn_multiproc)
300 monkey_patch_os('spawnvpe', create_warn_multiproc)
301
302 if sys.platform != 'win32':
303 monkey_patch_os('fork', create_warn_multiproc)
304 else:
305 #Windows
306 try:
307 import _subprocess
308 except ImportError:
309 import _winapi as _subprocess
310 monkey_patch_module(_subprocess, 'CreateProcess', create_CreateProcessWarnMultiproc)