1// +build js
2
3package testing
4
5import (
6	"bytes"
7	"io"
8	"os"
9	"strconv"
10	"sync"
11	"time"
12)
13
14var rand uint32
15var randmu sync.Mutex
16
17func reseed() uint32 {
18	return uint32(time.Now().UnixNano() + int64(os.Getpid()))
19}
20
21func nextSuffix() string {
22	randmu.Lock()
23	r := rand
24	if r == 0 {
25		r = reseed()
26	}
27	r = r*1664525 + 1013904223 // constants from Numerical Recipes
28	rand = r
29	randmu.Unlock()
30	return strconv.Itoa(int(1e9 + r%1e9))[1:]
31}
32
33// A functional copy of ioutil.TempFile, to avoid extra imports.
34func tempFile(prefix string) (f *os.File, err error) {
35	dir := os.TempDir()
36
37	nconflict := 0
38	for i := 0; i < 10000; i++ {
39		name := dir + string(os.PathSeparator) + prefix + nextSuffix()
40		f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
41		if os.IsExist(err) {
42			if nconflict++; nconflict > 10 {
43				randmu.Lock()
44				rand = reseed()
45				randmu.Unlock()
46			}
47			continue
48		}
49		break
50	}
51	return
52}
53
54func readFile(filename string) (string, error) {
55	f, err := os.Open(filename)
56	if err != nil {
57		return "", err
58	}
59	defer f.Close()
60	var buf bytes.Buffer
61	_, err = io.Copy(&buf, f)
62	if err != nil {
63		return "", err
64	}
65	return buf.String(), nil
66}
67