mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-15 23:54:19 +00:00
fixes #24174
This commit is contained in:
@@ -70,6 +70,7 @@
|
||||
- Changed `std/osfiles.copyFile` to allow specifying `bufferSize` instead of a hard-coded one.
|
||||
- Changed `std/osfiles.copyFile` to use `POSIX_FADV_SEQUENTIAL` hints for kernel-level aggressive sequential read-aheads.
|
||||
- `std/htmlparser` has been moved to a nimble package, use `nimble` or `atlas` to install it.
|
||||
- Changed `std/os.copyDir` and `copyDirWithPermissions` to allow skipping special "file" objects like FIFOs, device files, etc on Unix by specifying a `skipSpecial` parameter.
|
||||
|
||||
[//]: # "Additions:"
|
||||
|
||||
|
||||
@@ -446,13 +446,17 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1",
|
||||
else:
|
||||
discard existsOrCreateDir(p)
|
||||
|
||||
proc copyDir*(source, dest: string) {.rtl, extern: "nos$1",
|
||||
proc copyDir*(source, dest: string, skipSpecial = false) {.rtl, extern: "nos$1",
|
||||
tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect], benign, noWeirdTarget.} =
|
||||
## Copies a directory from `source` to `dest`.
|
||||
##
|
||||
## On non-Windows OSes, symlinks are copied as symlinks. On Windows, symlinks
|
||||
## are skipped.
|
||||
##
|
||||
## If `skipSpecial` is true, then (besides all directories) only *regular*
|
||||
## files (**without** special "file" objects like FIFOs, device files,
|
||||
## etc) will be copied on Unix.
|
||||
##
|
||||
## If this fails, `OSError` is raised.
|
||||
##
|
||||
## On the Windows platform this proc will copy the attributes from
|
||||
@@ -472,16 +476,17 @@ proc copyDir*(source, dest: string) {.rtl, extern: "nos$1",
|
||||
## * `createDir proc`_
|
||||
## * `moveDir proc`_
|
||||
createDir(dest)
|
||||
for kind, path in walkDir(source):
|
||||
for kind, path in walkDir(source, skipSpecial = skipSpecial):
|
||||
var noSource = splitPath(path).tail
|
||||
if kind == pcDir:
|
||||
copyDir(path, dest / noSource)
|
||||
copyDir(path, dest / noSource, skipSpecial = skipSpecial)
|
||||
else:
|
||||
copyFile(path, dest / noSource, {cfSymlinkAsIs})
|
||||
|
||||
|
||||
proc copyDirWithPermissions*(source, dest: string,
|
||||
ignorePermissionErrors = true)
|
||||
ignorePermissionErrors = true,
|
||||
skipSpecial = false)
|
||||
{.rtl, extern: "nos$1", tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect],
|
||||
benign, noWeirdTarget.} =
|
||||
## Copies a directory from `source` to `dest` preserving file permissions.
|
||||
@@ -489,6 +494,10 @@ proc copyDirWithPermissions*(source, dest: string,
|
||||
## On non-Windows OSes, symlinks are copied as symlinks. On Windows, symlinks
|
||||
## are skipped.
|
||||
##
|
||||
## If `skipSpecial` is true, then (besides all directories) only *regular*
|
||||
## files (**without** special "file" objects like FIFOs, device files,
|
||||
## etc) will be copied on Unix.
|
||||
##
|
||||
## If this fails, `OSError` is raised. This is a wrapper proc around
|
||||
## `copyDir`_ and `copyFileWithPermissions`_ procs
|
||||
## on non-Windows platforms.
|
||||
@@ -518,10 +527,10 @@ proc copyDirWithPermissions*(source, dest: string,
|
||||
except:
|
||||
if not ignorePermissionErrors:
|
||||
raise
|
||||
for kind, path in walkDir(source):
|
||||
for kind, path in walkDir(source, skipSpecial = skipSpecial):
|
||||
var noSource = splitPath(path).tail
|
||||
if kind == pcDir:
|
||||
copyDirWithPermissions(path, dest / noSource, ignorePermissionErrors)
|
||||
copyDirWithPermissions(path, dest / noSource, ignorePermissionErrors, skipSpecial = skipSpecial)
|
||||
else:
|
||||
copyFileWithPermissions(path, dest / noSource, ignorePermissionErrors, {cfSymlinkAsIs})
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@ proc copyFile*(source, dest: string, options = {cfSymlinkFollow}; bufferSize = 1
|
||||
else:
|
||||
# generic version of copyFile which works for any platform:
|
||||
var d, s: File
|
||||
if not open(s, source):raiseOSError(osLastError(), source)
|
||||
if not open(s, source): raiseOSError(osLastError(), source)
|
||||
if not open(d, dest, fmWrite):
|
||||
close(s)
|
||||
raiseOSError(osLastError(), dest)
|
||||
|
||||
@@ -27,9 +27,8 @@ Raises
|
||||
"""
|
||||
# test os path creation, iteration, and deletion
|
||||
|
||||
import os, strutils, pathnorm
|
||||
from stdtest/specialpaths import buildDir
|
||||
import std/[syncio, assertions]
|
||||
import std/[syncio, assertions, osproc, os, strutils, pathnorm]
|
||||
|
||||
block fileOperations:
|
||||
let files = @["these.txt", "are.x", "testing.r", "files.q"]
|
||||
@@ -161,6 +160,18 @@ block fileOperations:
|
||||
# createDir should not fail if `dir` is empty
|
||||
createDir("")
|
||||
|
||||
|
||||
when defined(linux): # bug #24174
|
||||
createDir("a/b")
|
||||
open("a/file.txt", fmWrite).close
|
||||
|
||||
if not fileExists("a/fifoFile"):
|
||||
doAssert execCmd("mkfifo -m 600 a/fifoFile") == 0
|
||||
|
||||
copyDir("a/", "../dest/a/", skipSpecial = true)
|
||||
copyDirWithPermissions("a/", "../dest2/a/", skipSpecial = true)
|
||||
removeDir("a")
|
||||
|
||||
# Symlink handling in `copyFile`, `copyFileWithPermissions`, `copyFileToDir`,
|
||||
# `copyDir`, `copyDirWithPermissions`, `moveFile`, and `moveDir`.
|
||||
block:
|
||||
|
||||
Reference in New Issue
Block a user