|
@@ -1139,6 +1139,41 @@ func (e *StatusError) Error() string {
|
|
|
return fmt.Sprintf("Status: %d", e.Status)
|
|
|
}
|
|
|
|
|
|
+func quote(word string, buf *bytes.Buffer) {
|
|
|
+ // Bail out early for "simple" strings
|
|
|
+ if word != "" && !strings.ContainsAny(word, "\\'\"`${[|&;<>()~*?! \t\n") {
|
|
|
+ buf.WriteString(word)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ buf.WriteString("'")
|
|
|
+
|
|
|
+ for i := 0; i < len(word); i++ {
|
|
|
+ b := word[i]
|
|
|
+ if b == '\'' {
|
|
|
+ // Replace literal ' with a close ', a \', and a open '
|
|
|
+ buf.WriteString("'\\''")
|
|
|
+ } else {
|
|
|
+ buf.WriteByte(b)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ buf.WriteString("'")
|
|
|
+}
|
|
|
+
|
|
|
+// Take a list of strings and escape them so they will be handled right
|
|
|
+// when passed as arguments to an program via a shell
|
|
|
+func ShellQuoteArguments(args []string) string {
|
|
|
+ var buf bytes.Buffer
|
|
|
+ for i, arg := range args {
|
|
|
+ if i != 0 {
|
|
|
+ buf.WriteByte(' ')
|
|
|
+ }
|
|
|
+ quote(arg, &buf)
|
|
|
+ }
|
|
|
+ return buf.String()
|
|
|
+}
|
|
|
+
|
|
|
func IsClosedError(err error) bool {
|
|
|
/* This comparison is ugly, but unfortunately, net.go doesn't export errClosing.
|
|
|
* See:
|