Skip to content

Commit 8a6e80a

Browse files
Add files via upload
1 parent f451057 commit 8a6e80a

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

pyfoxfile.py

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

20762076
Storage:
2077-
- inmem=True -> BytesIO (bytes) or StringIO (text)
2077+
- inmem=True -> BytesIO (bytes) or StringIO (text), or memfd for bytes if available
20782078
- inmem=False, use_spool=True -> SpooledTemporaryFile (binary), optionally TextIOWrapper for text
20792079
- inmem=False, use_spool=False -> NamedTemporaryFile (binary), optionally TextIOWrapper for text
20802080

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

20922094
# -- sanitize simple params (avoid None surprises) --
@@ -2120,20 +2122,36 @@ def MkTempFile(data=None,
21202122

21212123
# -------- In-memory --------
21222124
if inmem:
2125+
# Use memfd only for bytes, and only where available (Linux, Python 3.8+)
2126+
if isbytes and hasattr(os, "memfd_create"):
2127+
flags = 0
2128+
# Close-on-exec is almost always what you want for temps
2129+
if hasattr(os, "MFD_CLOEXEC"):
2130+
flags |= os.MFD_CLOEXEC
2131+
2132+
fd = os.memfd_create("MkTempFile", flags)
2133+
# Binary read/write file-like object backed by RAM
2134+
f = os.fdopen(fd, "w+b")
2135+
2136+
if init is not None:
2137+
f.write(init)
2138+
f.seek(0)
2139+
return f
2140+
2141+
# Fallback: pure Python in-memory objects
21232142
if isbytes:
21242143
f = io.BytesIO(init if init is not None else b"")
21252144
else:
21262145
# newline not enforced for StringIO; matches stdlib semantics
21272146
f = io.StringIO(init if init is not None else "")
2128-
# already positioned at 0 with provided init; ensure rewind for symmetry
2147+
21292148
f.seek(0)
21302149
return f
21312150

21322151
# Helper: wrap a binary file into a text file with encoding/newline
21332152
def _wrap_text(handle):
21342153
# For both Py2 & Py3, TextIOWrapper gives consistent newline/encoding behavior
21352154
tw = io.TextIOWrapper(handle, encoding=encoding, newline=newline)
2136-
# Position at start; if we wrote initial data below, we will rewind after writing
21372155
return tw
21382156

21392157
# -------- Spooled (RAM then disk) --------
@@ -2142,6 +2160,7 @@ def _wrap_text(handle):
21422160
bin_mode = "w+b" # read/write, binary
21432161
b = tempfile.SpooledTemporaryFile(max_size=spool_max, mode=bin_mode, dir=spool_dir)
21442162
f = b if isbytes else _wrap_text(b)
2163+
21452164
if init is not None:
21462165
f.write(init)
21472166
f.seek(0)
@@ -2158,6 +2177,7 @@ def _wrap_text(handle):
21582177
return f
21592178

21602179

2180+
21612181
def RemoveWindowsPath(dpath):
21622182
"""
21632183
Normalize a path by converting backslashes to forward slashes
@@ -5954,14 +5974,14 @@ def AppendFilesWithContent(infiles, fp, dirlistfromtxt=False, extradata=[], json
59545974
if(hasattr(fstatinfo, "st_flags")):
59555975
fflags = format(int(fstatinfo.st_flags), 'x').lower()
59565976
ftype = 0
5957-
if(hasattr(os.path, "isjunction") and os.path.isjunction(fname)):
5977+
if(not followlink and hasattr(os.path, "isjunction") and os.path.isjunction(fname)):
59585978
ftype = 13
59595979
elif(stat.S_ISREG(fpremode)):
59605980
if(hasattr(fstatinfo, "st_blocks") and fstatinfo.st_size > 0 and fstatinfo.st_blocks * 512 < fstatinfo.st_size):
59615981
ftype = 12
59625982
else:
59635983
ftype = 0
5964-
elif(stat.S_ISLNK(fpremode)):
5984+
elif(not followlink and stat.S_ISLNK(fpremode)):
59655985
ftype = 2
59665986
elif(stat.S_ISCHR(fpremode)):
59675987
ftype = 3

0 commit comments

Comments
 (0)