MCPcopy Index your code
hub / github.com/python/cpython / _fastcopy_sendfile

Function _fastcopy_sendfile

Lib/shutil.py:178–227  ·  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, Android and Solaris.

(fsrc, fdst)

Source from the content-addressed store, hash-verified

176 offset += n_copied
177
178def _fastcopy_sendfile(fsrc, fdst):
179 """Copy data from one regular mmap-like fd to another by using
180 high-performance sendfile(2) syscall.
181 This should work on Linux >= 2.6.33, Android and Solaris.
182 """
183 # Note: copyfileobj() is left alone in order to not introduce any
184 # unexpected breakage. Possible risks by using zero-copy calls
185 # in copyfileobj() are:
186 # - fdst cannot be open in "a"(ppend) mode
187 # - fsrc and fdst may be open in "t"(ext) mode
188 # - fsrc may be a BufferedReader (which hides unread data in a buffer),
189 # GzipFile (which decompresses data), HTTPResponse (which decodes
190 # chunks).
191 # - possibly others (e.g. encrypted fs/partition?)
192 global _USE_CP_SENDFILE
193 try:
194 infd = fsrc.fileno()
195 outfd = fdst.fileno()
196 except Exception as err:
197 raise _GiveupOnFastCopy(err) # not a regular file
198
199 blocksize = _determine_linux_fastcopy_blocksize(infd)
200 offset = 0
201 while True:
202 try:
203 sent = os.sendfile(outfd, infd, offset, blocksize)
204 except OSError as err:
205 # ...in order to have a more informative exception.
206 err.filename = fsrc.name
207 err.filename2 = fdst.name
208
209 if err.errno == errno.ENOTSOCK:
210 # sendfile() on this platform (probably Linux < 2.6.33)
211 # does not support copies between regular files (only
212 # sockets).
213 _USE_CP_SENDFILE = False
214 raise _GiveupOnFastCopy(err)
215
216 if err.errno == errno.ENOSPC: # filesystem is full
217 raise err from None
218
219 # Give up on first call and if no data was copied.
220 if offset == 0 and os.lseek(outfd, 0, os.SEEK_CUR) == 0:
221 raise _GiveupOnFastCopy(err)
222
223 raise err
224 else:
225 if sent == 0:
226 break # EOF
227 offset += sent
228
229def _copyfileobj_readinto(fsrc, fdst, length=COPY_BUFSIZE):
230 """readinto()/memoryview() based variant of copyfileobj().

Callers 1

copyfileFunction · 0.85

Calls 4

_GiveupOnFastCopyClass · 0.85
filenoMethod · 0.45
sendfileMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…