Skip to content

Commit

Permalink
Use dual stream for os.open with O_APPEND
Browse files Browse the repository at this point in the history
  • Loading branch information
BCSharp committed Dec 12, 2024
1 parent f971ff6 commit c1edb43
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions Src/IronPython.Modules/nt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -877,8 +877,9 @@ public static object open(CodeContext/*!*/ context, [NotNone] string path, int f
FileMode fileMode = FileModeFromFlags(flags);
FileAccess access = FileAccessFromFlags(flags);
FileOptions options = FileOptionsFromFlags(flags);
Stream s;
FileStream? fs;
Stream s; // the stream opened to acces the file
FileStream? fs; // downcast of s if s is FileStream (this is always the case on POSIX)
Stream? rs = null; // secondary read stream if needed, otherwise same as s
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && IsNulFile(path)) {
fs = null;
s = Stream.Null;
Expand All @@ -889,15 +890,20 @@ public static object open(CodeContext/*!*/ context, [NotNone] string path, int f
fs.Close();
s = fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, DefaultBufferSize, options);
} else if (access == FileAccess.ReadWrite && fileMode == FileMode.Append) {
// .NET doesn't allow Append w/ access != Write, so open the file w/ Write
// and a secondary stream w/ Read, then seek to the end.
s = fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite, DefaultBufferSize, options);
rs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, DefaultBufferSize, options);
rs.Seek(0L, SeekOrigin.End);
} else {
s = fs = new FileStream(path, fileMode, access, FileShare.ReadWrite, DefaultBufferSize, options);
}
rs ??= s;

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
return context.LanguageContext.FileManager.Add(new(s));
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) {
return context.LanguageContext.FileManager.Add(fs!.SafeFileHandle.DangerousGetHandle().ToInt32(), new(rs, s));
} else {
return context.LanguageContext.FileManager.Add((int)fs!.SafeFileHandle.DangerousGetHandle(), new(s));
return context.LanguageContext.FileManager.Add(new(rs, s));
}
} catch (Exception e) {
throw ToPythonException(e, path);
Expand Down

0 comments on commit c1edb43

Please sign in to comment.