Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
1cc4a5cd
Commit
1cc4a5cd
authored
Apr 02, 2011
by
Yuval Pavel Zholkover
Committed by
Rob Pike
Apr 02, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
R=rsc, brainman, ality, r2, r
CC=golang-dev
https://golang.org/cl/3816043
parent
c42b3e21
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
1604 additions
and
6 deletions
+1604
-6
src/pkg/syscall/Makefile
src/pkg/syscall/Makefile
+3
-0
src/pkg/syscall/asm_plan9_386.s
src/pkg/syscall/asm_plan9_386.s
+151
-0
src/pkg/syscall/exec_plan9.go
src/pkg/syscall/exec_plan9.go
+521
-0
src/pkg/syscall/mkall.sh
src/pkg/syscall/mkall.sh
+6
-0
src/pkg/syscall/mksyscall.pl
src/pkg/syscall/mksyscall.pl
+17
-1
src/pkg/syscall/mksysnum_plan9.sh
src/pkg/syscall/mksysnum_plan9.sh
+25
-0
src/pkg/syscall/str.go
src/pkg/syscall/str.go
+2
-2
src/pkg/syscall/syscall_linux.go
src/pkg/syscall/syscall_linux.go
+1
-1
src/pkg/syscall/syscall_plan9.go
src/pkg/syscall/syscall_plan9.go
+343
-0
src/pkg/syscall/syscall_plan9_386.go
src/pkg/syscall/syscall_plan9_386.go
+5
-0
src/pkg/syscall/syscall_unix.go
src/pkg/syscall/syscall_unix.go
+1
-1
src/pkg/syscall/syscall_windows.go
src/pkg/syscall/syscall_windows.go
+1
-1
src/pkg/syscall/types_plan9.c
src/pkg/syscall/types_plan9.c
+115
-0
src/pkg/syscall/zerrors_plan9_386.go
src/pkg/syscall/zerrors_plan9_386.go
+25
-0
src/pkg/syscall/zsyscall_plan9_386.go
src/pkg/syscall/zsyscall_plan9_386.go
+267
-0
src/pkg/syscall/zsysnum_plan9_386.go
src/pkg/syscall/zsysnum_plan9_386.go
+47
-0
src/pkg/syscall/ztypes_plan9_386.go
src/pkg/syscall/ztypes_plan9_386.go
+74
-0
No files found.
src/pkg/syscall/Makefile
View file @
1cc4a5cd
...
@@ -33,6 +33,9 @@ GOFILES_linux=\
...
@@ -33,6 +33,9 @@ GOFILES_linux=\
GOFILES_windows
=
\
GOFILES_windows
=
\
exec_windows.go
exec_windows.go
GOFILES_plan9
=
\
exec_plan9.go
OFILES
=
\
OFILES
=
\
asm_
$(GOOS)
_
$(GOARCH)
.
$O
\
asm_
$(GOOS)
_
$(GOARCH)
.
$O
\
...
...
src/pkg/syscall/asm_plan9_386.s
0 → 100644
View file @
1cc4a5cd
//
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
.
//
//
System
call
support
for
386
,
Plan
9
//
//
func
Syscall
(
trap
,
a1
,
a2
,
a3
uintptr
)
(
r1
,
r2
uintptr
,
err
string
)
//
func
Syscall6
(
trap
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
uintptr
)
(
r1
,
r2
uintptr
,
err
string
)
//
func
RawSyscall
(
trap
,
a1
,
a2
,
a3
uintptr
)
(
r1
,
r2
,
err
uintptr
)
//
func
RawSyscall6
(
trap
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
uintptr
)
(
r1
,
r2
,
err
uintptr
)
//
Trap
#
in
AX
,
args
on
stack
above
caller
pc
.
TEXT
·
Syscall
(
SB
),7,$0
CALL
runtime
·
entersyscall
(
SB
)
MOVL
4
(
SP
),
AX
//
syscall
entry
//
slide
args
down
on
top
of
system
call
number
LEAL
8
(
SP
),
SI
LEAL
4
(
SP
),
DI
CLD
MOVSL
MOVSL
MOVSL
INT
$
64
MOVL
AX
,
r1
+
20
(
SP
)
MOVL
$
0
,
r2
+
24
(
SP
)
CMPL
AX
,
$
-
1
JNE
ok3
SUBL
$
8
,
SP
CALL
syscall
·
errstr
(
SB
)
MOVL
SP
,
SI
ADDL
$
8
,
SP
JMP
copyresult3
ok3
:
LEAL
runtime
·
emptystring
(
SB
),
SI
copyresult3
:
LEAL
err
+
28
(
SP
),
DI
CLD
MOVSL
MOVSL
CALL
runtime
·
exitsyscall
(
SB
)
RET
TEXT
·
Syscall6
(
SB
),7,$0
CALL
runtime
·
entersyscall
(
SB
)
MOVL
4
(
SP
),
AX
//
syscall
entry
//
slide
args
down
on
top
of
system
call
number
LEAL
8
(
SP
),
SI
LEAL
4
(
SP
),
DI
CLD
MOVSL
MOVSL
MOVSL
MOVSL
MOVSL
MOVSL
INT
$
64
MOVL
AX
,
r1
+
32
(
SP
)
MOVL
$
0
,
r2
+
36
(
SP
)
CMPL
AX
,
$
-
1
JNE
ok4
SUBL
$
8
,
SP
CALL
syscall
·
errstr
(
SB
)
MOVL
SP
,
SI
ADDL
$
8
,
SP
JMP
copyresult4
ok4
:
LEAL
runtime
·
emptystring
(
SB
),
SI
copyresult4
:
LEAL
err
+
40
(
SP
),
DI
CLD
MOVSL
MOVSL
CALL
runtime
·
exitsyscall
(
SB
)
RET
TEXT
·
RawSyscall
(
SB
),7,$0
MOVL
4
(
SP
),
AX
//
syscall
entry
//
slide
args
down
on
top
of
system
call
number
LEAL
8
(
SP
),
SI
LEAL
4
(
SP
),
DI
CLD
MOVSL
MOVSL
MOVSL
INT
$
64
MOVL
AX
,
r1
+
20
(
SP
)
MOVL
AX
,
r2
+
24
(
SP
)
MOVL
AX
,
err
+
28
(
SP
)
RET
TEXT
·
RawSyscall6
(
SB
),7,$0
MOVL
4
(
SP
),
AX
//
syscall
entry
//
slide
args
down
on
top
of
system
call
number
LEAL
8
(
SP
),
SI
LEAL
4
(
SP
),
DI
CLD
MOVSL
MOVSL
MOVSL
MOVSL
MOVSL
MOVSL
INT
$
64
MOVL
AX
,
r1
+
32
(
SP
)
MOVL
AX
,
r2
+
36
(
SP
)
MOVL
AX
,
err
+
40
(
SP
)
RET
#define SYS_SEEK 39 /* from zsysnum_plan9_386.go */
//
func
seek
(
placeholder
uintptr
,
fd
int
,
offset
int64
,
whence
int
)
(
newoffset
int64
,
err
string
)
TEXT
·
seek
(
SB
),7,$0
LEAL
newoffset
+
24
(
SP
),
AX
MOVL
AX
,
placeholder
+
4
(
SP
)
MOVL
$SYS_SEEK
,
AX
//
syscall
entry
INT
$
64
CMPL
AX
,
$
-
1
JNE
ok6
MOVL
AX
,
24
(
SP
)
//
newoffset
low
MOVL
AX
,
28
(
SP
)
//
newoffset
high
SUBL
$
8
,
SP
CALL
syscall
·
errstr
(
SB
)
MOVL
SP
,
SI
ADDL
$
8
,
SP
JMP
copyresult6
ok6
:
LEAL
runtime
·
emptystring
(
SB
),
SI
copyresult6
:
LEAL
err
+
32
(
SP
),
DI
CLD
MOVSL
MOVSL
RET
src/pkg/syscall/exec_plan9.go
0 → 100644
View file @
1cc4a5cd
// 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.
// Fork, exec, wait, etc.
package
syscall
import
(
"sync"
"unsafe"
)
// Lock synchronizing creation of new file descriptors with fork.
//
// We want the child in a fork/exec sequence to inherit only the
// file descriptors we intend. To do that, we mark all file
// descriptors close-on-exec and then, in the child, explicitly
// unmark the ones we want the exec'ed program to keep.
// Unix doesn't make this easy: there is, in general, no way to
// allocate a new file descriptor close-on-exec. Instead you
// have to allocate the descriptor and then mark it close-on-exec.
// If a fork happens between those two events, the child's exec
// will inherit an unwanted file descriptor.
//
// This lock solves that race: the create new fd/mark close-on-exec
// operation is done holding ForkLock for reading, and the fork itself
// is done holding ForkLock for writing. At least, that's the idea.
// There are some complications.
//
// Some system calls that create new file descriptors can block
// for arbitrarily long times: open on a hung NFS server or named
// pipe, accept on a socket, and so on. We can't reasonably grab
// the lock across those operations.
//
// It is worse to inherit some file descriptors than others.
// If a non-malicious child accidentally inherits an open ordinary file,
// that's not a big deal. On the other hand, if a long-lived child
// accidentally inherits the write end of a pipe, then the reader
// of that pipe will not see EOF until that child exits, potentially
// causing the parent program to hang. This is a common problem
// in threaded C programs that use popen.
//
// Luckily, the file descriptors that are most important not to
// inherit are not the ones that can take an arbitrarily long time
// to create: pipe returns instantly, and the net package uses
// non-blocking I/O to accept on a listening socket.
// The rules for which file descriptor-creating operations use the
// ForkLock are as follows:
//
// 1) Pipe. Does not block. Use the ForkLock.
// 2) Socket. Does not block. Use the ForkLock.
// 3) Accept. If using non-blocking mode, use the ForkLock.
// Otherwise, live with the race.
// 4) Open. Can block. Use O_CLOEXEC if available (Linux).
// Otherwise, live with the race.
// 5) Dup. Does not block. Use the ForkLock.
// On Linux, could use fcntl F_DUPFD_CLOEXEC
// instead of the ForkLock, but only for dup(fd, -1).
var
ForkLock
sync
.
RWMutex
// Convert array of string to array
// of NUL-terminated byte pointer.
func
StringArrayPtr
(
ss
[]
string
)
[]
*
byte
{
bb
:=
make
([]
*
byte
,
len
(
ss
)
+
1
)
for
i
:=
0
;
i
<
len
(
ss
);
i
++
{
bb
[
i
]
=
StringBytePtr
(
ss
[
i
])
}
bb
[
len
(
ss
)]
=
nil
return
bb
}
// gbit16 reads a 16-bit numeric value from a 9P protocol message strored in b,
// returning the value and the remaining slice of b.
func
gbit16
(
b
[]
byte
)
(
uint16
,
[]
byte
)
{
return
uint16
(
b
[
0
])
|
uint16
(
b
[
1
])
<<
8
,
b
[
2
:
]
}
// gstring reads a string from a 9P protocol message strored in b,
// returning the value as a Go string and the remaining slice of b.
func
gstring
(
b
[]
byte
)
(
string
,
[]
byte
)
{
n
,
b
:=
gbit16
(
b
)
return
string
(
b
[
0
:
n
]),
b
[
n
:
]
}
// readdirnames returns the names of files inside the directory represented by dirfd.
func
readdirnames
(
dirfd
int
)
(
names
[]
string
,
err
Error
)
{
result
:=
make
([]
string
,
0
,
100
)
var
buf
[
STATMAX
]
byte
for
{
n
,
e
:=
Read
(
dirfd
,
buf
[
:
])
if
e
!=
nil
{
return
[]
string
{},
e
}
if
n
==
0
{
break
}
for
i
:=
0
;
i
<
n
;
{
m
,
_
:=
gbit16
(
buf
[
i
:
])
m
+=
2
if
m
<
STATFIXLEN
{
return
[]
string
{},
NewError
(
"malformed stat buffer"
)
}
name
,
_
:=
gstring
(
buf
[
i
+
41
:
])
result
=
append
(
result
,
name
)
i
+=
int
(
m
)
}
}
return
[]
string
{},
nil
}
// readdupdevice returns a list of currently opened fds (excluding stdin, stdout, stderr) from the dup device #d.
// ForkLock should be write locked before calling, so that no new fds would be created while the fd list is being read.
func
readdupdevice
()
(
fds
[]
int
,
err
Error
)
{
dupdevfd
,
err
:=
Open
(
"#d"
,
O_RDONLY
)
if
err
!=
nil
{
return
}
defer
Close
(
dupdevfd
)
fileNames
,
err
:=
readdirnames
(
dupdevfd
)
if
err
!=
nil
{
return
}
fds
=
make
([]
int
,
0
,
len
(
fileNames
)
>>
1
)
for
_
,
fdstr
:=
range
fileNames
{
if
l
:=
len
(
fdstr
);
l
>
2
&&
fdstr
[
l
-
3
]
==
'c'
&&
fdstr
[
l
-
2
]
==
't'
&&
fdstr
[
l
-
1
]
==
'l'
{
continue
}
fd
:=
int
(
atoi
([]
byte
(
fdstr
)))
if
fd
==
0
||
fd
==
1
||
fd
==
2
||
fd
==
dupdevfd
{
continue
}
fds
=
append
(
fds
,
fd
)
}
return
fds
[
0
:
len
(
fds
)],
nil
}
var
startupFds
[]
int
// Plan 9 does not allow clearing the OCEXEC flag
// from the underlying channel backing an open file descriptor,
// therefore we store a list of already opened file descriptors
// inside startupFds and skip them when manually closing descriptors
// not meant to be passed to a child exec.
func
init
()
{
startupFds
,
_
=
readdupdevice
()
}
// forkAndExecInChild forks the process, calling dup onto 0..len(fd)
// and finally invoking exec(argv0, argvv, envv) in the child.
// If a dup or exec fails, it writes the error string to pipe.
// (The pipe write end is close-on-exec so if exec succeeds, it will be closed.)
//
// In the child, this function must not acquire any locks, because
// they might have been locked at the time of the fork. This means
// no rescheduling, no malloc calls, and no new stack segments.
// The calls to RawSyscall are okay because they are assembly
// functions that do not grow the stack.
func
forkAndExecInChild
(
argv0
*
byte
,
argv
[]
*
byte
,
envv
[]
envItem
,
chroot
,
dir
*
byte
,
attr
*
ProcAttr
,
fdsToClose
[]
int
,
pipe
int
)
(
pid
int
,
err
Error
)
{
// Declare all variables at top in case any
// declarations require heap allocation (e.g., errbuf).
var
(
r1
uintptr
nextfd
int
i
int
clearenv
int
envfd
int
errbuf
[
ERRMAX
]
byte
)
// guard against side effects of shuffling fds below.
fd
:=
append
([]
int
(
nil
),
attr
.
Files
...
)
if
envv
!=
nil
{
clearenv
=
RFCENVG
}
// About to call fork.
// No more allocation or calls of non-assembly functions.
r1
,
_
,
_
=
RawSyscall
(
SYS_RFORK
,
uintptr
(
RFPROC
|
RFFDG
|
RFREND
|
clearenv
),
0
,
0
)
if
r1
!=
0
{
if
int
(
r1
)
==
-
1
{
return
0
,
NewError
(
errstr
())
}
// parent; return PID
return
int
(
r1
),
nil
}
// Fork succeeded, now in child.
// Close fds we don't need.
for
i
=
0
;
i
<
len
(
fdsToClose
);
i
++
{
r1
,
_
,
_
=
RawSyscall
(
SYS_CLOSE
,
uintptr
(
fdsToClose
[
i
]),
0
,
0
)
if
int
(
r1
)
==
-
1
{
goto
childerror
}
}
if
envv
!=
nil
{
// Write new environment variables.
for
i
=
0
;
i
<
len
(
envv
);
i
++
{
r1
,
_
,
_
=
RawSyscall
(
SYS_CREATE
,
uintptr
(
unsafe
.
Pointer
(
envv
[
i
]
.
name
)),
uintptr
(
O_WRONLY
),
uintptr
(
0666
))
if
int
(
r1
)
==
-
1
{
goto
childerror
}
envfd
=
int
(
r1
)
r1
,
_
,
_
=
RawSyscall6
(
SYS_PWRITE
,
uintptr
(
envfd
),
uintptr
(
unsafe
.
Pointer
(
envv
[
i
]
.
value
)),
uintptr
(
envv
[
i
]
.
nvalue
),
^
uintptr
(
0
),
^
uintptr
(
0
),
0
)
if
int
(
r1
)
==
-
1
||
int
(
r1
)
!=
envv
[
i
]
.
nvalue
{
goto
childerror
}
r1
,
_
,
_
=
RawSyscall
(
SYS_CLOSE
,
uintptr
(
envfd
),
0
,
0
)
if
int
(
r1
)
==
-
1
{
goto
childerror
}
}
}
// Chdir
if
dir
!=
nil
{
r1
,
_
,
_
=
RawSyscall
(
SYS_CHDIR
,
uintptr
(
unsafe
.
Pointer
(
dir
)),
0
,
0
)
if
int
(
r1
)
==
-
1
{
goto
childerror
}
}
// Pass 1: look for fd[i] < i and move those up above len(fd)
// so that pass 2 won't stomp on an fd it needs later.
nextfd
=
int
(
len
(
fd
))
if
pipe
<
nextfd
{
r1
,
_
,
_
=
RawSyscall
(
SYS_DUP
,
uintptr
(
pipe
),
uintptr
(
nextfd
),
0
)
if
int
(
r1
)
==
-
1
{
goto
childerror
}
pipe
=
nextfd
nextfd
++
}
for
i
=
0
;
i
<
len
(
fd
);
i
++
{
if
fd
[
i
]
>=
0
&&
fd
[
i
]
<
int
(
i
)
{
r1
,
_
,
_
=
RawSyscall
(
SYS_DUP
,
uintptr
(
fd
[
i
]),
uintptr
(
nextfd
),
0
)
if
int
(
r1
)
==
-
1
{
goto
childerror
}
fd
[
i
]
=
nextfd
nextfd
++
if
nextfd
==
pipe
{
// don't stomp on pipe
nextfd
++
}
}
}
// Pass 2: dup fd[i] down onto i.
for
i
=
0
;
i
<
len
(
fd
);
i
++
{
if
fd
[
i
]
==
-
1
{
RawSyscall
(
SYS_CLOSE
,
uintptr
(
i
),
0
,
0
)
continue
}
if
fd
[
i
]
==
int
(
i
)
{
continue
}
r1
,
_
,
_
=
RawSyscall
(
SYS_DUP
,
uintptr
(
fd
[
i
]),
uintptr
(
i
),
0
)
if
int
(
r1
)
==
-
1
{
goto
childerror
}
RawSyscall
(
SYS_CLOSE
,
uintptr
(
fd
[
i
]),
0
,
0
)
}
// Time to exec.
r1
,
_
,
_
=
RawSyscall
(
SYS_EXEC
,
uintptr
(
unsafe
.
Pointer
(
argv0
)),
uintptr
(
unsafe
.
Pointer
(
&
argv
[
0
])),
0
)
childerror
:
// send error string on pipe
RawSyscall
(
SYS_ERRSTR
,
uintptr
(
unsafe
.
Pointer
(
&
errbuf
[
0
])),
uintptr
(
len
(
errbuf
)),
0
)
errbuf
[
len
(
errbuf
)
-
1
]
=
0
i
=
0
for
i
<
len
(
errbuf
)
&&
errbuf
[
i
]
!=
0
{
i
++
}
RawSyscall6
(
SYS_PWRITE
,
uintptr
(
pipe
),
uintptr
(
unsafe
.
Pointer
(
&
errbuf
[
0
])),
uintptr
(
i
),
^
uintptr
(
0
),
^
uintptr
(
0
),
0
)
for
{
RawSyscall
(
SYS_EXITS
,
0
,
0
,
0
)
}
// Calling panic is not actually safe,
// but the for loop above won't break
// and this shuts up the compiler.
panic
(
"unreached"
)
}
func
cexecPipe
(
p
[]
int
)
Error
{
e
:=
Pipe
(
p
)
if
e
!=
nil
{
return
e
}
fd
,
e
:=
Open
(
"#d/"
+
itoa
(
p
[
1
]),
O_CLOEXEC
)
if
e
!=
nil
{
Close
(
p
[
0
])
Close
(
p
[
1
])
return
e
}
Close
(
fd
)
return
nil
}
type
envItem
struct
{
name
*
byte
value
*
byte
nvalue
int
}
type
ProcAttr
struct
{
Dir
string
// Current working directory.
Env
[]
string
// Environment.
Files
[]
int
// File descriptors.
Chroot
string
// Chroot.
}
var
zeroAttributes
ProcAttr
func
forkExec
(
argv0
string
,
argv
[]
string
,
attr
*
ProcAttr
)
(
pid
int
,
err
Error
)
{
var
(
p
[
2
]
int
n
int
errbuf
[
ERRMAX
]
byte
wmsg
Waitmsg
)
if
attr
==
nil
{
attr
=
&
zeroAttributes
}
p
[
0
]
=
-
1
p
[
1
]
=
-
1
// Convert args to C form.
argv0p
:=
StringBytePtr
(
argv
[
0
])
argvp
:=
StringArrayPtr
(
argv
)
var
chroot
*
byte
if
attr
.
Chroot
!=
""
{
chroot
=
StringBytePtr
(
attr
.
Chroot
)
}
var
dir
*
byte
if
attr
.
Dir
!=
""
{
dir
=
StringBytePtr
(
attr
.
Dir
)
}
var
envvParsed
[]
envItem
if
attr
.
Env
!=
nil
{
envvParsed
=
make
([]
envItem
,
0
,
len
(
attr
.
Env
))
for
_
,
v
:=
range
attr
.
Env
{
i
:=
0
for
i
<
len
(
v
)
&&
v
[
i
]
!=
'='
{
i
++
}
envvParsed
=
append
(
envvParsed
,
envItem
{
StringBytePtr
(
"/env/"
+
v
[
:
i
]),
StringBytePtr
(
v
[
i
+
1
:
]),
len
(
v
)
-
i
})
}
}
// Acquire the fork lock to prevent other threads from creating new fds before we fork.
ForkLock
.
Lock
()
// get a list of open fds, excluding stdin,stdout and stderr that need to be closed in the child.
// no new fds can be created while we hold the ForkLock for writing.
openFds
,
e
:=
readdupdevice
()
if
e
!=
nil
{
ForkLock
.
Unlock
()
return
0
,
e
}
fdsToClose
:=
make
([]
int
,
0
,
len
(
openFds
))
// exclude fds opened from startup from the list of fds to be closed.
for
_
,
fd
:=
range
openFds
{
isReserved
:=
false
for
_
,
reservedFd
:=
range
startupFds
{
if
fd
==
reservedFd
{
isReserved
=
true
break
}
}
if
!
isReserved
{
fdsToClose
=
append
(
fdsToClose
,
fd
)
}
}
// exclude fds requested by the caller from the list of fds to be closed.
for
_
,
fd
:=
range
openFds
{
isReserved
:=
false
for
_
,
reservedFd
:=
range
attr
.
Files
{
if
fd
==
reservedFd
{
isReserved
=
true
break
}
}
if
!
isReserved
{
fdsToClose
=
append
(
fdsToClose
,
fd
)
}
}
// Allocate child status pipe close on exec.
e
=
cexecPipe
(
p
[
:
])
if
e
!=
nil
{
return
0
,
e
}
fdsToClose
=
append
(
fdsToClose
,
p
[
0
])
// Kick off child.
pid
,
err
=
forkAndExecInChild
(
argv0p
,
argvp
,
envvParsed
,
chroot
,
dir
,
attr
,
fdsToClose
,
p
[
1
])
if
err
!=
nil
{
if
p
[
0
]
>=
0
{
Close
(
p
[
0
])
Close
(
p
[
1
])
}
ForkLock
.
Unlock
()
return
0
,
err
}
ForkLock
.
Unlock
()
// Read child error status from pipe.
Close
(
p
[
1
])
n
,
err
=
Read
(
p
[
0
],
errbuf
[
:
])
Close
(
p
[
0
])
if
err
!=
nil
||
n
!=
0
{
if
n
!=
0
{
err
=
NewError
(
string
(
errbuf
[
:
]))
}
// Child failed; wait for it to exit, to make sure
// the zombies don't accumulate.
for
wmsg
.
Pid
!=
pid
{
Await
(
&
wmsg
)
}
return
0
,
err
}
// Read got EOF, so pipe closed on exec, so exec succeeded.
return
pid
,
nil
}
// Combination of fork and exec, careful to be thread safe.
func
ForkExec
(
argv0
string
,
argv
[]
string
,
attr
*
ProcAttr
)
(
pid
int
,
err
Error
)
{
return
forkExec
(
argv0
,
argv
,
attr
)
}
// StartProcess wraps ForkExec for package os.
func
StartProcess
(
argv0
string
,
argv
[]
string
,
attr
*
ProcAttr
)
(
pid
,
handle
int
,
err
Error
)
{
pid
,
err
=
forkExec
(
argv0
,
argv
,
attr
)
return
pid
,
0
,
err
}
// Ordinary exec.
func
Exec
(
argv0
string
,
argv
[]
string
,
envv
[]
string
)
(
err
Error
)
{
if
envv
!=
nil
{
r1
,
_
,
_
:=
RawSyscall
(
SYS_RFORK
,
RFCENVG
,
0
,
0
)
if
int
(
r1
)
==
-
1
{
return
NewError
(
errstr
())
}
for
_
,
v
:=
range
envv
{
i
:=
0
for
i
<
len
(
v
)
&&
v
[
i
]
!=
'='
{
i
++
}
fd
,
e
:=
Create
(
"/env/"
+
v
[
:
i
],
O_WRONLY
,
0666
)
if
e
!=
nil
{
return
e
}
_
,
e
=
Write
(
fd
,
[]
byte
(
v
[
i
+
1
:
]))
if
e
!=
nil
{
Close
(
fd
)
return
e
}
Close
(
fd
)
}
}
_
,
_
,
e
:=
Syscall
(
SYS_EXEC
,
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
argv0
))),
uintptr
(
unsafe
.
Pointer
(
&
StringArrayPtr
(
argv
)[
0
])),
0
)
return
NewError
(
e
)
}
src/pkg/syscall/mkall.sh
View file @
1cc4a5cd
...
@@ -145,6 +145,12 @@ windows_386)
...
@@ -145,6 +145,12 @@ windows_386)
mktypes
=
mktypes
=
mkerrors
=
"./mkerrors_windows.sh -f -m32"
mkerrors
=
"./mkerrors_windows.sh -f -m32"
;;
;;
plan9_386
)
mkerrors
=
mksyscall
=
"./mksyscall.pl -l32 -plan9"
mksysnum
=
"./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
mktypes
=
"godefs -gsyscall -f -m32"
;;
*
)
*
)
echo
'unrecognized $GOOS_$GOARCH: '
"
$GOOSARCH
"
1>&2
echo
'unrecognized $GOOS_$GOARCH: '
"
$GOOSARCH
"
1>&2
exit
1
exit
1
...
...
src/pkg/syscall/mksyscall.pl
View file @
1cc4a5cd
...
@@ -23,6 +23,7 @@ $cmdline = "mksyscall.pl " . join(' ', @ARGV);
...
@@ -23,6 +23,7 @@ $cmdline = "mksyscall.pl " . join(' ', @ARGV);
$errors
=
0
;
$errors
=
0
;
$_32bit
=
"";
$_32bit
=
"";
$nacl
=
0
;
$nacl
=
0
;
$plan9
=
0
;
if
(
$ARGV
[
0
]
eq
"
-b32
")
{
if
(
$ARGV
[
0
]
eq
"
-b32
")
{
$_32bit
=
"
big-endian
";
$_32bit
=
"
big-endian
";
...
@@ -35,6 +36,10 @@ if($ARGV[0] eq "-nacl") {
...
@@ -35,6 +36,10 @@ if($ARGV[0] eq "-nacl") {
$nacl
=
1
;
$nacl
=
1
;
shift
;
shift
;
}
}
if
(
$ARGV
[
0
]
eq
"
-plan9
")
{
$plan9
=
1
;
shift
;
}
if
(
$ARGV
[
0
]
=~
/^-/
)
{
if
(
$ARGV
[
0
]
=~
/^-/
)
{
print
STDERR
"
usage: mksyscall.pl [-b32 | -l32] [file ...]
\n
";
print
STDERR
"
usage: mksyscall.pl [-b32 | -l32] [file ...]
\n
";
...
@@ -160,9 +165,13 @@ while(<>) {
...
@@ -160,9 +165,13 @@ while(<>) {
my
$p
=
$out
[
$i
];
my
$p
=
$out
[
$i
];
my
(
$name
,
$type
)
=
parseparam
(
$p
);
my
(
$name
,
$type
)
=
parseparam
(
$p
);
my
$reg
=
"";
my
$reg
=
"";
if
(
$name
eq
"
errno
")
{
if
(
$name
eq
"
errno
"
&&
!
$plan9
)
{
$reg
=
"
e1
";
$reg
=
"
e1
";
$ret
[
2
]
=
$reg
;
$ret
[
2
]
=
$reg
;
}
elsif
(
$name
eq
"
err
"
&&
$plan9
)
{
$ret
[
0
]
=
"
r0
";
$ret
[
2
]
=
"
e1
";
next
;
}
else
{
}
else
{
$reg
=
sprintf
("
r%d
",
$i
);
$reg
=
sprintf
("
r%d
",
$i
);
$ret
[
$i
]
=
$reg
;
$ret
[
$i
]
=
$reg
;
...
@@ -192,6 +201,13 @@ while(<>) {
...
@@ -192,6 +201,13 @@ while(<>) {
}
}
$text
.=
$body
;
$text
.=
$body
;
if
(
$plan9
&&
$ret
[
2
]
eq
"
e1
")
{
$text
.=
"
\t
err = nil
\n
";
$text
.=
"
\t
if int(r0) == -1 {
\n
";
$text
.=
"
\t\t
err = NewError(e1)
\n
";
$text
.=
"
\t
}
\n
";
}
$text
.=
"
\t
return
\n
";
$text
.=
"
\t
return
\n
";
$text
.=
"
}
\n\n
";
$text
.=
"
}
\n\n
";
}
}
...
...
src/pkg/syscall/mksysnum_plan9.sh
0 → 100755
View file @
1cc4a5cd
#!/bin/sh
# 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.# 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.
COMMAND
=
"mksysnum_plan9.sh
$@
"
cat
<<
EOF
//
$COMMAND
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
package syscall
const(
EOF
SP
=
'[ ]'
# space or tab
sed
"s/^#define
${
SP
}
\\
([A-Z0-9_][A-Z0-9_]*
\\
)
${
SP
}${
SP
}
*
\\
([0-9][0-9]*
\\
)/SYS_
\\
1=
\\
2/g"
\
<
$1
|
grep
-v
SYS__
cat
<<
EOF
)
EOF
src/pkg/syscall/str.go
View file @
1cc4a5cd
...
@@ -4,9 +4,9 @@
...
@@ -4,9 +4,9 @@
package
syscall
package
syscall
func
str
(
val
int
)
string
{
// do it here rather than with fmt to avoid dependency
func
itoa
(
val
int
)
string
{
// do it here rather than with fmt to avoid dependency
if
val
<
0
{
if
val
<
0
{
return
"-"
+
str
(
-
val
)
return
"-"
+
itoa
(
-
val
)
}
}
var
buf
[
32
]
byte
// big enough for int64
var
buf
[
32
]
byte
// big enough for int64
i
:=
len
(
buf
)
-
1
i
:=
len
(
buf
)
-
1
...
...
src/pkg/syscall/syscall_linux.go
View file @
1cc4a5cd
...
@@ -60,7 +60,7 @@ func Futimesat(dirfd int, path string, tv []Timeval) (errno int) {
...
@@ -60,7 +60,7 @@ func Futimesat(dirfd int, path string, tv []Timeval) (errno int) {
func
Futimes
(
fd
int
,
tv
[]
Timeval
)
(
errno
int
)
{
func
Futimes
(
fd
int
,
tv
[]
Timeval
)
(
errno
int
)
{
// Believe it or not, this is the best we can do on Linux
// Believe it or not, this is the best we can do on Linux
// (and is what glibc does).
// (and is what glibc does).
return
Utimes
(
"/proc/self/fd/"
+
str
(
fd
),
tv
)
return
Utimes
(
"/proc/self/fd/"
+
itoa
(
fd
),
tv
)
}
}
const
ImplementsGetwd
=
true
const
ImplementsGetwd
=
true
...
...
src/pkg/syscall/syscall_plan9.go
0 → 100644
View file @
1cc4a5cd
// Copyright 2011 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.
// Plan 9 system calls.
// This file is compiled as ordinary Go code,
// but it is also input to mksyscall,
// which parses the //sys lines and generates system call stubs.
// Note that sometimes we use a lowercase //sys name and
// wrap it in our own nicer implementation.
package
syscall
import
"unsafe"
const
OS
=
"plan9"
const
ImplementsGetwd
=
true
// An Error can represent any printable error condition.
type
Error
interface
{
String
()
string
}
// ErrorString implements Error's String method by returning itself.
type
ErrorString
string
func
(
e
ErrorString
)
String
()
string
{
return
string
(
e
)
}
// NewError converts s to an ErrorString, which satisfies the Error interface.
func
NewError
(
s
string
)
Error
{
return
ErrorString
(
s
)
}
var
(
Stdin
=
0
Stdout
=
1
Stderr
=
2
EISDIR
Error
=
NewError
(
"file is a directory"
)
)
func
Syscall
(
trap
,
a1
,
a2
,
a3
uintptr
)
(
r1
,
r2
uintptr
,
err
string
)
func
Syscall6
(
trap
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
uintptr
)
(
r1
,
r2
uintptr
,
err
string
)
func
RawSyscall
(
trap
,
a1
,
a2
,
a3
uintptr
)
(
r1
,
r2
,
err
uintptr
)
func
RawSyscall6
(
trap
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
uintptr
)
(
r1
,
r2
,
err
uintptr
)
func
atoi
(
b
[]
byte
)
(
n
uint
)
{
n
=
0
for
i
:=
0
;
i
<
len
(
b
);
i
++
{
n
=
n
*
10
+
uint
(
b
[
i
]
-
'0'
)
}
return
}
func
cstring
(
s
[]
byte
)
string
{
for
i
,
_
:=
range
s
{
if
s
[
i
]
==
0
{
return
string
(
s
[
0
:
i
])
}
}
return
string
(
s
)
}
func
errstr
()
string
{
var
buf
[
ERRMAX
]
byte
RawSyscall
(
SYS_ERRSTR
,
uintptr
(
unsafe
.
Pointer
(
&
buf
[
0
])),
uintptr
(
len
(
buf
)),
0
)
buf
[
len
(
buf
)
-
1
]
=
0
return
cstring
(
buf
[
:
])
}
func
Getpagesize
()
int
{
return
4096
}
//sys exits(msg *byte)
func
Exits
(
msg
*
string
)
{
if
msg
==
nil
{
exits
(
nil
)
}
exits
(
StringBytePtr
(
*
msg
))
}
func
Exit
(
code
int
)
{
if
code
==
0
{
Exits
(
nil
)
}
msg
:=
itoa
(
code
)
Exits
(
&
msg
)
}
func
readnum
(
path
string
)
(
uint
,
Error
)
{
var
b
[
12
]
byte
fd
,
e
:=
Open
(
path
,
O_RDONLY
)
if
e
!=
nil
{
return
0
,
e
}
defer
Close
(
fd
)
n
,
e
:=
Pread
(
fd
,
b
[
:
],
0
)
if
e
!=
nil
{
return
0
,
e
}
m
:=
0
for
;
m
<
n
&&
b
[
m
]
==
' '
;
m
++
{
}
return
atoi
(
b
[
m
:
n
-
1
]),
nil
}
func
Getpid
()
(
pid
int
)
{
n
,
_
:=
readnum
(
"#c/pid"
)
return
int
(
n
)
}
func
Getppid
()
(
ppid
int
)
{
n
,
_
:=
readnum
(
"#c/ppid"
)
return
int
(
n
)
}
func
Read
(
fd
int
,
p
[]
byte
)
(
n
int
,
err
Error
)
{
return
Pread
(
fd
,
p
,
-
1
)
}
func
Write
(
fd
int
,
p
[]
byte
)
(
n
int
,
err
Error
)
{
return
Pwrite
(
fd
,
p
,
-
1
)
}
func
Getwd
()
(
wd
string
,
err
Error
)
{
fd
,
e
:=
Open
(
"."
,
O_RDONLY
)
if
e
!=
nil
{
return
""
,
e
}
defer
Close
(
fd
)
return
Fd2path
(
fd
)
}
//sys fd2path(fd int, buf []byte) (err Error)
func
Fd2path
(
fd
int
)
(
path
string
,
err
Error
)
{
var
buf
[
512
]
byte
e
:=
fd2path
(
fd
,
buf
[
:
])
if
e
!=
nil
{
return
""
,
e
}
return
cstring
(
buf
[
:
]),
nil
}
//sys pipe(p *[2]_C_int) (err Error)
func
Pipe
(
p
[]
int
)
(
err
Error
)
{
if
len
(
p
)
!=
2
{
return
NewError
(
"bad arg in system call"
)
}
var
pp
[
2
]
_C_int
err
=
pipe
(
&
pp
)
p
[
0
]
=
int
(
pp
[
0
])
p
[
1
]
=
int
(
pp
[
1
])
return
}
//sys sleep(millisecs int32) (err Error)
func
Sleep
(
nsec
int64
)
(
err
Error
)
{
return
sleep
(
int32
((
nsec
+
999
)
/
1e6
))
// round up to microsecond
}
// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
func
seek
(
placeholder
uintptr
,
fd
int
,
offset
int64
,
whence
int
)
(
newoffset
int64
,
err
string
)
func
Seek
(
fd
int
,
offset
int64
,
whence
int
)
(
newoffset
int64
,
err
Error
)
{
newoffset
,
e
:=
seek
(
0
,
fd
,
offset
,
whence
)
err
=
nil
if
newoffset
==
-
1
{
err
=
NewError
(
e
)
}
return
}
func
Mkdir
(
path
string
,
mode
uint32
)
(
err
Error
)
{
fd
,
err
:=
Create
(
path
,
O_RDONLY
,
DMDIR
|
mode
)
if
fd
!=
-
1
{
Close
(
fd
)
}
return
}
type
Waitmsg
struct
{
Pid
int
Time
[
3
]
uint32
Msg
string
}
//sys await(s []byte) (n int, err Error)
func
Await
(
w
*
Waitmsg
)
(
err
Error
)
{
var
buf
[
512
]
byte
var
f
[
5
][]
byte
n
,
err
:=
await
(
buf
[
:
])
if
err
!=
nil
||
w
==
nil
{
return
}
nf
:=
0
p
:=
0
for
i
:=
0
;
i
<
n
&&
nf
<
len
(
f
)
-
1
;
i
++
{
if
buf
[
i
]
==
' '
{
f
[
nf
]
=
buf
[
p
:
i
]
p
=
i
+
1
nf
++
}
}
f
[
nf
]
=
buf
[
p
:
]
nf
++
if
nf
!=
len
(
f
)
{
return
NewError
(
"invalid wait message"
)
}
w
.
Pid
=
int
(
atoi
(
f
[
0
]))
w
.
Time
[
0
]
=
uint32
(
atoi
(
f
[
1
]))
w
.
Time
[
1
]
=
uint32
(
atoi
(
f
[
2
]))
w
.
Time
[
2
]
=
uint32
(
atoi
(
f
[
3
]))
w
.
Msg
=
string
(
f
[
4
])
return
}
func
Unmount
(
name
,
old
string
)
(
err
Error
)
{
oldp
:=
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
old
)))
var
r0
uintptr
var
e
string
// bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
if
name
==
""
{
r0
,
_
,
e
=
Syscall
(
SYS_UNMOUNT
,
_zero
,
oldp
,
0
)
}
else
{
r0
,
_
,
e
=
Syscall
(
SYS_UNMOUNT
,
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
name
))),
oldp
,
0
)
}
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e
)
}
return
}
func
Fchdir
(
fd
int
)
(
err
Error
)
{
path
,
err
:=
Fd2path
(
fd
)
if
err
!=
nil
{
return
}
return
Chdir
(
path
)
}
type
Timeval
struct
{
Sec
int32
Usec
int32
}
func
NsecToTimeval
(
nsec
int64
)
(
tv
Timeval
)
{
nsec
+=
999
// round up to microsecond
tv
.
Usec
=
int32
(
nsec
%
1e9
/
1e3
)
tv
.
Sec
=
int32
(
nsec
/
1e9
)
return
}
func
DecodeBintime
(
b
[]
byte
)
(
nsec
int64
,
err
Error
)
{
if
len
(
b
)
!=
8
{
return
-
1
,
NewError
(
"bad /dev/bintime format"
)
}
err
=
nil
nsec
=
int64
(
b
[
0
])
<<
56
|
int64
(
b
[
1
])
<<
48
|
int64
(
b
[
2
])
<<
40
|
int64
(
b
[
3
])
<<
32
|
int64
(
b
[
4
])
<<
24
|
int64
(
b
[
5
])
<<
16
|
int64
(
b
[
6
])
<<
8
|
int64
(
b
[
7
])
return
}
func
Gettimeofday
(
tv
*
Timeval
)
(
err
Error
)
{
// TODO(paulzhol):
// avoid reopening a file descriptor for /dev/bintime on each call,
// use lower-level calls to avoid allocation.
var
b
[
8
]
byte
var
nsec
int64
fd
,
e
:=
Open
(
"/dev/bintime"
,
O_RDONLY
)
if
e
!=
nil
{
return
e
}
defer
Close
(
fd
)
if
_
,
e
=
Pread
(
fd
,
b
[
:
],
0
);
e
!=
nil
{
return
e
}
if
nsec
,
e
=
DecodeBintime
(
b
[
:
]);
e
!=
nil
{
return
e
}
*
tv
=
NsecToTimeval
(
nsec
)
return
e
}
func
Getegid
()
(
egid
int
)
{
return
-
1
}
func
Geteuid
()
(
euid
int
)
{
return
-
1
}
func
Getgid
()
(
gid
int
)
{
return
-
1
}
func
Getuid
()
(
uid
int
)
{
return
-
1
}
func
Getgroups
()
(
gids
[]
int
,
err
Error
)
{
return
make
([]
int
,
0
),
nil
}
//sys Dup(oldfd int, newfd int) (fd int, err Error)
//sys Open(path string, mode int) (fd int, err Error)
//sys Create(path string, mode int, perm uint32) (fd int, err Error)
//sys Remove(path string) (err Error)
//sys Pread(fd int, p []byte, offset int64) (n int, err Error)
//sys Pwrite(fd int, p []byte, offset int64) (n int, err Error)
//sys Close(fd int) (err Error)
//sys Chdir(path string) (err Error)
//sys Bind(name string, old string, flag int) (err Error)
//sys Mount(fd int, afd int, old string, flag int, aname string) (err Error)
//sys Stat(path string, edir []byte) (n int, err Error)
//sys Fstat(fd int, edir []byte) (n int, err Error)
//sys Wstat(path string, edir []byte) (err Error)
//sys Fwstat(fd int, edir []byte) (err Error)
src/pkg/syscall/syscall_plan9_386.go
0 → 100644
View file @
1cc4a5cd
// 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
syscall
src/pkg/syscall/syscall_unix.go
View file @
1cc4a5cd
...
@@ -17,7 +17,7 @@ func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
...
@@ -17,7 +17,7 @@ func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
func
Errstr
(
errno
int
)
string
{
func
Errstr
(
errno
int
)
string
{
if
errno
<
0
||
errno
>=
int
(
len
(
errors
))
{
if
errno
<
0
||
errno
>=
int
(
len
(
errors
))
{
return
"error "
+
str
(
errno
)
return
"error "
+
itoa
(
errno
)
}
}
return
errors
[
errno
]
return
errors
[
errno
]
}
}
src/pkg/syscall/syscall_windows.go
View file @
1cc4a5cd
...
@@ -175,7 +175,7 @@ func Errstr(errno int) string {
...
@@ -175,7 +175,7 @@ func Errstr(errno int) string {
b
:=
make
([]
uint16
,
300
)
b
:=
make
([]
uint16
,
300
)
n
,
err
:=
FormatMessage
(
flags
,
0
,
uint32
(
errno
),
0
,
b
,
nil
)
n
,
err
:=
FormatMessage
(
flags
,
0
,
uint32
(
errno
),
0
,
b
,
nil
)
if
err
!=
0
{
if
err
!=
0
{
return
"error "
+
str
(
errno
)
+
" (FormatMessage failed with err="
+
str
(
err
)
+
")"
return
"error "
+
itoa
(
errno
)
+
" (FormatMessage failed with err="
+
itoa
(
err
)
+
")"
}
}
// trim terminating \r and \n
// trim terminating \r and \n
for
;
n
>
0
&&
(
b
[
n
-
1
]
==
'\n'
||
b
[
n
-
1
]
==
'\r'
);
n
--
{
for
;
n
>
0
&&
(
b
[
n
-
1
]
==
'\n'
||
b
[
n
-
1
]
==
'\r'
);
n
--
{
...
...
src/pkg/syscall/types_plan9.c
0 → 100644
View file @
1cc4a5cd
// 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.
/*
Input to godefs. See also mkerrors.sh and mkall.sh
*/
typedef
unsigned
short
ushort
;
typedef
unsigned
char
uchar
;
typedef
unsigned
long
ulong
;
typedef
unsigned
int
uint
;
typedef
long
long
vlong
;
typedef
unsigned
long
long
uvlong
;
typedef
int
$
_C_int
;
enum
{
OREAD
=
0
,
// open for read
OWRITE
=
1
,
// write
ORDWR
=
2
,
// read and write
$
O_RDONLY
=
OREAD
,
$
O_WRONLY
=
OWRITE
,
$
O_RDWR
=
ORDWR
,
OEXEC
=
3
,
// execute, == read but check execute permission
OTRUNC
=
16
,
// or'ed in (except for exec), truncate file first
OCEXEC
=
32
,
// or'ed in, close on exec
$
O_CLOEXEC
=
OCEXEC
,
ORCLOSE
=
64
,
// or'ed in, remove on close
OEXCL
=
0x1000
,
// or'ed in, exclusive use (create only)
$
O_EXCL
=
OEXCL
,
$
STATMAX
=
65535U
,
$
ERRMAX
=
128
,
$
MORDER
=
0x0003
,
// mask for bits defining order of mounting
$
MREPL
=
0x0000
,
// mount replaces object
$
MBEFORE
=
0x0001
,
// mount goes before others in union directory
$
MAFTER
=
0x0002
,
// mount goes after others in union directory
$
MCREATE
=
0x0004
,
// permit creation in mounted directory
$
MCACHE
=
0x0010
,
// cache some data
$
MMASK
=
0x0017
,
// all bits on
$
RFNAMEG
=
(
1
<<
0
),
$
RFENVG
=
(
1
<<
1
),
$
RFFDG
=
(
1
<<
2
),
$
RFNOTEG
=
(
1
<<
3
),
$
RFPROC
=
(
1
<<
4
),
$
RFMEM
=
(
1
<<
5
),
$
RFNOWAIT
=
(
1
<<
6
),
$
RFCNAMEG
=
(
1
<<
10
),
$
RFCENVG
=
(
1
<<
11
),
$
RFCFDG
=
(
1
<<
12
),
$
RFREND
=
(
1
<<
13
),
$
RFNOMNT
=
(
1
<<
14
),
// bits in Qid.type
$
QTDIR
=
0x80
,
// type bit for directories
$
QTAPPEND
=
0x40
,
// type bit for append only files
$
QTEXCL
=
0x20
,
// type bit for exclusive use files
$
QTMOUNT
=
0x10
,
// type bit for mounted channel
$
QTAUTH
=
0x08
,
// type bit for authentication file
$
QTTMP
=
0x04
,
// type bit for not-backed-up file
$
QTFILE
=
0x00
,
// plain file
// bits in Dir.mode
$
DMDIR
=
0x80000000
,
// mode bit for directories
$
DMAPPEND
=
0x40000000
,
// mode bit for append only files
$
DMEXCL
=
0x20000000
,
// mode bit for exclusive use files
$
DMMOUNT
=
0x10000000
,
// mode bit for mounted channel
$
DMAUTH
=
0x08000000
,
// mode bit for authentication file
$
DMTMP
=
0x04000000
,
// mode bit for non-backed-up files
$
DMREAD
=
0x4
,
// mode bit for read permission
$
DMWRITE
=
0x2
,
// mode bit for write permission
$
DMEXEC
=
0x1
,
// mode bit for execute permission
BIT8SZ
=
1
,
BIT16SZ
=
2
,
BIT32SZ
=
4
,
BIT64SZ
=
8
,
QIDSZ
=
BIT8SZ
+
BIT32SZ
+
BIT64SZ
,
// STATFIXLEN includes leading 16-bit count
// The count, however, excludes itself; total size is BIT16SZ+count
$
STATFIXLEN
=
BIT16SZ
+
QIDSZ
+
5
*
BIT16SZ
+
4
*
BIT32SZ
+
1
*
BIT64SZ
,
// amount of fixed length data in a stat buffer
};
struct
Prof
// Per process profiling
{
struct
Plink
*
pp
;
// known to be 0(ptr)
struct
Plink
*
next
;
// known to be 4(ptr)
struct
Plink
*
last
;
struct
Plink
*
first
;
ulong
pid
;
ulong
what
;
};
struct
Tos
{
struct
Prof
prof
;
uvlong
cyclefreq
;
// cycle clock frequency if there is one, 0 otherwise
vlong
kcycles
;
// cycles spent in kernel
vlong
pcycles
;
// cycles spent in process (kernel + user)
ulong
pid
;
// might as well put the pid here
ulong
clock
;
// top of stack is here
};
typedef
struct
Prof
$
Prof
;
typedef
struct
Tos
$
Tos
;
src/pkg/syscall/zerrors_plan9_386.go
0 → 100644
View file @
1cc4a5cd
package
syscall
// Constants
const
(
// Invented values to support what package os expects.
O_CREAT
=
0x02000
O_NOCTTY
=
0x00000
O_TRUNC
=
0x00000
O_NONBLOCK
=
0x00000
O_APPEND
=
0x00000
O_SYNC
=
0x00000
O_ASYNC
=
0x00000
S_IFMT
=
0x1f000
S_IFIFO
=
0x1000
S_IFCHR
=
0x2000
S_IFDIR
=
0x4000
S_IFBLK
=
0x6000
S_IFREG
=
0x8000
S_IFLNK
=
0xa000
S_IFSOCK
=
0xc000
)
// Error table
src/pkg/syscall/zsyscall_plan9_386.go
0 → 100644
View file @
1cc4a5cd
// mksyscall.pl -l32 -plan9 syscall_plan9.go syscall_plan9_386.go
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
package
syscall
import
"unsafe"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
exits
(
msg
*
byte
)
{
Syscall
(
SYS_EXITS
,
uintptr
(
unsafe
.
Pointer
(
msg
)),
0
,
0
)
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
fd2path
(
fd
int
,
buf
[]
byte
)
(
err
Error
)
{
var
_p0
unsafe
.
Pointer
if
len
(
buf
)
>
0
{
_p0
=
unsafe
.
Pointer
(
&
buf
[
0
])
}
else
{
_p0
=
unsafe
.
Pointer
(
&
_zero
)
}
r0
,
_
,
e1
:=
Syscall
(
SYS_FD2PATH
,
uintptr
(
fd
),
uintptr
(
_p0
),
uintptr
(
len
(
buf
)))
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
pipe
(
p
*
[
2
]
_C_int
)
(
err
Error
)
{
r0
,
_
,
e1
:=
Syscall
(
SYS_PIPE
,
uintptr
(
unsafe
.
Pointer
(
p
)),
0
,
0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
sleep
(
millisecs
int32
)
(
err
Error
)
{
r0
,
_
,
e1
:=
Syscall
(
SYS_SLEEP
,
uintptr
(
millisecs
),
0
,
0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
await
(
s
[]
byte
)
(
n
int
,
err
Error
)
{
var
_p0
unsafe
.
Pointer
if
len
(
s
)
>
0
{
_p0
=
unsafe
.
Pointer
(
&
s
[
0
])
}
else
{
_p0
=
unsafe
.
Pointer
(
&
_zero
)
}
r0
,
_
,
e1
:=
Syscall
(
SYS_AWAIT
,
uintptr
(
_p0
),
uintptr
(
len
(
s
)),
0
)
n
=
int
(
r0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Dup
(
oldfd
int
,
newfd
int
)
(
fd
int
,
err
Error
)
{
r0
,
_
,
e1
:=
Syscall
(
SYS_DUP
,
uintptr
(
oldfd
),
uintptr
(
newfd
),
0
)
fd
=
int
(
r0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Open
(
path
string
,
mode
int
)
(
fd
int
,
err
Error
)
{
r0
,
_
,
e1
:=
Syscall
(
SYS_OPEN
,
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
path
))),
uintptr
(
mode
),
0
)
fd
=
int
(
r0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Create
(
path
string
,
mode
int
,
perm
uint32
)
(
fd
int
,
err
Error
)
{
r0
,
_
,
e1
:=
Syscall
(
SYS_CREATE
,
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
path
))),
uintptr
(
mode
),
uintptr
(
perm
))
fd
=
int
(
r0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Remove
(
path
string
)
(
err
Error
)
{
r0
,
_
,
e1
:=
Syscall
(
SYS_REMOVE
,
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
path
))),
0
,
0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Pread
(
fd
int
,
p
[]
byte
,
offset
int64
)
(
n
int
,
err
Error
)
{
var
_p0
unsafe
.
Pointer
if
len
(
p
)
>
0
{
_p0
=
unsafe
.
Pointer
(
&
p
[
0
])
}
else
{
_p0
=
unsafe
.
Pointer
(
&
_zero
)
}
r0
,
_
,
e1
:=
Syscall6
(
SYS_PREAD
,
uintptr
(
fd
),
uintptr
(
_p0
),
uintptr
(
len
(
p
)),
uintptr
(
offset
),
uintptr
(
offset
>>
32
),
0
)
n
=
int
(
r0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Pwrite
(
fd
int
,
p
[]
byte
,
offset
int64
)
(
n
int
,
err
Error
)
{
var
_p0
unsafe
.
Pointer
if
len
(
p
)
>
0
{
_p0
=
unsafe
.
Pointer
(
&
p
[
0
])
}
else
{
_p0
=
unsafe
.
Pointer
(
&
_zero
)
}
r0
,
_
,
e1
:=
Syscall6
(
SYS_PWRITE
,
uintptr
(
fd
),
uintptr
(
_p0
),
uintptr
(
len
(
p
)),
uintptr
(
offset
),
uintptr
(
offset
>>
32
),
0
)
n
=
int
(
r0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Close
(
fd
int
)
(
err
Error
)
{
r0
,
_
,
e1
:=
Syscall
(
SYS_CLOSE
,
uintptr
(
fd
),
0
,
0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Chdir
(
path
string
)
(
err
Error
)
{
r0
,
_
,
e1
:=
Syscall
(
SYS_CHDIR
,
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
path
))),
0
,
0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Bind
(
name
string
,
old
string
,
flag
int
)
(
err
Error
)
{
r0
,
_
,
e1
:=
Syscall
(
SYS_BIND
,
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
name
))),
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
old
))),
uintptr
(
flag
))
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Mount
(
fd
int
,
afd
int
,
old
string
,
flag
int
,
aname
string
)
(
err
Error
)
{
r0
,
_
,
e1
:=
Syscall6
(
SYS_MOUNT
,
uintptr
(
fd
),
uintptr
(
afd
),
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
old
))),
uintptr
(
flag
),
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
aname
))),
0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Stat
(
path
string
,
edir
[]
byte
)
(
n
int
,
err
Error
)
{
var
_p0
unsafe
.
Pointer
if
len
(
edir
)
>
0
{
_p0
=
unsafe
.
Pointer
(
&
edir
[
0
])
}
else
{
_p0
=
unsafe
.
Pointer
(
&
_zero
)
}
r0
,
_
,
e1
:=
Syscall
(
SYS_STAT
,
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
path
))),
uintptr
(
_p0
),
uintptr
(
len
(
edir
)))
n
=
int
(
r0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Fstat
(
fd
int
,
edir
[]
byte
)
(
n
int
,
err
Error
)
{
var
_p0
unsafe
.
Pointer
if
len
(
edir
)
>
0
{
_p0
=
unsafe
.
Pointer
(
&
edir
[
0
])
}
else
{
_p0
=
unsafe
.
Pointer
(
&
_zero
)
}
r0
,
_
,
e1
:=
Syscall
(
SYS_FSTAT
,
uintptr
(
fd
),
uintptr
(
_p0
),
uintptr
(
len
(
edir
)))
n
=
int
(
r0
)
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Wstat
(
path
string
,
edir
[]
byte
)
(
err
Error
)
{
var
_p0
unsafe
.
Pointer
if
len
(
edir
)
>
0
{
_p0
=
unsafe
.
Pointer
(
&
edir
[
0
])
}
else
{
_p0
=
unsafe
.
Pointer
(
&
_zero
)
}
r0
,
_
,
e1
:=
Syscall
(
SYS_WSTAT
,
uintptr
(
unsafe
.
Pointer
(
StringBytePtr
(
path
))),
uintptr
(
_p0
),
uintptr
(
len
(
edir
)))
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func
Fwstat
(
fd
int
,
edir
[]
byte
)
(
err
Error
)
{
var
_p0
unsafe
.
Pointer
if
len
(
edir
)
>
0
{
_p0
=
unsafe
.
Pointer
(
&
edir
[
0
])
}
else
{
_p0
=
unsafe
.
Pointer
(
&
_zero
)
}
r0
,
_
,
e1
:=
Syscall
(
SYS_FWSTAT
,
uintptr
(
fd
),
uintptr
(
_p0
),
uintptr
(
len
(
edir
)))
err
=
nil
if
int
(
r0
)
==
-
1
{
err
=
NewError
(
e1
)
}
return
}
src/pkg/syscall/zsysnum_plan9_386.go
0 → 100644
View file @
1cc4a5cd
// mksysnum_plan9.sh /media/sys/src/libc/9syscall/sys.h
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
package
syscall
const
(
SYS_SYSR1
=
0
SYS_BIND
=
2
SYS_CHDIR
=
3
SYS_CLOSE
=
4
SYS_DUP
=
5
SYS_ALARM
=
6
SYS_EXEC
=
7
SYS_EXITS
=
8
SYS_FAUTH
=
10
SYS_SEGBRK
=
12
SYS_OPEN
=
14
SYS_OSEEK
=
16
SYS_SLEEP
=
17
SYS_RFORK
=
19
SYS_PIPE
=
21
SYS_CREATE
=
22
SYS_FD2PATH
=
23
SYS_BRK_
=
24
SYS_REMOVE
=
25
SYS_NOTIFY
=
28
SYS_NOTED
=
29
SYS_SEGATTACH
=
30
SYS_SEGDETACH
=
31
SYS_SEGFREE
=
32
SYS_SEGFLUSH
=
33
SYS_RENDEZVOUS
=
34
SYS_UNMOUNT
=
35
SYS_SEMACQUIRE
=
37
SYS_SEMRELEASE
=
38
SYS_SEEK
=
39
SYS_FVERSION
=
40
SYS_ERRSTR
=
41
SYS_STAT
=
42
SYS_FSTAT
=
43
SYS_WSTAT
=
44
SYS_FWSTAT
=
45
SYS_MOUNT
=
46
SYS_AWAIT
=
47
SYS_PREAD
=
50
SYS_PWRITE
=
51
)
src/pkg/syscall/ztypes_plan9_386.go
0 → 100644
View file @
1cc4a5cd
// godefs -gsyscall -f -m32 types_plan9.c
// MACHINE GENERATED - DO NOT EDIT.
package
syscall
// Constants
const
(
O_RDONLY
=
0
O_WRONLY
=
0x1
O_RDWR
=
0x2
O_CLOEXEC
=
0x20
O_EXCL
=
0x1000
STATMAX
=
0xffff
ERRMAX
=
0x80
MORDER
=
0x3
MREPL
=
0
MBEFORE
=
0x1
MAFTER
=
0x2
MCREATE
=
0x4
MCACHE
=
0x10
MMASK
=
0x17
RFNAMEG
=
0x1
RFENVG
=
0x2
RFFDG
=
0x4
RFNOTEG
=
0x8
RFPROC
=
0x10
RFMEM
=
0x20
RFNOWAIT
=
0x40
RFCNAMEG
=
0x400
RFCENVG
=
0x800
RFCFDG
=
0x1000
RFREND
=
0x2000
RFNOMNT
=
0x4000
QTDIR
=
0x80
QTAPPEND
=
0x40
QTEXCL
=
0x20
QTMOUNT
=
0x10
QTAUTH
=
0x8
QTTMP
=
0x4
QTFILE
=
0
DMDIR
=
0x80000000
DMAPPEND
=
0x40000000
DMEXCL
=
0x20000000
DMMOUNT
=
0x10000000
DMAUTH
=
0x8000000
DMTMP
=
0x4000000
DMREAD
=
0x4
DMWRITE
=
0x2
DMEXEC
=
0x1
STATFIXLEN
=
0x31
)
// Types
type
_C_int
int32
type
Prof
struct
{
Pp
*
[
0
]
byte
/* sPlink */
Next
*
[
0
]
byte
/* sPlink */
Last
*
[
0
]
byte
/* sPlink */
First
*
[
0
]
byte
/* sPlink */
Pid
uint32
What
uint32
}
type
Tos
struct
{
Prof
Prof
Cyclefreq
uint64
Kcycles
int64
Pcycles
int64
Pid
uint32
Clock
uint32
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment