MCPcopy Create free account
hub / github.com/RT-Thread/env-windows / _fastcopy_sendfile

Function _fastcopy_sendfile

tools/python-3.11.9-amd64/Lib/shutil.py:106–168  ·  view source on GitHub ↗

Copy data from one regular mmap-like fd to another by using high-performance sendfile(2) syscall. This should work on Linux >= 2.6.33 only.

(fsrc, fdst)

Source from the content-addressed store, hash-verified

104 raise err from None
105
106def _fastcopy_sendfile(fsrc, fdst):
107 """Copy data from one regular mmap-like fd to another by using
108 high-performance sendfile(2) syscall.
109 This should work on Linux >= 2.6.33 only.
110 """
111 # Note: copyfileobj() is left alone in order to not introduce any
112 # unexpected breakage. Possible risks by using zero-copy calls
113 # in copyfileobj() are:
114 # - fdst cannot be open in "a"(ppend) mode
115 # - fsrc and fdst may be open in "t"(ext) mode
116 # - fsrc may be a BufferedReader (which hides unread data in a buffer),
117 # GzipFile (which decompresses data), HTTPResponse (which decodes
118 # chunks).
119 # - possibly others (e.g. encrypted fs/partition?)
120 global _USE_CP_SENDFILE
121 try:
122 infd = fsrc.fileno()
123 outfd = fdst.fileno()
124 except Exception as err:
125 raise _GiveupOnFastCopy(err) # not a regular file
126
127 # Hopefully the whole file will be copied in a single call.
128 # sendfile() is called in a loop 'till EOF is reached (0 return)
129 # so a bufsize smaller or bigger than the actual file size
130 # should not make any difference, also in case the file content
131 # changes while being copied.
132 try:
133 blocksize = max(os.fstat(infd).st_size, 2 ** 23) # min 8MiB
134 except OSError:
135 blocksize = 2 ** 27 # 128MiB
136 # On 32-bit architectures truncate to 1GiB to avoid OverflowError,
137 # see bpo-38319.
138 if sys.maxsize < 2 ** 32:
139 blocksize = min(blocksize, 2 ** 30)
140
141 offset = 0
142 while True:
143 try:
144 sent = os.sendfile(outfd, infd, offset, blocksize)
145 except OSError as err:
146 # ...in oder to have a more informative exception.
147 err.filename = fsrc.name
148 err.filename2 = fdst.name
149
150 if err.errno == errno.ENOTSOCK:
151 # sendfile() on this platform (probably Linux < 2.6.33)
152 # does not support copies between regular files (only
153 # sockets).
154 _USE_CP_SENDFILE = False
155 raise _GiveupOnFastCopy(err)
156
157 if err.errno == errno.ENOSPC: # filesystem is full
158 raise err from None
159
160 # Give up on first call and if no data was copied.
161 if offset == 0 and os.lseek(outfd, 0, os.SEEK_CUR) == 0:
162 raise _GiveupOnFastCopy(err)
163

Callers 1

copyfileFunction · 0.85

Calls 5

_GiveupOnFastCopyClass · 0.85
maxFunction · 0.85
minFunction · 0.85
filenoMethod · 0.45
sendfileMethod · 0.45

Tested by

no test coverage detected