Skip to content

Commit 256f12b

Browse files
committed
Implement a fallback for missing sh
Closes #274
1 parent 4ecfcdb commit 256f12b

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed

src/cred.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,44 @@ impl CredentialHelper {
296296
}
297297
) );
298298

299-
let mut p = my_try!(Command::new("sh").arg("-c")
300-
.arg(&format!("{} get", cmd))
301-
.stdin(Stdio::piped())
302-
.stdout(Stdio::piped())
303-
.stderr(Stdio::piped())
304-
.spawn());
299+
// It looks like the `cmd` specification is typically bourne-shell-like
300+
// syntax, so try that first. If that fails, though, we may be on a
301+
// Windows machine for example where `sh` isn't actually available by
302+
// default. Most credential helper configurations though are pretty
303+
// simple (aka one or two space-separated strings) so also try to invoke
304+
// the process directly.
305+
//
306+
// If that fails then it's up to the user to put `sh` in path and make
307+
// sure it works.
308+
let mut c = Command::new("sh");
309+
c.arg("-c")
310+
.arg(&format!("{} get", cmd))
311+
.stdin(Stdio::piped())
312+
.stdout(Stdio::piped())
313+
.stderr(Stdio::piped());
314+
let mut p = match c.spawn() {
315+
Ok(p) => p,
316+
Err(e) => {
317+
debug!("`sh` failed to spawn: {}", e);
318+
let mut parts = cmd.split_whitespace();
319+
let mut c = Command::new(parts.next().unwrap());
320+
for arg in parts {
321+
c.arg(arg);
322+
}
323+
c.arg("get")
324+
.stdin(Stdio::piped())
325+
.stdout(Stdio::piped())
326+
.stderr(Stdio::piped());
327+
match c.spawn() {
328+
Ok(p) => p,
329+
Err(e) => {
330+
debug!("fallback of {:?} failed with {}", cmd, e);
331+
return (None, None);
332+
}
333+
}
334+
}
335+
};
336+
305337
// Ignore write errors as the command may not actually be listening for
306338
// stdin
307339
{

0 commit comments

Comments
 (0)