Upgrade libuv to c35548a
authorRyan Dahl <ry@tinyclouds.org>
Tue, 2 Aug 2011 00:06:03 +0000 (17:06 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Tue, 2 Aug 2011 00:06:03 +0000 (17:06 -0700)
deps/uv/src/win/process.c
deps/uv/test/test-spawn.c

index e259677..6ad221f 100644 (file)
@@ -76,6 +76,48 @@ static void uv_process_init(uv_process_t* handle) {
 
 
 /*
+ * Quotes command line arguments
+ * Returns a pointer to the end (next char to be written) of the buffer
+ */
+static wchar_t* quote_cmd_arg(wchar_t *source, wchar_t *target,
+    wchar_t terminator) {
+  int len = wcslen(source),
+      i;
+
+  // Check if the string must be quoted;
+  // if unnecessary, don't do it, it may only confuse older programs.
+  if (len == 0) {
+    goto quote;
+  }
+  for (i = 0; i < len; i++) {
+    if (source[i] == L' ' || source[i] == L'"') {
+      goto quote;
+    }
+  }
+
+  // No quotation needed
+  wcsncpy(target, source, len);
+  target += len;
+  *(target++) = terminator;
+  return target;
+
+quote:
+  // Quote
+  *(target++) = L'"';
+  for (i = 0; i < len; i++) {
+    if (source[i] == L'"' || source[i] == L'\\') {
+      *(target++) = '\\';
+    }
+    *(target++) = source[i];
+  }
+  *(target++) = L'"';
+  *(target++) = terminator;
+
+  return target;
+}
+
+
+/*
  * Path search functions
  */
 
@@ -369,13 +411,21 @@ static wchar_t* make_program_args(char** args) {
   size_t size = 0;
   size_t len;
   int arg_count = 0;
+  wchar_t* buffer;
+  int arg_size;
+  int buffer_size = 0;
 
   /* Count the required size. */
   for (arg = args; *arg; arg++) {
-    size += (uv_utf8_to_utf16(*arg, NULL, 0) * sizeof(wchar_t));
+    arg_size = uv_utf8_to_utf16(*arg, NULL, 0) * sizeof(wchar_t);
+    size += arg_size;
+    buffer_size = arg_size > buffer_size ? arg_size : buffer_size;
     arg_count++;
   }
 
+  /* Adjust for potential quotes. */
+  size += arg_count * 2;
+
   /* Arguments are separated with a space. */
   if (arg_count > 0) {
     size += arg_count - 1;
@@ -386,21 +436,28 @@ static wchar_t* make_program_args(char** args) {
     uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
   }
 
+  buffer = (wchar_t*)malloc(buffer_size);
+  if (!buffer) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+  }
+
   ptr = dst;
-  for (arg = args; *arg; arg++, ptr += len) {
-    len = uv_utf8_to_utf16(*arg, ptr, (size_t)(size - (ptr - dst)));
+  for (arg = args; *arg; arg++) {
+    len = uv_utf8_to_utf16(*arg, buffer, (size_t)(size - (ptr - dst)));
     if (!len) {
-      free(dst);
-      return NULL;
+      goto error;
     }
 
-    if (*(arg + 1)) {
-      /* Replace with a space if there are more args. */
-      *((ptr + len) - 1) = L' ';
-    }
+    ptr = quote_cmd_arg(buffer, ptr, *(arg + 1) ? L' ' : L'\0');
   }
 
+  free(buffer);
   return dst;
+
+error:
+  free(dst);
+  free(buffer);
+  return NULL;
 }
 
 /*
index fc1c1ae..2ab6e6c 100644 (file)
@@ -58,11 +58,10 @@ static void kill_cb(uv_process_t* process, int exit_status, int term_signal) {
   exit_cb_called++;
 #ifdef _WIN32
   ASSERT(exit_status == 1);
-  ASSERT(term_signal == 0);
 #else
   ASSERT(exit_status == 0);
-  ASSERT(term_signal == 15);
 #endif
+  ASSERT(term_signal == 15);
   uv_close((uv_handle_t*)process, close_cb);
 }