View Javadoc
1   /*
2    * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.util;
12  
13  import static java.nio.charset.StandardCharsets.UTF_8;
14  
15  import java.io.File;
16  import java.io.PrintStream;
17  import java.security.AccessController;
18  import java.security.PrivilegedAction;
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.List;
22  
23  import org.eclipse.jgit.api.errors.JGitInternalException;
24  import org.eclipse.jgit.errors.CommandFailedException;
25  import org.eclipse.jgit.lib.Repository;
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  
29  /**
30   * FS implementation for Cygwin on Windows
31   *
32   * @since 3.0
33   */
34  public class FS_Win32_Cygwin extends FS_Win32 {
35  	private static final Logger LOG = LoggerFactory
36  			.getLogger(FS_Win32_Cygwin.class);
37  
38  	private static String cygpath;
39  
40  	/**
41  	 * Whether cygwin is found
42  	 *
43  	 * @return true if cygwin is found
44  	 */
45  	public static boolean isCygwin() {
46  		final String path = AccessController
47  				.doPrivileged((PrivilegedAction<String>) () -> System
48  						.getProperty("java.library.path") //$NON-NLS-1$
49  				);
50  		if (path == null)
51  			return false;
52  		File found = FS.searchPath(path, "cygpath.exe"); //$NON-NLS-1$
53  		if (found != null)
54  			cygpath = found.getPath();
55  		return cygpath != null;
56  	}
57  
58  	/**
59  	 * Constructor
60  	 */
61  	public FS_Win32_Cygwin() {
62  		super();
63  	}
64  
65  	/**
66  	 * Constructor
67  	 *
68  	 * @param src
69  	 *            instance whose attributes to copy
70  	 */
71  	protected FS_Win32_Cygwin(FS src) {
72  		super(src);
73  	}
74  
75  	/** {@inheritDoc} */
76  	@Override
77  	public FS newInstance() {
78  		return new FS_Win32_Cygwin(this);
79  	}
80  
81  	/** {@inheritDoc} */
82  	@Override
83  	public File resolve(File dir, String pn) {
84  		String useCygPath = System.getProperty("jgit.usecygpath"); //$NON-NLS-1$
85  		if (useCygPath != null && useCygPath.equals("true")) { //$NON-NLS-1$
86  			String w;
87  			try {
88  				w = readPipe(dir, //
89  					new String[] { cygpath, "--windows", "--absolute", pn }, // //$NON-NLS-1$ //$NON-NLS-2$
90  					UTF_8.name());
91  			} catch (CommandFailedException e) {
92  				LOG.warn(e.getMessage());
93  				return null;
94  			}
95  			if (!StringUtils.isEmptyOrNull(w)) {
96  				return new File(w);
97  			}
98  		}
99  		return super.resolve(dir, pn);
100 	}
101 
102 	/** {@inheritDoc} */
103 	@Override
104 	protected File userHomeImpl() {
105 		final String home = AccessController.doPrivileged(
106 				(PrivilegedAction<String>) () -> System.getenv("HOME") //$NON-NLS-1$
107 		);
108 		if (home == null || home.length() == 0)
109 			return super.userHomeImpl();
110 		return resolve(new File("."), home); //$NON-NLS-1$
111 	}
112 
113 	/** {@inheritDoc} */
114 	@Override
115 	public ProcessBuilder runInShell(String cmd, String[] args) {
116 		List<String> argv = new ArrayList<>(4 + args.length);
117 		argv.add("sh.exe"); //$NON-NLS-1$
118 		argv.add("-c"); //$NON-NLS-1$
119 		argv.add(cmd + " \"$@\""); //$NON-NLS-1$
120 		argv.add(cmd);
121 		argv.addAll(Arrays.asList(args));
122 		ProcessBuilder proc = new ProcessBuilder();
123 		proc.command(argv);
124 		return proc;
125 	}
126 
127 	@Override
128 	String shellQuote(String cmd) {
129 		return QuotedString.BOURNE.quote(cmd.replace(File.separatorChar, '/'));
130 	}
131 
132 	/** {@inheritDoc} */
133 	@Override
134 	public String relativize(String base, String other) {
135 		final String relativized = super.relativize(base, other);
136 		return relativized.replace(File.separatorChar, '/');
137 	}
138 
139 	/** {@inheritDoc} */
140 	@Override
141 	public ProcessResult runHookIfPresent(Repository repository, String hookName,
142 			String[] args, PrintStream outRedirect, PrintStream errRedirect,
143 			String stdinArgs) throws JGitInternalException {
144 		return internalRunHookIfPresent(repository, hookName, args, outRedirect,
145 				errRedirect, stdinArgs);
146 	}
147 }