OLD | NEW |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build linux | 5 // +build linux |
6 | 6 |
7 package syscall | 7 package syscall |
8 | 8 |
9 import ( | 9 import ( |
10 "unsafe" | 10 "unsafe" |
(...skipping 23 matching lines...) Expand all Loading... |
34 // Declare all variables at top in case any | 34 // Declare all variables at top in case any |
35 // declarations require heap allocation (e.g., err1). | 35 // declarations require heap allocation (e.g., err1). |
36 var ( | 36 var ( |
37 r1 uintptr | 37 r1 uintptr |
38 err1 Errno | 38 err1 Errno |
39 nextfd int | 39 nextfd int |
40 i int | 40 i int |
41 ) | 41 ) |
42 | 42 |
43 // guard against side effects of shuffling fds below. | 43 // guard against side effects of shuffling fds below. |
| 44 // Make sure that nextfd is beyond any currently open files so |
| 45 // that we can't run the risk of overwriting any of them. |
44 fd := make([]int, len(attr.Files)) | 46 fd := make([]int, len(attr.Files)) |
| 47 nextfd = len(attr.Files) |
45 for i, ufd := range attr.Files { | 48 for i, ufd := range attr.Files { |
| 49 if nextfd < int(ufd) { |
| 50 nextfd = int(ufd) |
| 51 } |
46 fd[i] = int(ufd) | 52 fd[i] = int(ufd) |
47 } | 53 } |
| 54 nextfd++ |
48 | 55 |
49 // About to call fork. | 56 // About to call fork. |
50 // No more allocation or calls of non-assembly functions. | 57 // No more allocation or calls of non-assembly functions. |
51 r1, _, err1 = RawSyscall(SYS_FORK, 0, 0, 0) | 58 r1, _, err1 = RawSyscall(SYS_FORK, 0, 0, 0) |
52 if err1 != 0 { | 59 if err1 != 0 { |
53 return 0, err1 | 60 return 0, err1 |
54 } | 61 } |
55 | 62 |
56 if r1 != 0 { | 63 if r1 != 0 { |
57 // parent; return PID | 64 // parent; return PID |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 // Chdir | 143 // Chdir |
137 if dir != nil { | 144 if dir != nil { |
138 _, _, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)),
0, 0) | 145 _, _, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)),
0, 0) |
139 if err1 != 0 { | 146 if err1 != 0 { |
140 goto childerror | 147 goto childerror |
141 } | 148 } |
142 } | 149 } |
143 | 150 |
144 // Pass 1: look for fd[i] < i and move those up above len(fd) | 151 // Pass 1: look for fd[i] < i and move those up above len(fd) |
145 // so that pass 2 won't stomp on an fd it needs later. | 152 // so that pass 2 won't stomp on an fd it needs later. |
146 nextfd = int(len(fd)) | |
147 if pipe < nextfd { | 153 if pipe < nextfd { |
148 _, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd)
, 0) | 154 _, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd)
, 0) |
149 if err1 != 0 { | 155 if err1 != 0 { |
150 goto childerror | 156 goto childerror |
151 } | 157 } |
152 RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC) | 158 RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC) |
153 pipe = nextfd | 159 pipe = nextfd |
154 nextfd++ | 160 nextfd++ |
155 } | 161 } |
156 for i = 0; i < len(fd); i++ { | 162 for i = 0; i < len(fd); i++ { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 if err = Pipe(p); err != nil { | 249 if err = Pipe(p); err != nil { |
244 return | 250 return |
245 } | 251 } |
246 if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil { | 252 if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil { |
247 return | 253 return |
248 } | 254 } |
249 _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC) | 255 _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC) |
250 } | 256 } |
251 return | 257 return |
252 } | 258 } |
OLD | NEW |