func Create(filename string, options ...Option) error {
	cfg := defaultConfig()
	for _, o := range options {
		if err := o.apply(&cfg); err != nil {
			return &werror{"options", err}
		}
	}

	dir := path.Dir(filename)

	var d *os.File
	var err error
	if cfg.fsync {
		// on Linux the directory fd can be opened as read-only for fsync
		d, err = os.OpenFile(dir, unix.O_DIRECTORY|os.O_RDONLY, 0)
		if err != nil {
			return &werror{"opening directory", err}
		}
		// TODO: check error
		defer d.Close()
	}

	f, err := os.OpenFile(dir, unix.O_TMPFILE|os.O_APPEND|os.O_WRONLY, 0o666)
	if err != nil {
		return &werror{"opening file", err}
	}
	// TODO: check error
	defer f.Close()

	if cfg.uid != defaultConfig().uid || cfg.gid != defaultConfig().gid {
		err := unix.Fchown(int(f.Fd()), cfg.uid, cfg.gid)
		if err != nil {
			return &werror{"setting ownership", err}
		}
	}

	if cfg.perm != defaultConfig().perm {
		err := unix.Fchmod(int(f.Fd()), cfg.perm)
		if err != nil {
			return &werror{"setting permissions", err}
		}
	}

	prealloc := cfg.prealloc
	if prealloc == defaultConfig().prealloc && cfg.contents != nil {
		if guess := guessContentSize(cfg.contents); guess > 0 {
			prealloc = guess
		}
	}
	if prealloc > 0 {
		err := unix.Fallocate(int(f.Fd()), unix.FALLOC_FL_KEEP_SIZE, 0, prealloc)
		if err != nil {
			prealloc = 0
			if cfg.prealloc > 0 {
				return &werror{"preallocating file", err}
			}
		}
	}

	var written int64
	if cfg.contents != nil {
		written, err = io.Copy(f, cfg.contents)
		if err != nil {
			return &werror{"populating file", err}
		}
	}

	if written < prealloc && cfg.prealloc == 0 {
		// The user did not request prealloc, and our guess was too big:
		// trim the excess allocation so that we don't waste space in case
		// the fs honoured our request.
		// TODO: should we fail in this case?
		_ = unix.Fallocate(int(f.Fd()), unix.FALLOC_FL_PUNCH_HOLE|unix.FALLOC_FL_KEEP_SIZE, written, prealloc-written)
	}

	for _, xattr := range cfg.xattrs {
		err := unix.Fsetxattr(int(f.Fd()), xattr.name, xattr.value, 0)
		if err != nil {
			return &werror{"setting xattr", err}
		}
	}

	if cfg.mtime != defaultConfig().mtime || cfg.atime != defaultConfig().atime {
		err := futimens(int(f.Fd()), &[2]unix.Timespec{cfg.atime, cfg.mtime})
		if err != nil {
			return &werror{"setting access/modification time", err}
		}
	}

	if cfg.dontNeed {
		// TODO: this should be done incrementally in the io.Copy loop
		_ = unix.Fadvise(int(f.Fd()), 0, written, unix.FADV_DONTNEED)
	}

	if cfg.fsync {
		err := f.Sync()
		if err != nil {
			return &werror{"fsync file", err}
		}
	}

	const AT_EMPTY_PATH = 0x1000
	err = unix.Linkat(int(f.Fd()), "", unix.AT_FDCWD, filename, AT_EMPTY_PATH)
	if err != nil {
		procPath := "/proc/self/fd/" + strconv.Itoa(int(f.Fd()))
		err2 := unix.Linkat(unix.AT_FDCWD, procPath, unix.AT_FDCWD, filename, unix.AT_SYMLINK_FOLLOW)
		if err2 != nil {
			return &werror{"linking file", err2}
		}
	}

	if cfg.fsync {
		err := d.Sync()
		if err != nil {
			return &werror{"fsync directory", err}
		}
	}

	return nil
}
// Create creates the specified file with the provided options.
// The file is created atomically in a fully-formed state using
// O_TMPFILE/linkat.
// Create fails if the file already exists.
Create creates the specified file with the provided options.
The file is created atomically in a fully-formed state using
O_TMPFILE/linkat.
Create fails if the file already exists.
// Create creates the specified file with the provided options . // The file is created atomically in a fully - formed state using // O_TMPFILE / linkat . // Create fails if the file already exists .
func Create(filename string, options ...Option) error {
	cfg := defaultConfig()
	for _, o := range options {
		if err := o.apply(&cfg); err != nil {
			return &werror{"options", err}
		}
	}
	dir := path.Dir(filename)
	var d *os.File
	var err error
	if cfg.fsync {
		d, err = os.OpenFile(dir, unix.O_DIRECTORY|os.O_RDONLY, 0)
		if err != nil {
			return &werror{"opening directory", err}
		}
		defer d.Close()
	}
	f, err := os.OpenFile(dir, unix.O_TMPFILE|os.O_APPEND|os.O_WRONLY, 0o666)
	if err != nil {
		return &werror{"opening file", err}
	}
	defer f.Close()
	if cfg.uid != defaultConfig().uid || cfg.gid != defaultConfig().gid {
		err := unix.Fchown(int(f.Fd()), cfg.uid, cfg.gid)
		if err != nil {
			return &werror{"setting ownership", err}
		}
	}
	if cfg.perm != defaultConfig().perm {
		err := unix.Fchmod(int(f.Fd()), cfg.perm)
		if err != nil {
			return &werror{"setting permissions", err}
		}
	}
	prealloc := cfg.prealloc
	if prealloc == defaultConfig().prealloc && cfg.contents != nil {
		if guess := guessContentSize(cfg.contents); guess > 0 {
			prealloc = guess
		}
	}
	if prealloc > 0 {
		err := unix.Fallocate(int(f.Fd()), unix.FALLOC_FL_KEEP_SIZE, 0, prealloc)
		if err != nil {
			prealloc = 0
			if cfg.prealloc > 0 {
				return &werror{"preallocating file", err}
			}
		}
	}
	var written int64
	if cfg.contents != nil {
		written, err = io.Copy(f, cfg.contents)
		if err != nil {
			return &werror{"populating file", err}
		}
	}
	if written < prealloc && cfg.prealloc == 0 {
		_ = unix.Fallocate(int(f.Fd()), unix.FALLOC_FL_PUNCH_HOLE|unix.FALLOC_FL_KEEP_SIZE, written, prealloc-written)
	}
	for _, xattr := range cfg.xattrs {
		err := unix.Fsetxattr(int(f.Fd()), xattr.name, xattr.value, 0)
		if err != nil {
			return &werror{"setting xattr", err}
		}
	}
	if cfg.mtime != defaultConfig().mtime || cfg.atime != defaultConfig().atime {
		err := futimens(int(f.Fd()), &[2]unix.Timespec{cfg.atime, cfg.mtime})
		if err != nil {
			return &werror{"setting access/modification time", err}
		}
	}
	if cfg.dontNeed {
		_ = unix.Fadvise(int(f.Fd()), 0, written, unix.FADV_DONTNEED)
	}
	if cfg.fsync {
		err := f.Sync()
		if err != nil {
			return &werror{"fsync file", err}
		}
	}
	const AT_EMPTY_PATH = 0x1000
	err = unix.Linkat(int(f.Fd()), "", unix.AT_FDCWD, filename, AT_EMPTY_PATH)
	if err != nil {
		procPath := "/proc/self/fd/" + strconv.Itoa(int(f.Fd()))
		err2 := unix.Linkat(unix.AT_FDCWD, procPath, unix.AT_FDCWD, filename, unix.AT_SYMLINK_FOLLOW)
		if err2 != nil {
			return &werror{"linking file", err2}
		}
	}
	if cfg.fsync {
		err := d.Sync()
		if err != nil {
			return &werror{"fsync directory", err}
		}
	}
	return nil
}
func Create ( filename string , options ... Option ) error { cfg := defaultConfig ( ) for _ , o := range options { if err := o . apply ( & cfg ) ; err != nil { return & werror { " " , err } } } dir := path . Dir ( filename ) var d * os . File var err error if cfg . fsync { d , err = os . OpenFile ( dir , unix . O_DIRECTORY | os . O_RDONLY , 0 ) if err != nil { return & werror { " " , err } } defer d . Close ( ) } f , err := os . OpenFile ( dir , unix . O_TMPFILE | os . O_APPEND | os . O_WRONLY , 0o666 ) if err != nil { return & werror { " " , err } } defer f . Close ( ) if cfg . uid != defaultConfig ( ) . uid || cfg . gid != defaultConfig ( ) . gid { err := unix . Fchown ( int ( f . Fd ( ) ) , cfg . uid , cfg . gid ) if err != nil { return & werror { " " , err } } } if cfg . perm != defaultConfig ( ) . perm { err := unix . Fchmod ( int ( f . Fd ( ) ) , cfg . perm ) if err != nil { return & werror { " " , err } } } prealloc := cfg . prealloc if prealloc == defaultConfig ( ) . prealloc && cfg . contents != nil { if guess := guessContentSize ( cfg . contents ) ; guess > 0 { prealloc = guess } } if prealloc > 0 { err := unix . Fallocate ( int ( f . Fd ( ) ) , unix . FALLOC_FL_KEEP_SIZE , 0 , prealloc ) if err != nil { prealloc = 0 if cfg . prealloc > 0 { return & werror { " " , err } } } } var written int64 if cfg . contents != nil { written , err = io . Copy ( f , cfg . contents ) if err != nil { return & werror { " " , err } } } if written < prealloc && cfg . prealloc == 0 { _ = unix . Fallocate ( int ( f . Fd ( ) ) , unix . FALLOC_FL_PUNCH_HOLE | unix . FALLOC_FL_KEEP_SIZE , written , prealloc - written ) } for _ , xattr := range cfg . xattrs { err := unix . Fsetxattr ( int ( f . Fd ( ) ) , xattr . name , xattr . value , 0 ) if err != nil { return & werror { " " , err } } } if cfg . mtime != defaultConfig ( ) . mtime || cfg . atime != defaultConfig ( ) . atime { err := futimens ( int ( f . Fd ( ) ) , & [ 2 ] unix . Timespec { cfg . atime , cfg . mtime } ) if err != nil { return & werror { " " , err } } } if cfg . dontNeed { _ = unix . Fadvise ( int ( f . Fd ( ) ) , 0 , written , unix . FADV_DONTNEED ) } if cfg . fsync { err := f . Sync ( ) if err != nil { return & werror { " " , err } } } const AT_EMPTY_PATH = 0x1000 err = unix . Linkat ( int ( f . Fd ( ) ) , " " , unix . AT_FDCWD , filename , AT_EMPTY_PATH ) if err != nil { procPath := " " + strconv . Itoa ( int ( f . Fd ( ) ) ) err2 := unix . Linkat ( unix . AT_FDCWD , procPath , unix . AT_FDCWD , filename , unix . AT_SYMLINK_FOLLOW ) if err2 != nil { return & werror { " " , err2 } } } if cfg . fsync { err := d . Sync ( ) if err != nil { return & werror { " " , err } } } return nil }
Create creates the specified file with the provided options.
Create creates the specified file with the provided options .
// on Linux the directory fd can be opened as read-only for fsync // TODO: check error // TODO: check error // The user did not request prealloc, and our guess was too big: // trim the excess allocation so that we don't waste space in case // the fs honoured our request. // TODO: should we fail in this case? // TODO: this should be done incrementally in the io.Copy loop