A lightweight mechanism to provide an *instant kickstart* to a Go web server instance upon changing any Go source files under the project directory (and its subdirectories).

exec_windows.go 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Fork, exec, wait, etc.
  5. package windows
  6. // EscapeArg rewrites command line argument s as prescribed
  7. // in http://msdn.microsoft.com/en-us/library/ms880421.
  8. // This function returns "" (2 double quotes) if s is empty.
  9. // Alternatively, these transformations are done:
  10. // - every back slash (\) is doubled, but only if immediately
  11. // followed by double quote (");
  12. // - every double quote (") is escaped by back slash (\);
  13. // - finally, s is wrapped with double quotes (arg -> "arg"),
  14. // but only if there is space or tab inside s.
  15. func EscapeArg(s string) string {
  16. if len(s) == 0 {
  17. return "\"\""
  18. }
  19. n := len(s)
  20. hasSpace := false
  21. for i := 0; i < len(s); i++ {
  22. switch s[i] {
  23. case '"', '\\':
  24. n++
  25. case ' ', '\t':
  26. hasSpace = true
  27. }
  28. }
  29. if hasSpace {
  30. n += 2
  31. }
  32. if n == len(s) {
  33. return s
  34. }
  35. qs := make([]byte, n)
  36. j := 0
  37. if hasSpace {
  38. qs[j] = '"'
  39. j++
  40. }
  41. slashes := 0
  42. for i := 0; i < len(s); i++ {
  43. switch s[i] {
  44. default:
  45. slashes = 0
  46. qs[j] = s[i]
  47. case '\\':
  48. slashes++
  49. qs[j] = s[i]
  50. case '"':
  51. for ; slashes > 0; slashes-- {
  52. qs[j] = '\\'
  53. j++
  54. }
  55. qs[j] = '\\'
  56. j++
  57. qs[j] = s[i]
  58. }
  59. j++
  60. }
  61. if hasSpace {
  62. for ; slashes > 0; slashes-- {
  63. qs[j] = '\\'
  64. j++
  65. }
  66. qs[j] = '"'
  67. j++
  68. }
  69. return string(qs[:j])
  70. }
  71. func CloseOnExec(fd Handle) {
  72. SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
  73. }
  74. // FullPath retrieves the full path of the specified file.
  75. func FullPath(name string) (path string, err error) {
  76. p, err := UTF16PtrFromString(name)
  77. if err != nil {
  78. return "", err
  79. }
  80. n := uint32(100)
  81. for {
  82. buf := make([]uint16, n)
  83. n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
  84. if err != nil {
  85. return "", err
  86. }
  87. if n <= uint32(len(buf)) {
  88. return UTF16ToString(buf[:n]), nil
  89. }
  90. }
  91. }