gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ioutil_openbsd.go (1512B)


      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 
      9 package libc // import "modernc.org/libc"
     10 
     11 import (
     12 	"fmt"
     13 	"os"
     14 	"sync"
     15 	"time"
     16 	"unsafe"
     17 
     18 	"golang.org/x/sys/unix"
     19 )
     20 
     21 // Random number state.
     22 // We generate random temporary file names so that there's a good
     23 // chance the file doesn't exist yet - keeps the number of tries in
     24 // TempFile to a minimum.
     25 var randState uint32
     26 var randStateMu sync.Mutex
     27 
     28 func reseed() uint32 {
     29 	return uint32(time.Now().UnixNano() + int64(os.Getpid()))
     30 }
     31 
     32 func nextRandom(x uintptr) {
     33 	randStateMu.Lock()
     34 	r := randState
     35 	if r == 0 {
     36 		r = reseed()
     37 	}
     38 	r = r*1664525 + 1013904223 // constants from Numerical Recipes
     39 	randState = r
     40 	randStateMu.Unlock()
     41 	copy((*RawMem)(unsafe.Pointer(x))[:6:6], fmt.Sprintf("%06d", int(1e9+r%1e9)%1e6))
     42 }
     43 
     44 func tempFile(s, x uintptr, _ int32) (fd int, err error) {
     45 	const maxTry = 10000
     46 	nconflict := 0
     47 	for i := 0; i < maxTry; i++ {
     48 		nextRandom(x)
     49 		if fd, err = unix.Open(GoString(s), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600); err == nil {
     50 			return fd, nil
     51 		}
     52 
     53 		if !os.IsExist(err) {
     54 			return -1, err
     55 		}
     56 
     57 		if nconflict++; nconflict > 10 {
     58 			randStateMu.Lock()
     59 			randState = reseed()
     60 			nconflict = 0
     61 			randStateMu.Unlock()
     62 		}
     63 	}
     64 	return -1, err
     65 }