summaryrefslogtreecommitdiffstats
path: root/tools/python/google/platform_utils_win.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/python/google/platform_utils_win.py')
-rw-r--r--tools/python/google/platform_utils_win.py219
1 files changed, 219 insertions, 0 deletions
diff --git a/tools/python/google/platform_utils_win.py b/tools/python/google/platform_utils_win.py
new file mode 100644
index 0000000..df72e3d
--- /dev/null
+++ b/tools/python/google/platform_utils_win.py
@@ -0,0 +1,219 @@
+# Copyright 2008, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""Platform-specific utility methods shared by several scripts."""
+
+import os
+import re
+import subprocess
+import sys
+
+import google.path_utils
+
+# Cache a single cygpath process for use throughout, even across instances of
+# the PlatformUtility class.
+_cygpath_proc = None
+
+class PlatformUtility(object):
+ def __init__(self, base_dir):
+ """Args:
+ base_dir: a directory above which third_party/cygwin can be found,
+ used to locate the cygpath executable for path conversions.
+ """
+ self._cygwin_root = None
+ self._base_dir = base_dir
+
+ def _CygwinRoot(self):
+ """Returns the full path to third_party/cygwin/."""
+ if not self._cygwin_root:
+ self._cygwin_root = google.path_utils.FindUpward(self._base_dir,
+ 'third_party', 'cygwin')
+ return self._cygwin_root
+
+ def _PathToExecutable(self, executable):
+ """Returns the full path to an executable in Cygwin's bin dir."""
+ return os.path.join(self._CygwinRoot(), 'bin', executable)
+
+ def GetAbsolutePath(self, path, force=False):
+ """Returns an absolute windows path. If platform is cygwin, converts it to
+ windows style using cygpath.
+
+ For performance reasons, we use a single cygpath process, shared among all
+ instances of this class. Otherwise Python can run out of file handles.
+ """
+ if not force and sys.platform != "cygwin":
+ return os.path.abspath(path)
+ global _cygpath_proc
+ if not _cygpath_proc:
+ cygpath_command = [self._PathToExecutable("cygpath.exe"),
+ "-a", "-m", "-f", "-"]
+ _cygpath_proc = subprocess.Popen(cygpath_command,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
+ _cygpath_proc.stdin.write(path + "\n")
+ return _cygpath_proc.stdout.readline().rstrip()
+
+ def GetFilesystemRoot(self):
+ """Returns the root directory of the file system."""
+ return os.environ['SYSTEMDRIVE'] + '\\'
+
+ def GetTempDirectory(self):
+ """Returns the file system's base temp directory, or the filesystem root
+ if the standard temp directory can't be determined.
+
+ Note that this does not use a random subdirectory, so it's not
+ intrinsically secure. If you need a secure subdir, use the tempfile
+ package.
+ """
+ return os.environ.get('TEMP', self.GetFilesystemRoot())
+
+ def FilenameToUri(self, path, use_http=False, use_ssl=False, port=8000):
+ """Convert a Windows style path to a URI.
+
+ Args:
+ path: For an http URI, the path relative to the httpd server's
+ DocumentRoot; for a file URI, the full path to the file.
+ use_http: if True, returns a URI of the form http://127.0.0.1:8000/.
+ If False, returns a file:/// URI.
+ use_ssl: if True, returns HTTPS URL (https://127.0.0.1:8000/).
+ This parameter is ignored if use_http=False.
+ port: The port number to append when returning an HTTP URI
+ """
+ if use_http:
+ protocol = 'http'
+ if use_ssl:
+ protocol = 'https'
+ path = path.replace("\\", "/")
+ return "%s://127.0.0.1:%s/%s" % (protocol, str(port), path)
+ return "file:///" + self.GetAbsolutePath(path)
+
+ def GetStartHttpdCommand(self, output_dir,
+ httpd_conf_path, mime_types_path,
+ document_root=None, apache2=False):
+ """Prepares the config file and output directory to start an httpd server.
+ Returns a list of strings containing the server's command line+args.
+
+ Args:
+ output_dir: the path to the server's output directory, for log files.
+ It will be created if necessary.
+ httpd_conf_path: full path to the httpd.conf file to be used.
+ mime_types_path: full path to the mime.types file to be used.
+ document_root: full path to the DocumentRoot. If None, the DocumentRoot
+ from the httpd.conf file will be used. Note that the httpd.conf
+ file alongside this script does not specify any DocumentRoot, so if
+ you're using that one, be sure to specify a document_root here.
+ apache2: boolean if true will cause this function to return start
+ command for Apache 2.x as opposed to Apache 1.3.x
+ """
+
+ if document_root:
+ document_root = GetCygwinPath(document_root)
+ exe_name = "httpd"
+ cert_file = ""
+ if apache2:
+ exe_name = "httpd2"
+ cert_file = google.path_utils.FindUpward(self._base_dir, 'tools',
+ 'python', 'google',
+ 'httpd_config', 'httpd2.pem')
+ httpd_vars = {
+ "httpd_executable_path": GetCygwinPath(
+ os.path.join(self._CygwinRoot(), "usr", "sbin", exe_name)),
+ "httpd_conf_path": GetCygwinPath(httpd_conf_path),
+ "ssl_certificate_file": GetCygwinPath(cert_file),
+ "document_root" : document_root,
+ "server_root": GetCygwinPath(os.path.join(self._CygwinRoot(), "usr")),
+ "mime_types_path": GetCygwinPath(mime_types_path),
+ "output_dir": GetCygwinPath(output_dir),
+ "bindir": GetCygwinPath(os.path.join(self._CygwinRoot(), "bin")),
+ "user": os.environ.get("USERNAME", os.environ.get("USER", "")),
+ }
+ if not httpd_vars["user"]:
+ # Failed to get the username from the environment; use whoami.exe
+ # instead.
+ proc = subprocess.Popen(self._PathToExecutable("whoami.exe"),
+ stdout=subprocess.PIPE)
+ httpd_vars["user"] = proc.stdout.read().strip()
+
+ if not httpd_vars["user"]:
+ raise Exception("Failed to get username.")
+
+ google.path_utils.MaybeMakeDirectory(output_dir)
+
+ # We have to wrap the command in bash because the cygwin environment
+ # is required for httpd to run.
+ # -C: process directive before reading config files
+ # -c: process directive after reading config files
+ # Apache wouldn't run CGIs with permissions==700 unless we add
+ # -c User "<username>"
+ bash = self._PathToExecutable("bash.exe")
+ httpd_cmd_string = (
+ ' PATH=%(bindir)s %(httpd_executable_path)s'
+ ' -f %(httpd_conf_path)s'
+ ' -c \'TypesConfig "%(mime_types_path)s"\''
+ ' -c \'CustomLog "%(output_dir)s/access_log.txt" common\''
+ ' -c \'ErrorLog "%(output_dir)s/error_log.txt"\''
+ ' -c \'PidFile "%(output_dir)s/httpd.pid"\''
+ ' -C \'User "%(user)s"\''
+ ' -C \'ServerRoot "%(server_root)s"\''
+ )
+ if apache2:
+ httpd_cmd_string = ('export CYGWIN=server;' + httpd_cmd_string +
+ ' -c \'SSLCertificateFile "%(ssl_certificate_file)s"\'')
+ if document_root:
+ httpd_cmd_string += ' -C \'DocumentRoot "%(document_root)s"\''
+
+ httpd_cmd = [bash, "-c", httpd_cmd_string % httpd_vars]
+ return httpd_cmd
+
+ def GetStopHttpdCommand(self):
+ """Returns a list of strings that contains the command line+args needed to
+ stop the http server used in the http tests.
+ """
+ # Force kill (/f) *all* httpd processes. This has the side effect of
+ # killing httpd processes that we didn't start.
+ return ["taskkill.exe", "/f", "/im", "httpd*"]
+
+###########################################################################
+# This method is specific to windows, expected to be used only by *_win.py
+# files.
+
+def GetCygwinPath(path):
+ """Convert a Windows path to a cygwin path.
+
+ The cygpath utility insists on converting paths that it thinks are Cygwin
+ root paths to what it thinks the correct roots are. So paths such as
+ "C:\b\slave\webkit-release-kjs\build\third_party\cygwin\bin" are converted to
+ plain "/usr/bin". To avoid this, we do the conversion manually.
+
+ The path is expected to be an absolute path, on any drive.
+ """
+ drive_regexp = re.compile(r'([a-z]):[/\\]', re.IGNORECASE)
+ def LowerDrive(matchobj):
+ return '/cygdrive/%s/' % matchobj.group(1).lower()
+ path = drive_regexp.sub(LowerDrive, path)
+ return path.replace('\\', '/')