~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/syscall/exec_unix.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
 
64
64
var ForkLock sync.RWMutex
65
65
 
66
 
// Convert array of string to array
67
 
// of NUL-terminated byte pointer.
 
66
// StringSlicePtr is deprecated. Use SlicePtrFromStrings instead.
 
67
// If any string contains a NUL byte this function panics instead
 
68
// of returning an error.
68
69
func StringSlicePtr(ss []string) []*byte {
69
70
        bb := make([]*byte, len(ss)+1)
70
71
        for i := 0; i < len(ss); i++ {
74
75
        return bb
75
76
}
76
77
 
 
78
// SlicePtrFromStrings converts a slice of strings to a slice of
 
79
// pointers to NUL-terminated byte slices. If any string contains
 
80
// a NUL byte, it returns (nil, EINVAL).
 
81
func SlicePtrFromStrings(ss []string) ([]*byte, error) {
 
82
        var err error
 
83
        bb := make([]*byte, len(ss)+1)
 
84
        for i := 0; i < len(ss); i++ {
 
85
                bb[i], err = BytePtrFromString(ss[i])
 
86
                if err != nil {
 
87
                        return nil, err
 
88
                }
 
89
        }
 
90
        bb[len(ss)] = nil
 
91
        return bb, nil
 
92
}
 
93
 
77
94
func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
78
95
 
79
96
func SetNonblock(fd int, nonblocking bool) (err error) {
128
145
        p[1] = -1
129
146
 
130
147
        // Convert args to C form.
131
 
        argv0p := StringBytePtr(argv0)
132
 
        argvp := StringSlicePtr(argv)
133
 
        envvp := StringSlicePtr(attr.Env)
 
148
        argv0p, err := BytePtrFromString(argv0)
 
149
        if err != nil {
 
150
                return 0, err
 
151
        }
 
152
        argvp, err := SlicePtrFromStrings(argv)
 
153
        if err != nil {
 
154
                return 0, err
 
155
        }
 
156
        envvp, err := SlicePtrFromStrings(attr.Env)
 
157
        if err != nil {
 
158
                return 0, err
 
159
        }
134
160
 
135
161
        if runtime.GOOS == "freebsd" && len(argv[0]) > len(argv0) {
136
162
                argvp[0] = argv0p
138
164
 
139
165
        var chroot *byte
140
166
        if sys.Chroot != "" {
141
 
                chroot = StringBytePtr(sys.Chroot)
 
167
                chroot, err = BytePtrFromString(sys.Chroot)
 
168
                if err != nil {
 
169
                        return 0, err
 
170
                }
142
171
        }
143
172
        var dir *byte
144
173
        if attr.Dir != "" {
145
 
                dir = StringBytePtr(attr.Dir)
 
174
                dir, err = BytePtrFromString(attr.Dir)
 
175
                if err != nil {
 
176
                        return 0, err
 
177
                }
146
178
        }
147
179
 
148
180
        // Acquire the fork lock so that no other threads
151
183
        ForkLock.Lock()
152
184
 
153
185
        // Allocate child status pipe close on exec.
154
 
        if err = Pipe(p[0:]); err != nil {
155
 
                goto error
156
 
        }
157
 
        if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil {
158
 
                goto error
159
 
        }
160
 
        if _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC); err != nil {
 
186
        if err = forkExecPipe(p[:]); err != nil {
161
187
                goto error
162
188
        }
163
189
 
171
197
 
172
198
        // Read child error status from pipe.
173
199
        Close(p[1])
174
 
        n, err = read(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
 
200
        n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
175
201
        Close(p[0])
176
202
        if err != nil || n != 0 {
177
203
                if n == int(unsafe.Sizeof(err1)) {
215
241
 
216
242
// Ordinary exec.
217
243
func Exec(argv0 string, argv []string, envv []string) (err error) {
 
244
        argv0p, err := BytePtrFromString(argv0)
 
245
        if err != nil {
 
246
                return err
 
247
        }
 
248
        argvp, err := SlicePtrFromStrings(argv)
 
249
        if err != nil {
 
250
                return err
 
251
        }
 
252
        envvp, err := SlicePtrFromStrings(envv)
 
253
        if err != nil {
 
254
                return err
 
255
        }
218
256
        _, _, err1 := RawSyscall(SYS_EXECVE,
219
 
                uintptr(unsafe.Pointer(StringBytePtr(argv0))),
220
 
                uintptr(unsafe.Pointer(&StringSlicePtr(argv)[0])),
221
 
                uintptr(unsafe.Pointer(&StringSlicePtr(envv)[0])))
 
257
                uintptr(unsafe.Pointer(argv0p)),
 
258
                uintptr(unsafe.Pointer(&argvp[0])),
 
259
                uintptr(unsafe.Pointer(&envvp[0])))
222
260
        return Errno(err1)
223
261
}