Small style stuff
[zxing.git] / cpp / scons / scons-local-2.0.0.final.0 / SCons / Platform / posix.py
1 """SCons.Platform.posix
2
3 Platform-specific initialization for POSIX (Linux, UNIX, etc.) systems.
4
5 There normally shouldn't be any need to import this module directly.  It
6 will usually be imported through the generic SCons.Platform.Platform()
7 selection method.
8 """
9
10 #
11 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
12 #
13 # Permission is hereby granted, free of charge, to any person obtaining
14 # a copy of this software and associated documentation files (the
15 # "Software"), to deal in the Software without restriction, including
16 # without limitation the rights to use, copy, modify, merge, publish,
17 # distribute, sublicense, and/or sell copies of the Software, and to
18 # permit persons to whom the Software is furnished to do so, subject to
19 # the following conditions:
20 #
21 # The above copyright notice and this permission notice shall be included
22 # in all copies or substantial portions of the Software.
23 #
24 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
25 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
26 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #
32
33 __revision__ = "src/engine/SCons/Platform/posix.py 5023 2010/06/14 22:05:46 scons"
34
35 import errno
36 import os
37 import os.path
38 import subprocess
39 import sys
40 import select
41
42 import SCons.Util
43 from SCons.Platform import TempFileMunge
44
45 exitvalmap = {
46     2 : 127,
47     13 : 126,
48 }
49
50 def escape(arg):
51     "escape shell special characters"
52     slash = '\\'
53     special = '"$()'
54
55     arg = arg.replace(slash, slash+slash)
56     for c in special:
57         arg = arg.replace(c, slash+c)
58
59     return '"' + arg + '"'
60
61 def exec_system(l, env):
62     stat = os.system(' '.join(l))
63     if stat & 0xff:
64         return stat | 0x80
65     return stat >> 8
66
67 def exec_spawnvpe(l, env):
68     stat = os.spawnvpe(os.P_WAIT, l[0], l, env)
69     # os.spawnvpe() returns the actual exit code, not the encoding
70     # returned by os.waitpid() or os.system().
71     return stat
72
73 def exec_fork(l, env): 
74     pid = os.fork()
75     if not pid:
76         # Child process.
77         exitval = 127
78         try:
79             os.execvpe(l[0], l, env)
80         except OSError, e:
81             exitval = exitvalmap.get(e[0], e[0])
82             sys.stderr.write("scons: %s: %s\n" % (l[0], e[1]))
83         os._exit(exitval)
84     else:
85         # Parent process.
86         pid, stat = os.waitpid(pid, 0)
87         if stat & 0xff:
88             return stat | 0x80
89         return stat >> 8
90
91 def _get_env_command(sh, escape, cmd, args, env):
92     s = ' '.join(args)
93     if env:
94         l = ['env', '-'] + \
95             [escape(t[0])+'='+escape(t[1]) for t in env.items()] + \
96             [sh, '-c', escape(s)]
97         s = ' '.join(l)
98     return s
99
100 def env_spawn(sh, escape, cmd, args, env):
101     return exec_system([_get_env_command( sh, escape, cmd, args, env)], env)
102
103 def spawnvpe_spawn(sh, escape, cmd, args, env):
104     return exec_spawnvpe([sh, '-c', ' '.join(args)], env)
105
106 def fork_spawn(sh, escape, cmd, args, env):
107     return exec_fork([sh, '-c', ' '.join(args)], env)
108
109 def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
110     stdout_eof = stderr_eof = 0
111     while not (stdout_eof and stderr_eof):
112         try:
113             (i,o,e) = select.select([cmd_stdout, cmd_stderr], [], [])
114             if cmd_stdout in i:
115                 str = cmd_stdout.read()
116                 if len(str) == 0:
117                     stdout_eof = 1
118                 elif stdout is not None:
119                     stdout.write(str)
120             if cmd_stderr in i:
121                 str = cmd_stderr.read()
122                 if len(str) == 0:
123                     #sys.__stderr__.write( "stderr_eof=1\n" )
124                     stderr_eof = 1
125                 else:
126                     #sys.__stderr__.write( "str(stderr) = %s\n" % str )
127                     stderr.write(str)
128         except select.error, (_errno, _strerror):
129             if _errno != errno.EINTR:
130                 raise
131
132 def exec_popen3(l, env, stdout, stderr):
133     proc = subprocess.Popen(' '.join(l),
134                             stdout=stdout,
135                             stderr=stderr,
136                             shell=True)
137     stat = proc.wait()
138     if stat & 0xff:
139         return stat | 0x80
140     return stat >> 8
141
142 def exec_piped_fork(l, env, stdout, stderr):
143     # spawn using fork / exec and providing a pipe for the command's
144     # stdout / stderr stream
145     if stdout != stderr:
146         (rFdOut, wFdOut) = os.pipe()
147         (rFdErr, wFdErr) = os.pipe()
148     else:
149         (rFdOut, wFdOut) = os.pipe()
150         rFdErr = rFdOut
151         wFdErr = wFdOut
152     # do the fork
153     pid = os.fork()
154     if not pid:
155         # Child process
156         os.close( rFdOut )
157         if rFdOut != rFdErr:
158             os.close( rFdErr )
159         os.dup2( wFdOut, 1 ) # is there some symbolic way to do that ?
160         os.dup2( wFdErr, 2 )
161         os.close( wFdOut )
162         if stdout != stderr:
163             os.close( wFdErr )
164         exitval = 127
165         try:
166             os.execvpe(l[0], l, env)
167         except OSError, e:
168             exitval = exitvalmap.get(e[0], e[0])
169             stderr.write("scons: %s: %s\n" % (l[0], e[1]))
170         os._exit(exitval)
171     else:
172         # Parent process
173         pid, stat = os.waitpid(pid, 0)
174         os.close( wFdOut )
175         if stdout != stderr:
176             os.close( wFdErr )
177         childOut = os.fdopen( rFdOut )
178         if stdout != stderr:
179             childErr = os.fdopen( rFdErr )
180         else:
181             childErr = childOut
182         process_cmd_output(childOut, childErr, stdout, stderr)
183         os.close( rFdOut )
184         if stdout != stderr:
185             os.close( rFdErr )
186         if stat & 0xff:
187             return stat | 0x80
188         return stat >> 8
189
190 def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr):
191     # spawn using Popen3 combined with the env command
192     # the command name and the command's stdout is written to stdout
193     # the command's stderr is written to stderr
194     return exec_popen3([_get_env_command(sh, escape, cmd, args, env)],
195                        env, stdout, stderr)
196
197 def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
198     # spawn using fork / exec and providing a pipe for the command's
199     # stdout / stderr stream
200     return exec_piped_fork([sh, '-c', ' '.join(args)],
201                            env, stdout, stderr)
202
203
204
205 def generate(env):
206     # If os.spawnvpe() exists, we use it to spawn commands.  Otherwise
207     # if the env utility exists, we use os.system() to spawn commands,
208     # finally we fall back on os.fork()/os.exec().  
209     #
210     # os.spawnvpe() is prefered because it is the most efficient.  But
211     # for Python versions without it, os.system() is prefered because it
212     # is claimed that it works better with threads (i.e. -j) and is more
213     # efficient than forking Python.
214     #
215     # NB: Other people on the scons-users mailing list have claimed that
216     # os.fork()/os.exec() works better than os.system().  There may just
217     # not be a default that works best for all users.
218
219     if 'spawnvpe' in os.__dict__:
220         spawn = spawnvpe_spawn
221     elif env.Detect('env'):
222         spawn = env_spawn
223     else:
224         spawn = fork_spawn
225
226     if env.Detect('env'):
227         pspawn = piped_env_spawn
228     else:
229         pspawn = piped_fork_spawn
230
231     if 'ENV' not in env:
232         env['ENV']        = {}
233     env['ENV']['PATH']    = '/usr/local/bin:/opt/bin:/bin:/usr/bin'
234     env['OBJPREFIX']      = ''
235     env['OBJSUFFIX']      = '.o'
236     env['SHOBJPREFIX']    = '$OBJPREFIX'
237     env['SHOBJSUFFIX']    = '$OBJSUFFIX'
238     env['PROGPREFIX']     = ''
239     env['PROGSUFFIX']     = ''
240     env['LIBPREFIX']      = 'lib'
241     env['LIBSUFFIX']      = '.a'
242     env['SHLIBPREFIX']    = '$LIBPREFIX'
243     env['SHLIBSUFFIX']    = '.so'
244     env['LIBPREFIXES']    = [ '$LIBPREFIX' ]
245     env['LIBSUFFIXES']    = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ]
246     env['PSPAWN']         = pspawn
247     env['SPAWN']          = spawn
248     env['SHELL']          = 'sh'
249     env['ESCAPE']         = escape
250     env['TEMPFILE']       = TempFileMunge
251     env['TEMPFILEPREFIX'] = '@'
252     #Based on LINUX: ARG_MAX=ARG_MAX=131072 - 3000 for environment expansion
253     #Note: specific platforms might rise or lower this value
254     env['MAXLINELENGTH']  = 128072
255
256     # This platform supports RPATH specifications.
257     env['__RPATH'] = '$_RPATH'
258
259 # Local Variables:
260 # tab-width:4
261 # indent-tabs-mode:nil
262 # End:
263 # vim: set expandtab tabstop=4 shiftwidth=4: