github.com/tardisgo/tardisgo@v0.0.0-20161119180838-e0dd9a7e46b5/goroot/haxe/go1.4/src/io/ioutil/tempfile.go (about)

     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 file.
     4  
     5  package ioutil
     6  
     7  import (
     8  	"os"
     9  	"path/filepath"
    10  	"strconv"
    11  	"sync"
    12  	"time"
    13  )
    14  
    15  // Random number state.
    16  // We generate random temporary file names so that there's a good
    17  // chance the file doesn't exist yet - keeps the number of tries in
    18  // TempFile to a minimum.
    19  var rand uint32
    20  var randmu sync.Mutex
    21  
    22  func reseed() uint32 {
    23  	return uint32(time.Now().UnixNano() + int64(os.Getpid()))
    24  }
    25  
    26  func nextSuffix() string {
    27  	randmu.Lock()
    28  	r := rand
    29  	if r == 0 {
    30  		r = reseed()
    31  	}
    32  	r = r*1664525 + 1013904223 // constants from Numerical Recipes
    33  	rand = r
    34  	randmu.Unlock()
    35  	return strconv.Itoa(int(1e9 + r%1e9))[1:]
    36  }
    37  
    38  // TempFile creates a new temporary file in the directory dir
    39  // with a name beginning with prefix, opens the file for reading
    40  // and writing, and returns the resulting *os.File.
    41  // If dir is the empty string, TempFile uses the default directory
    42  // for temporary files (see os.TempDir).
    43  // Multiple programs calling TempFile simultaneously
    44  // will not choose the same file.  The caller can use f.Name()
    45  // to find the pathname of the file.  It is the caller's responsibility
    46  // to remove the file when no longer needed.
    47  func TempFile(dir, prefix string) (f *os.File, err error) {
    48  	if dir == "" {
    49  		dir = os.TempDir()
    50  	}
    51  
    52  	nconflict := 0
    53  	for i := 0; i < 10000; i++ {
    54  		name := filepath.Join(dir, prefix+nextSuffix())
    55  		f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
    56  		if os.IsExist(err) {
    57  			if nconflict++; nconflict > 10 {
    58  				rand = reseed()
    59  			}
    60  			continue
    61  		}
    62  		break
    63  	}
    64  	return
    65  }
    66  
    67  // TempDir creates a new temporary directory in the directory dir
    68  // with a name beginning with prefix and returns the path of the
    69  // new directory.  If dir is the empty string, TempDir uses the
    70  // default directory for temporary files (see os.TempDir).
    71  // Multiple programs calling TempDir simultaneously
    72  // will not choose the same directory.  It is the caller's responsibility
    73  // to remove the directory when no longer needed.
    74  func TempDir(dir, prefix string) (name string, err error) {
    75  	if dir == "" {
    76  		dir = os.TempDir()
    77  	}
    78  
    79  	nconflict := 0
    80  	for i := 0; i < 10000; i++ {
    81  		try := filepath.Join(dir, prefix+nextSuffix())
    82  		err = os.Mkdir(try, 0700)
    83  		if os.IsExist(err) {
    84  			if nconflict++; nconflict > 10 {
    85  				rand = reseed()
    86  			}
    87  			continue
    88  		}
    89  		if err == nil {
    90  			name = try
    91  		}
    92  		break
    93  	}
    94  	return
    95  }