From mboxrd@z Thu Jan 1 00:00:00 1970 MIME-Version: 1.0 In-Reply-To: References: Date: Tue, 28 Dec 2010 23:06:03 +0200 Message-ID: From: Pavel Zholkover To: Fans of the OS Plan 9 from Bell Labs <9fans@9fans.net> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [9fans] Golang support for Plan 9 Topicbox-Message-UUID: 8ea40d2c-ead6-11e9-9d60-3106f5b1d025 On Tue, Dec 28, 2010 at 9:24 AM, Skip Tavakkolian wrote: > sorry for the noise; the -s was mentioned in your original post and i > missed it. =A0now hell-o example works. i'll try out a few more things. > > i checked out a complete release (fresh copy) earlier today before > applying the patch; it had the same results (one patch failed to > apply). > $ hg identify > 51c777dbccb9+ tip > You were right, I did a clean pull and then tried applying to patch - it fails on exec.go (not sure what is the cause though). I'm attaching a diff for the missing file exec_unix.go (it is not needed for plan9 but all the other os's break without it). Also if you are brave enough to run "cd src/pkg; make clean; GOOS=3Dplan9 make -k install" after building the 8g toolchain you could import "fmt" and friends... fmt.Println should even wor= k :) diff -r 51c777dbccb9 src/pkg/os/exec_unix.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pkg/os/exec_unix.go Tue Dec 28 22:53:30 2010 +0200 @@ -0,0 +1,148 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package os + +import ( + "syscall" +) + +// ForkExec forks the current process and invokes Exec with the program, arguments, +// and environment specified by name, argv, and envv. It returns the proc= ess +// id of the forked process and an Error, if any. The fd array specifies = the +// file descriptors to be set up in the new process: fd[0] will be Unix fi= le +// descriptor 0 (standard input), fd[1] descriptor 1, and so on. A nil en= try +// will cause the child to have no open file descriptor with that index. +// If dir is not empty, the child chdirs into the directory before execing the program. +func ForkExec(name string, argv []string, envv []string, dir string, fd []*File) (pid int, err Error) { + if envv =3D=3D nil { + envv =3D Environ() + } + // Create array of integer (system) fds. + intfd :=3D make([]int, len(fd)) + for i, f :=3D range fd { + if f =3D=3D nil { + intfd[i] =3D -1 + } else { + intfd[i] =3D f.Fd() + } + } + + p, e :=3D syscall.ForkExec(name, argv, envv, dir, intfd) + if e !=3D 0 { + return 0, &PathError{"fork/exec", name, Errno(e)} + } + return p, nil +} + +// Exec replaces the current process with an execution of the +// named binary, with arguments argv and environment envv. +// If successful, Exec never returns. If it fails, it returns an Error. +// ForkExec is almost always a better way to execute a program. +func Exec(name string, argv []string, envv []string) Error { + if envv =3D=3D nil { + envv =3D Environ() + } + e :=3D syscall.Exec(name, argv, envv) + if e !=3D 0 { + return &PathError{"exec", name, Errno(e)} + } + return nil +} + +// TODO(rsc): Should os implement its own syscall.WaitStatus +// wrapper with the methods, or is exposing the underlying one enough? +// +// TODO(rsc): Certainly need to have Rusage struct, +// since syscall one might have different field types across +// different OS. + +// Waitmsg stores the information about an exited process as reported by W= ait. +type Waitmsg struct { + Pid int // The process's id. + syscall.WaitStatus // System-dependent status info. + Rusage *syscall.Rusage // System-dependent resource usage inf= o. +} + +// Options for Wait. +const ( + WNOHANG =3D syscall.WNOHANG // Don't wait if no process has exited. + WSTOPPED =3D syscall.WSTOPPED // If set, status of stopped subprocesses is also reported. + WUNTRACED =3D WSTOPPED + WRUSAGE =3D 1 << 20 // Record resource usage. +) + +// WRUSAGE must not be too high a bit, to avoid clashing with Linux's +// WCLONE, WALL, and WNOTHREAD flags, which sit in the top few bits of +// the options + +// Wait waits for process pid to exit or stop, and then returns a +// Waitmsg describing its status and an Error, if any. The options +// (WNOHANG etc.) affect the behavior of the Wait call. +func Wait(pid int, options int) (w *Waitmsg, err Error) { + var status syscall.WaitStatus + var rusage *syscall.Rusage + if options&WRUSAGE !=3D 0 { + rusage =3D new(syscall.Rusage) + options ^=3D WRUSAGE + } + pid1, e :=3D syscall.Wait4(pid, &status, options, rusage) + if e !=3D 0 { + return nil, NewSyscallError("wait", e) + } + w =3D new(Waitmsg) + w.Pid =3D pid1 + w.WaitStatus =3D status + w.Rusage =3D rusage + return w, nil +} + +// Convert i to decimal string. +func itod(i int) string { + if i =3D=3D 0 { + return "0" + } + + u :=3D uint64(i) + if i < 0 { + u =3D -u + } + + // Assemble decimal in reverse order. + var b [32]byte + bp :=3D len(b) + for ; u > 0; u /=3D 10 { + bp-- + b[bp] =3D byte(u%10) + '0' + } + + if i < 0 { + bp-- + b[bp] =3D '-' + } + + return string(b[bp:]) +} + +func (w Waitmsg) String() string { + // TODO(austin) Use signal names when possible? + res :=3D "" + switch { + case w.Exited(): + res =3D "exit status " + itod(w.ExitStatus()) + case w.Signaled(): + res =3D "signal " + itod(w.Signal()) + case w.Stopped(): + res =3D "stop signal " + itod(w.StopSignal()) + if w.StopSignal() =3D=3D syscall.SIGTRAP && w.TrapCause() !=3D 0 { + res +=3D " (trap " + itod(w.TrapCause()) + ")" + } + case w.Continued(): + res =3D "continued" + } + if w.CoreDump() { + res +=3D " (core dumped)" + } + return res +}