15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def Main(argv): 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """This is like 'env -i', but it uses a whitelist of env variables to allow 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) through to the command being run. It attempts to strip off Xcode-added 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) values from PATH. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Note: An attempt was made to do something like: env -i bash -lc '[command]' 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # but that fails to set the things set by login (USER, etc.), so instead 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # the only approach that seems to work is to have a whitelist. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) env_key_whitelist = ( 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'HOME', 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'LOGNAME', 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 'PATH' added below (but filtered). 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'PWD', 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'SHELL', 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'TEMP', 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'TMPDIR', 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'USER' 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Need something to run. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # TODO(lliabraa): Make this output a usage string and exit (here and below). 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(len(argv) > 0) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_to_path = []; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_entry = argv[0]; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if first_entry.startswith('ADD_TO_PATH='): 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) argv = argv[1:]; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_to_path = first_entry.replace('ADD_TO_PATH=', '', 1).split(':') 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Still need something to run. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(len(argv) > 0) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clean_env = {} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Pull over the whitelisted keys. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key in env_key_whitelist: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = os.environ.get(key, None) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not val is None: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clean_env[key] = val 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Collect the developer dir as set via Xcode, defaulting it. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dev_prefix = os.environ.get('DEVELOPER_DIR', '/Developer/') 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if dev_prefix[-1:] != '/': 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dev_prefix += '/' 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Now pull in PATH, but remove anything Xcode might have added. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_path = os.environ.get('PATH', '') 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filtered_chunks = \ 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [x for x in initial_path.split(':') if not x.startswith(dev_prefix)] 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if filtered_chunks: 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clean_env['PATH'] = ':'.join(add_to_path + filtered_chunks) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Add any KEY=VALUE args before the command to the cleaned environment. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args = argv[:] 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while '=' in args[0]: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (key, val) = args[0].split('=', 1) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clean_env[key] = val 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) args = args[1:] 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Still need something to run. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(len(args) > 0) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Off it goes... 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os.execvpe(args[0], args, clean_env) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Should never get here, so return a distinctive, non-zero status code. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 66 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.exit(Main(sys.argv[1:])) 78