Skip to content

Commit 7ae5cbc

Browse files
authored
Add files via upload
1 parent dc03dd4 commit 7ae5cbc

1 file changed

Lines changed: 24 additions & 5 deletions

File tree

pyarchivefile.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,7 +2066,7 @@ def MkTempFile(data=None,
20662066
Return a file-like handle with consistent behavior on Py2.7 and Py3.x.
20672067

20682068
Storage:
2069-
- inmem=True -> BytesIO (bytes) or StringIO (text)
2069+
- inmem=True -> BytesIO (bytes) or StringIO (text), or memfd for bytes if available
20702070
- inmem=False, use_spool=True -> SpooledTemporaryFile (binary), optionally TextIOWrapper for text
20712071
- inmem=False, use_spool=False -> NamedTemporaryFile (binary), optionally TextIOWrapper for text
20722072

@@ -2079,6 +2079,8 @@ def MkTempFile(data=None,
20792079
- On Windows, NamedTemporaryFile(delete=True) keeps the file open and cannot be reopened by other processes.
20802080
Use delete=False if you need to pass the path elsewhere.
20812081
- For text: in-memory StringIO ignores 'newline' (as usual).
2082+
- When available, memfd is used only for inmem=True and isbytes=True, providing an anonymous in-memory
2083+
file descriptor (Linux-only). Text in-memory still uses StringIO to preserve newline semantics.
20822084
"""
20832085

20842086
# -- sanitize simple params (avoid None surprises) --
@@ -2112,20 +2114,36 @@ def MkTempFile(data=None,
21122114

21132115
# -------- In-memory --------
21142116
if inmem:
2117+
# Use memfd only for bytes, and only where available (Linux, Python 3.8+)
2118+
if isbytes and hasattr(os, "memfd_create"):
2119+
flags = 0
2120+
# Close-on-exec is almost always what you want for temps
2121+
if hasattr(os, "MFD_CLOEXEC"):
2122+
flags |= os.MFD_CLOEXEC
2123+
2124+
fd = os.memfd_create("MkTempFile", flags)
2125+
# Binary read/write file-like object backed by RAM
2126+
f = os.fdopen(fd, "w+b")
2127+
2128+
if init is not None:
2129+
f.write(init)
2130+
f.seek(0)
2131+
return f
2132+
2133+
# Fallback: pure Python in-memory objects
21152134
if isbytes:
21162135
f = io.BytesIO(init if init is not None else b"")
21172136
else:
21182137
# newline not enforced for StringIO; matches stdlib semantics
21192138
f = io.StringIO(init if init is not None else "")
2120-
# already positioned at 0 with provided init; ensure rewind for symmetry
2139+
21212140
f.seek(0)
21222141
return f
21232142

21242143
# Helper: wrap a binary file into a text file with encoding/newline
21252144
def _wrap_text(handle):
21262145
# For both Py2 & Py3, TextIOWrapper gives consistent newline/encoding behavior
21272146
tw = io.TextIOWrapper(handle, encoding=encoding, newline=newline)
2128-
# Position at start; if we wrote initial data below, we will rewind after writing
21292147
return tw
21302148

21312149
# -------- Spooled (RAM then disk) --------
@@ -2134,6 +2152,7 @@ def _wrap_text(handle):
21342152
bin_mode = "w+b" # read/write, binary
21352153
b = tempfile.SpooledTemporaryFile(max_size=spool_max, mode=bin_mode, dir=spool_dir)
21362154
f = b if isbytes else _wrap_text(b)
2155+
21372156
if init is not None:
21382157
f.write(init)
21392158
f.seek(0)
@@ -5946,14 +5965,14 @@ def AppendFilesWithContent(infiles, fp, dirlistfromtxt=False, extradata=[], json
59465965
if(hasattr(fstatinfo, "st_flags")):
59475966
fflags = format(int(fstatinfo.st_flags), 'x').lower()
59485967
ftype = 0
5949-
if(hasattr(os.path, "isjunction") and os.path.isjunction(fname)):
5968+
if(not followlink and hasattr(os.path, "isjunction") and os.path.isjunction(fname)):
59505969
ftype = 13
59515970
elif(stat.S_ISREG(fpremode)):
59525971
if(hasattr(fstatinfo, "st_blocks") and fstatinfo.st_size > 0 and fstatinfo.st_blocks * 512 < fstatinfo.st_size):
59535972
ftype = 12
59545973
else:
59555974
ftype = 0
5956-
elif(stat.S_ISLNK(fpremode)):
5975+
elif(not followlink and stat.S_ISLNK(fpremode)):
59575976
ftype = 2
59585977
elif(stat.S_ISCHR(fpremode)):
59595978
ftype = 3

0 commit comments

Comments
 (0)