// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ioutil

import (
	
	
	
	
	
	
	
)

// Random number state.
// We generate random temporary file names so that there's a good
// chance the file doesn't exist yet - keeps the number of tries in
// TempFile to a minimum.
var rand uint32
var randmu sync.Mutex

func reseed() uint32 {
	return uint32(time.Now().UnixNano() + int64(os.Getpid()))
}

func nextRandom() string {
	randmu.Lock()
	 := rand
	if  == 0 {
		 = reseed()
	}
	 = *1664525 + 1013904223 // constants from Numerical Recipes
	rand = 
	randmu.Unlock()
	return strconv.Itoa(int(1e9 + %1e9))[1:]
}

// TempFile creates a new temporary file in the directory dir,
// opens the file for reading and writing, and returns the resulting *os.File.
// The filename is generated by taking pattern and adding a random
// string to the end. If pattern includes a "*", the random string
// replaces the last "*".
// If dir is the empty string, TempFile uses the default directory
// for temporary files (see os.TempDir).
// Multiple programs calling TempFile simultaneously
// will not choose the same file. The caller can use f.Name()
// to find the pathname of the file. It is the caller's responsibility
// to remove the file when no longer needed.
func (,  string) ( *os.File,  error) {
	if  == "" {
		 = os.TempDir()
	}

	, ,  := prefixAndSuffix()
	if  != nil {
		return
	}

	 := 0
	for  := 0;  < 10000; ++ {
		 := filepath.Join(, +nextRandom()+)
		,  = os.OpenFile(, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
		if os.IsExist() {
			if ++;  > 10 {
				randmu.Lock()
				rand = reseed()
				randmu.Unlock()
			}
			continue
		}
		break
	}
	return
}

var errPatternHasSeparator = errors.New("pattern contains path separator")

// prefixAndSuffix splits pattern by the last wildcard "*", if applicable,
// returning prefix as the part before "*" and suffix as the part after "*".
func prefixAndSuffix( string) (,  string,  error) {
	if strings.ContainsRune(, os.PathSeparator) {
		 = errPatternHasSeparator
		return
	}
	if  := strings.LastIndex(, "*");  != -1 {
		,  = [:], [+1:]
	} else {
		 = 
	}
	return
}

// TempDir creates a new temporary directory in the directory dir.
// The directory name is generated by taking pattern and applying a
// random string to the end. If pattern includes a "*", the random string
// replaces the last "*". TempDir returns the name of the new directory.
// If dir is the empty string, TempDir uses the
// default directory for temporary files (see os.TempDir).
// Multiple programs calling TempDir simultaneously
// will not choose the same directory. It is the caller's responsibility
// to remove the directory when no longer needed.
func (,  string) ( string,  error) {
	if  == "" {
		 = os.TempDir()
	}

	, ,  := prefixAndSuffix()
	if  != nil {
		return
	}

	 := 0
	for  := 0;  < 10000; ++ {
		 := filepath.Join(, +nextRandom()+)
		 = os.Mkdir(, 0700)
		if os.IsExist() {
			if ++;  > 10 {
				randmu.Lock()
				rand = reseed()
				randmu.Unlock()
			}
			continue
		}
		if os.IsNotExist() {
			if ,  := os.Stat(); os.IsNotExist() {
				return "", 
			}
		}
		if  == nil {
			 = 
		}
		break
	}
	return
}