KiCad PCB EDA Suite
Loading...
Searching...
No Matches
KIPLATFORM::IO Namespace Reference

Classes

class  MAPPED_FILE
 RAII wrapper for memory-mapped file I/O. More...
 
struct  TARGET_ATTRS
 Opaque snapshot of filesystem attributes that MakeWriteable may alter and that the atomic rename sequence does not preserve by itself. More...
 

Functions

FILE * SeqFOpen (const wxString &aPath, const wxString &mode)
 Opens the file like fopen but sets flags (if available) for sequential read hinting.
 
bool DuplicatePermissions (const wxString &aSrc, const wxString &aDest)
 Duplicates the file security data from one file to another ensuring that they are the same between both.
 
bool MakeWriteable (const wxString &aFilePath)
 Ensures that a file has write permissions.
 
bool IsFileHidden (const wxString &aFileName)
 Helper function to determine the status of the 'Hidden' file attribute.
 
void LongPathAdjustment (wxFileName &aFilename)
 Adjusts a filename to be a long path compatible.
 
long long TimestampDir (const wxString &aDirPath, const wxString &aFilespec)
 Computes a hash of modification times and sizes for files matching a pattern.
 
bool FlushToDisk (FILE *aFp)
 Flushes user-space buffers for aFp and forces the kernel/filesystem to commit the file's data blocks to stable storage.
 
bool FlushDirectory (const wxString &aDirPath)
 Forces a directory entry's metadata to stable storage.
 
bool AtomicRename (const wxString &aSrc, const wxString &aDst, wxString *aError=nullptr)
 Atomically replaces aDst with aSrc.
 
wxString MakeSiblingTempPath (const wxString &aTargetPath)
 Returns a unique sibling path of aTargetPath suitable as an atomic-save temp file.
 
FILE * OpenUniqueSiblingTempFile (const wxString &aTargetPath, const wxString &aMode, wxString *aTempPathOut, wxString *aError=nullptr)
 Opens a fresh sibling temp file next to aTargetPath with exclusive-create semantics (POSIX O_CREAT|O_EXCL, Windows CREATE_NEW).
 
wxString ResolveSymlinkTarget (const wxString &aPath)
 If aPath is a symlink on POSIX, returns the canonical path of its referent so atomic-save operations replace the underlying file rather than the link itself.
 
TARGET_ATTRS CaptureTargetAttributes (const wxString &aPath)
 Captures attributes of an existing aPath that must survive an atomic rename.
 
bool ApplyTargetAttributes (const wxString &aPath, const TARGET_ATTRS &aAttrs)
 Re-applies attributes previously captured by CaptureTargetAttributes.
 
bool CommitTempFile (const wxString &aTempPath, const wxString &aTargetPath, wxString *aError=nullptr)
 Completes an atomic save.
 
bool AtomicWriteFile (const wxString &aTargetPath, const void *aData, size_t aSize, wxString *aError=nullptr)
 Writes aData to aTargetPath via a sibling temp file, fsyncs the data and directory, and atomically replaces the target.
 

Variables

static constexpr size_t CLOUD_SYNC_BUFFER_SIZE = 512 * 1024
 Buffer size for file I/O operations on cloud-synced folders.
 

Function Documentation

◆ ApplyTargetAttributes()

bool KIPLATFORM::IO::ApplyTargetAttributes ( const wxString & aPath,
const TARGET_ATTRS & aAttrs )

Re-applies attributes previously captured by CaptureTargetAttributes.

Safe to call on either the happy path (restores HIDDEN/READONLY bits to the new file produced by the rename, which DuplicatePermissions would not have carried) or the failure path (rolls back a MakeWriteable mutation on the original target).

Returns
true if the attributes were re-applied or the snapshot is a no-op; false only if the OS rejected the attribute change.

Definition at line 103 of file unix/io.cpp.

Referenced by CommitTempFile().

◆ AtomicRename()

bool KIPLATFORM::IO::AtomicRename ( const wxString & aSrc,
const wxString & aDst,
wxString * aError = nullptr )

Atomically replaces aDst with aSrc.

Both paths must live on the same filesystem; cross-device renames are not atomic.

POSIX uses rename(2), which is atomic w.r.t. concurrent opens. Windows uses MoveFileExW with MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH and falls back to ReplaceFileW for cases (antivirus, indexer, share-locked) that reject MoveFileEx. A brief retry loop absorbs transient ERROR_SHARING_VIOLATION and ERROR_ACCESS_DENIED on Windows.

On success aSrc no longer exists; on failure it is left in place so the caller can clean up.

Parameters
aSrcsource path, typically a sibling temp file of aDst.
aDstdestination path.
aErroroptional out-parameter populated with a human-readable message.
Returns
true if the rename committed atomically.

Definition at line 162 of file common/io.cpp.

Referenced by CommitTempFile().

◆ AtomicWriteFile()

bool KIPLATFORM::IO::AtomicWriteFile ( const wxString & aTargetPath,
const void * aData,
size_t aSize,
wxString * aError = nullptr )

Writes aData to aTargetPath via a sibling temp file, fsyncs the data and directory, and atomically replaces the target.

A crash or power loss at any point leaves aTargetPath either byte-identical to its prior contents or byte-identical to aData – never truncated or partially written.

If aTargetPath already exists its permissions are duplicated onto the replacement, and any read-only/hidden attributes are cleared first so cloud sync services don't block the rename.

Parameters
aTargetPathfinal destination path.
aDatapointer to bytes to write.
aSizenumber of bytes in aData.
aErroroptional out-parameter populated with a human-readable message on failure.
Returns
true on durable commit of aData to aTargetPath.

Definition at line 264 of file common/io.cpp.

References CommitTempFile(), FlushToDisk(), OpenUniqueSiblingTempFile(), and ResolveSymlinkTarget().

Referenced by BOOST_AUTO_TEST_CASE(), BOOST_AUTO_TEST_CASE(), BOOST_AUTO_TEST_CASE(), BOOST_AUTO_TEST_CASE(), BOOST_AUTO_TEST_CASE(), DESIGN_BLOCK_IO::DesignBlockSave(), LIBRARY_TABLE::Save(), DRC_RULE_SAVER::SaveFile(), DRC_RULE_EDITOR_UTILS::SaveRules(), JSON_SETTINGS::SaveToFile(), and PANEL_SETUP_RULES::TransferDataFromWindow().

◆ CaptureTargetAttributes()

KIPLATFORM::IO::TARGET_ATTRS KIPLATFORM::IO::CaptureTargetAttributes ( const wxString & aPath)

Captures attributes of an existing aPath that must survive an atomic rename.

Windows reads GetFileAttributesW and stores READONLY/HIDDEN bits. POSIX returns an uncaptured snapshot. Call before any mutation of the target (MakeWriteable).

Definition at line 94 of file unix/io.cpp.

Referenced by CommitTempFile().

◆ CommitTempFile()

bool KIPLATFORM::IO::CommitTempFile ( const wxString & aTempPath,
const wxString & aTargetPath,
wxString * aError = nullptr )

Completes an atomic save.

Assumes aTempPath has been fully written, fsynced, and closed. Clears any read-only/hidden attributes on an existing aTargetPath, duplicates its permissions onto the temp file, atomically renames aTempPath onto aTargetPath, and fsyncs the containing directory so the rename itself is durable across power loss.

On failure aTempPath is left in place for the caller to clean up.

Parameters
aTempPathalready-closed source temp file.
aTargetPathfinal destination path.
aErroroptional human-readable failure message.
Returns
true on durable commit.

Definition at line 176 of file common/io.cpp.

References ApplyTargetAttributes(), AtomicRename(), CaptureTargetAttributes(), DuplicatePermissions(), FlushDirectory(), and MakeWriteable().

Referenced by AtomicWriteFile().

◆ DuplicatePermissions()

bool KIPLATFORM::IO::DuplicatePermissions ( const wxString & aSrc,
const wxString & aDest )

Duplicates the file security data from one file to another ensuring that they are the same between both.

This assumes that the user has permission to set #aDest

Returns
true if the process was successful

Definition at line 55 of file unix/io.cpp.

Referenced by CommitTempFile(), PL_EDITOR_FRAME::SaveDrawingSheetFile(), STEP_PCB_MODEL::WriteGLTF(), STEP_PCB_MODEL::WritePDF(), STEP_PCB_MODEL::WritePLY(), STEP_PCB_MODEL::WriteSTEP(), STEP_PCB_MODEL::WriteSTL(), and STEP_PCB_MODEL::WriteU3D().

◆ FlushDirectory()

bool KIPLATFORM::IO::FlushDirectory ( const wxString & aDirPath)

Forces a directory entry's metadata to stable storage.

Without this, a rename() that successfully returns can still be lost on power loss because the directory inode isn't yet committed to the journal.

POSIX opens the directory read-only and calls fsync on its fd. Windows returns true without action since NTFS metadata journaling handles this automatically.

Parameters
aDirPathdirectory containing the files just renamed.
Returns
true on success or on platforms where the call is a no-op.

Definition at line 139 of file common/io.cpp.

Referenced by CommitTempFile().

◆ FlushToDisk()

bool KIPLATFORM::IO::FlushToDisk ( FILE * aFp)

Flushes user-space buffers for aFp and forces the kernel/filesystem to commit the file's data blocks to stable storage.

POSIX uses fflush + fsync. macOS uses fflush + fcntl F_FULLFSYNC, which is stronger than fsync on APFS/HFS+ (the kernel flushes the drive's own write cache). Windows uses fflush + FlushFileBuffers.

Parameters
aFpopen FILE*; must remain open across the call.
Returns
true if every layer reported success.

Definition at line 182 of file unix/io.cpp.

Referenced by AtomicWriteFile().

◆ IsFileHidden()

bool KIPLATFORM::IO::IsFileHidden ( const wxString & aFileName)

Helper function to determine the status of the 'Hidden' file attribute.

Returns
true if the file attribut is set.

Definition at line 109 of file unix/io.cpp.

Referenced by PROJECT_TREE_PANE::addItemToProjectTree().

◆ LongPathAdjustment()

void KIPLATFORM::IO::LongPathAdjustment ( wxFileName & aFilename)

Adjusts a filename to be a long path compatible.

This is a no-op on non-Windows platforms.

Definition at line 117 of file unix/io.cpp.

◆ MakeSiblingTempPath()

wxString KIPLATFORM::IO::MakeSiblingTempPath ( const wxString & aTargetPath)

Returns a unique sibling path of aTargetPath suitable as an atomic-save temp file.

The sibling lives in the same directory so rename() stays atomic. Uniqueness is provided by process pid plus a process-wide atomic counter.

Definition at line 45 of file common/io.cpp.

Referenced by OpenUniqueSiblingTempFile().

◆ MakeWriteable()

bool KIPLATFORM::IO::MakeWriteable ( const wxString & aFilePath)

Ensures that a file has write permissions.

This is useful after copying files that may have been read-only.

Parameters
aFilePathpath to the file to make writeable
Returns
true if the process was successful

Definition at line 78 of file unix/io.cpp.

Referenced by CommitTempFile(), PCB_EDIT_FRAME::SavePcbCopy(), PCB_EDIT_FRAME::SavePcbFile(), and SCH_EDIT_FRAME::saveSchematicFile().

◆ OpenUniqueSiblingTempFile()

FILE * KIPLATFORM::IO::OpenUniqueSiblingTempFile ( const wxString & aTargetPath,
const wxString & aMode,
wxString * aTempPathOut,
wxString * aError = nullptr )

Opens a fresh sibling temp file next to aTargetPath with exclusive-create semantics (POSIX O_CREAT|O_EXCL, Windows CREATE_NEW).

A pre-existing file at the chosen temp path is never opened or truncated; if the candidate is taken the helper retries with a new counter value.

The returned FILE* is opened with aMode ("wb" typically). On success aTempPathOut receives the path actually created. On failure the FILE* is nullptr and aError (if provided) holds a human-readable message.

Callers own the FILE* and must fclose/remove the temp file as appropriate.

Definition at line 66 of file common/io.cpp.

References MakeSiblingTempPath().

Referenced by AtomicWriteFile(), FILE_OUTPUTFORMATTER::FILE_OUTPUTFORMATTER(), and PRETTIFIED_FILE_OUTPUTFORMATTER::PRETTIFIED_FILE_OUTPUTFORMATTER().

◆ ResolveSymlinkTarget()

wxString KIPLATFORM::IO::ResolveSymlinkTarget ( const wxString & aPath)

If aPath is a symlink on POSIX, returns the canonical path of its referent so atomic-save operations replace the underlying file rather than the link itself.

On Windows and when aPath is not a symlink (or does not yet exist) the input is returned unchanged.

Definition at line 120 of file common/io.cpp.

Referenced by AtomicWriteFile().

◆ SeqFOpen()

FILE * KIPLATFORM::IO::SeqFOpen ( const wxString & aPath,
const wxString & mode )

Opens the file like fopen but sets flags (if available) for sequential read hinting.

Only use this variant of fopen if the file is truely going to be read sequentially only otherwise you may encounter performance penalities.

Windows in particular is a little ulgy to set the sequential scan flag compared to say linux and it's posix_fadvise

Definition at line 39 of file unix/io.cpp.

Referenced by FILE_LINE_READER::FILE_LINE_READER().

◆ TimestampDir()

long long KIPLATFORM::IO::TimestampDir ( const wxString & aDirPath,
const wxString & aFilespec )

Computes a hash of modification times and sizes for files matching a pattern.

Used for cache invalidation by detecting changes to library directories.

Parameters
aDirPathDirectory to search
aFilespecWildcard pattern to match (e.g. "*.kicad_mod")
Returns
Hash value that changes when any matching file is modified

Definition at line 123 of file unix/io.cpp.

Referenced by SCH_IO_LIB_CACHE::GetLibModificationTime(), SYMBOL_LIBRARY_MANAGER::GetLibraryHash(), DESIGN_BLOCK_IO::GetLibraryTimestamp(), FP_CACHE::GetTimestamp(), GPCB_FPL_CACHE::GetTimestamp(), SCH_IO_LIB_CACHE::IsFileChanged(), SCH_BASE_FRAME::OnSymChangeDebounceTimer(), SCH_IO_KICAD_LEGACY_LIB_CACHE::Save(), SYMBOL_EDIT_FRAME::saveLibrary(), and SCH_BASE_FRAME::setSymWatcher().

Variable Documentation

◆ CLOUD_SYNC_BUFFER_SIZE

size_t KIPLATFORM::IO::CLOUD_SYNC_BUFFER_SIZE = 512 * 1024
staticconstexpr

Buffer size for file I/O operations on cloud-synced folders.

Cloud sync services like Google Drive, OneDrive, and Dropbox can report stale file sizes during seek operations immediately after writing. Using a 512KB buffer reduces the number of I/O operations and allows the cloud sync driver to flush data more reliably before subsequent reads. This value was determined empirically to eliminate sync issues.

Definition at line 77 of file io.h.

Referenced by PROJECT_ARCHIVER::Archive(), DIALOG_EXPORT_2581::GenerateFile(), DIALOG_EXPORT_ODBPP::GenerateODBPPFiles(), and JOBS_OUTPUT_ARCHIVE::HandleOutputs().