Create creates a new file beneath the root. Creation is exclusive unless an existing regular file is safely opened and truncated for replacement. filePerm and dirPerm specify creation modes before applying the umask. Existing regular files and directories retain their permissions.
(name string, filePerm, dirPerm os.FileMode, replace bool)
| 165 | // filePerm and dirPerm specify creation modes before applying the umask. |
| 166 | // Existing regular files and directories retain their permissions. |
| 167 | func (r *Root) Create(name string, filePerm, dirPerm os.FileMode, replace bool) (*os.File, error) { |
| 168 | if hasTrailingPathSeparator(name) { |
| 169 | return nil, trailingPathSeparatorError(name) |
| 170 | } |
| 171 | local, err := r.localPath(name) |
| 172 | if err != nil { |
| 173 | return nil, err |
| 174 | } |
| 175 | if local == "." { |
| 176 | return nil, fmt.Errorf("cannot create root directory as a file") |
| 177 | } |
| 178 | parent, err := r.openDirectories(filepath.Dir(local), dirPerm) |
| 179 | if err != nil { |
| 180 | return nil, err |
| 181 | } |
| 182 | defer parent.Close() |
| 183 | base := filepath.Base(local) |
| 184 | |
| 185 | if replace { |
| 186 | info, err := r.lstat(parent, base) |
| 187 | if err == nil { |
| 188 | redirect, err := isPathRedirect(r, parent, base, info) |
| 189 | if err != nil { |
| 190 | return nil, err |
| 191 | } |
| 192 | if redirect { |
| 193 | targetIsDir, err := r.redirectTargetIsDir(parent, base) |
| 194 | if err != nil { |
| 195 | return nil, err |
| 196 | } |
| 197 | if targetIsDir { |
| 198 | return nil, directoryWriteError(name) |
| 199 | } |
| 200 | if err := parent.Remove(base); err != nil { |
| 201 | return nil, err |
| 202 | } |
| 203 | } else { |
| 204 | if info.IsDir() { |
| 205 | return nil, directoryWriteError(name) |
| 206 | } |
| 207 | if info.Mode()&os.ModeNamedPipe != 0 { |
| 208 | return nil, namedPipeWriteError(name) |
| 209 | } |
| 210 | file, err := r.openVerifiedEntry(parent, base, local) |
| 211 | if err != nil { |
| 212 | return nil, err |
| 213 | } |
| 214 | if info.Mode().IsRegular() || info.Mode()&os.ModeIrregular != 0 { |
| 215 | if err := file.Truncate(0); err != nil { |
| 216 | _ = file.Close() |
| 217 | return nil, err |
| 218 | } |
| 219 | if _, err := file.Seek(0, io.SeekStart); err != nil { |
| 220 | _ = file.Close() |
| 221 | return nil, err |
| 222 | } |
| 223 | } |
| 224 | return file, nil |
no test coverage detected