source: code/trunk/vendor/modernc.org/libc/ioutil_linux.go@ 823

Last change on this file since 823 was 822, checked in by yakumo.izuru, 22 months ago

Prefer immortal.run over runit and rc.d, use vendored modules
for convenience.

Signed-off-by: Izuru Yakumo <yakumo.izuru@…>

File size: 1.7 KB
Line 
1// Copyright 2010 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-GO file.
4
5// Modifications Copyright 2020 The Libc Authors. All rights reserved.
6// Use of this source code is governed by a BSD-style
7// license that can be found in the LICENSE file.
8
9package libc // import "modernc.org/libc"
10
11import (
12 "fmt"
13 "os"
14 "sync"
15 "time"
16 "unsafe"
17
18 "golang.org/x/sys/unix"
19 "modernc.org/libc/errno"
20 "modernc.org/libc/fcntl"
21)
22
23// Random number state.
24// We generate random temporary file names so that there's a good
25// chance the file doesn't exist yet - keeps the number of tries in
26// TempFile to a minimum.
27var randState uint32
28var randStateMu sync.Mutex
29
30func reseed() uint32 {
31 return uint32(time.Now().UnixNano() + int64(os.Getpid()))
32}
33
34func nextRandom(x uintptr) {
35 randStateMu.Lock()
36 r := randState
37 if r == 0 {
38 r = reseed()
39 }
40 r = r*1664525 + 1013904223 // constants from Numerical Recipes
41 randState = r
42 randStateMu.Unlock()
43 copy((*RawMem)(unsafe.Pointer(x))[:6:6], fmt.Sprintf("%06d", int(1e9+r%1e9)%1e6))
44}
45
46func tempFile(s, x uintptr, flags int32) (fd int, err error) {
47 const maxTry = 10000
48 nconflict := 0
49 flags |= int32(os.O_RDWR | os.O_CREATE | os.O_EXCL | unix.O_LARGEFILE)
50 for i := 0; i < maxTry; i++ {
51 nextRandom(x)
52 fdcwd := fcntl.AT_FDCWD
53 n, _, err := unix.Syscall6(unix.SYS_OPENAT, uintptr(fdcwd), s, uintptr(flags), 0600, 0, 0)
54 if err == 0 {
55 return int(n), nil
56 }
57
58 if err != errno.EEXIST {
59 return -1, err
60 }
61
62 if nconflict++; nconflict > 10 {
63 randStateMu.Lock()
64 randState = reseed()
65 nconflict = 0
66 randStateMu.Unlock()
67 }
68 }
69 return -1, unix.Errno(errno.EEXIST)
70}
Note: See TracBrowser for help on using the repository browser.