1#!/usr/bin/python 2# Copyright (c) 2012 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import os 7import sys 8 9def Main(argv): 10 """This is like 'env -i', but it uses a whitelist of env variables to allow 11 through to the command being run. It attempts to strip off Xcode-added 12 values from PATH. 13 """ 14 # Note: An attempt was made to do something like: env -i bash -lc '[command]' 15 # but that fails to set the things set by login (USER, etc.), so instead 16 # the only approach that seems to work is to have a whitelist. 17 env_key_whitelist = ( 18 'HOME', 19 'LOGNAME', 20 # 'PATH' added below (but filtered). 21 'PWD', 22 'SHELL', 23 'TEMP', 24 'TMPDIR', 25 'USER' 26 ) 27 28 # Need something to run. 29 # TODO(lliabraa): Make this output a usage string and exit (here and below). 30 assert(len(argv) > 0) 31 32 add_to_path = []; 33 first_entry = argv[0]; 34 if first_entry.startswith('ADD_TO_PATH='): 35 argv = argv[1:]; 36 add_to_path = first_entry.replace('ADD_TO_PATH=', '', 1).split(':') 37 38 # Still need something to run. 39 assert(len(argv) > 0) 40 41 clean_env = {} 42 43 # Pull over the whitelisted keys. 44 for key in env_key_whitelist: 45 val = os.environ.get(key, None) 46 if not val is None: 47 clean_env[key] = val 48 49 # Collect the developer dir as set via Xcode, defaulting it. 50 dev_prefix = os.environ.get('DEVELOPER_DIR', '/Developer/') 51 if dev_prefix[-1:] != '/': 52 dev_prefix += '/' 53 54 # Now pull in PATH, but remove anything Xcode might have added. 55 initial_path = os.environ.get('PATH', '') 56 filtered_chunks = \ 57 [x for x in initial_path.split(':') if not x.startswith(dev_prefix)] 58 if filtered_chunks: 59 clean_env['PATH'] = ':'.join(add_to_path + filtered_chunks) 60 61 # Add any KEY=VALUE args before the command to the cleaned environment. 62 args = argv[:] 63 while '=' in args[0]: 64 (key, val) = args[0].split('=', 1) 65 clean_env[key] = val 66 args = args[1:] 67 68 # Still need something to run. 69 assert(len(args) > 0) 70 71 # Off it goes... 72 os.execvpe(args[0], args, clean_env) 73 # Should never get here, so return a distinctive, non-zero status code. 74 return 66 75 76if __name__ == '__main__': 77 sys.exit(Main(sys.argv[1:])) 78