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
5package runtime
6
7import (
8	"unsafe"
9)
10
11// For C code to call:
12//go:linkname minit
13
14func goenvs() {
15	goenvs_unix()
16}
17
18// Called to initialize a new m (including the bootstrap m).
19// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
20func mpreinit(mp *m) {
21	mp.gsignal = malg(true, true, &mp.gsignalstack, &mp.gsignalstacksize)
22	mp.gsignal.m = mp
23}
24
25// minit is called to initialize a new m (including the bootstrap m).
26// Called on the new thread, cannot allocate memory.
27func minit() {
28	minitSignals()
29
30	// FIXME: only works on linux for now.
31	getg().m.procid = uint64(gettid())
32}
33
34// Called from dropm to undo the effect of an minit.
35//go:nosplit
36//go:nowritebarrierrec
37func unminit() {
38	unminitSignals()
39}
40
41var urandom_dev = []byte("/dev/urandom\x00")
42
43func getRandomData(r []byte) {
44	if startupRandomData != nil {
45		n := copy(r, startupRandomData)
46		extendRandom(r, n)
47		return
48	}
49	fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
50	n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
51	closefd(fd)
52	extendRandom(r, int(n))
53}
54
55//go:noescape
56//extern pipe
57func libcPipe(*[2]int32) int32
58
59func pipe() (r, w int32, e int32) {
60	var p [2]int32
61	res := libcPipe(&p)
62	if res < 0 {
63		e = int32(errno())
64	}
65	return p[0], p[1], e
66}
67
68//go:noescape
69//extern pipe2
70func libcPipe2(*[2]int32, int32) int32
71
72func pipe2(flags int32) (r, w int32, e int32) {
73	var p [2]int32
74	res := libcPipe2(&p, flags)
75	if res < 0 {
76		e = int32(errno())
77	}
78	return p[0], p[1], e
79}
80
81//extern __go_fcntl_uintptr
82func fcntlUintptr(fd, cmd, arg uintptr) (uintptr, uintptr)
83
84//go:nosplit
85func closeonexec(fd int32) {
86	fcntlUintptr(uintptr(fd), _F_SETFD, _FD_CLOEXEC)
87}
88
89//go:nosplit
90func setNonblock(fd int32) {
91	flags, errno := fcntlUintptr(uintptr(fd), _F_GETFL, 0)
92	if errno == 0 {
93		fcntlUintptr(uintptr(fd), _F_SETFL, flags|_O_NONBLOCK)
94	}
95}
96