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