SDL_CopyFile(3)

πŸ’– SDL_CopyFile(3) β€” SDL3 FUNCTIONS πŸ’–

okay bestie, gather round, because we're about to talk about the most "sure jan" little filesystem function in all of SDL3: SDL_CopyFile πŸ’… it does exactly one thing and it does it with main character energy, and that thing is copy a file. periodt.


✨ NAME ✨

SDL_CopyFile β€” copy a file. that's it. that's the whole job description πŸŽ€


🌸 SYNOPSIS 🌸

#include <SDL3/SDL_filesystem.h>

bool SDL_CopyFile(const char *oldpath, const char *newpath);

look at her. two const char *s and a bool. lowkey iconic if you ask me πŸ’–


πŸ¦‹ DESCRIPTION πŸ¦‹

so here's the tea, bestie. if the file at newpath already exists? it's getting overwritten with the contents of the file at oldpath. no asking, no backup, no "are you sure". it just goes 🫢

this function blocks until the copy is complete. and ngl, for large files on slow disks that could be a significant amount of time, so maybe don't call this on your UI thread while you're also trying to be cute about frame pacing 😭 on some platforms the copy can be handed off to the OS itself (slay, efficient), but on others SDL might just open both paths and read from one and write to the other. no cap, that's literally what it might do.

not me about to deliver the most important warning of this whole page πŸ’€ this is NOT an atomic operation! if something tries to read from newpath while the copy is in progress, it will see an incomplete copy of the data. and if the calling thread terminates (or the power goes out 😡) during the copy, newpath's previous contents will be gone, replaced with an incomplete copy of the data. like, the old stuff? evaporated. the new stuff? half-baked. it's giving cursed.

so what's the move? the recommended trick is this: copy to a temporary file in the same directory as newpath, and if the copy is successful, use SDL_RenamePath() to replace newpath with the temporary file. that way, reads of newpath will either see a complete copy of the data, or the pre-copy state of newpath. no in-between, no cursed half-file, we love a clean handoff ✨

and here's the extra thoughtful part: this function attempts to synchronize the newly-copied data to disk before returning, if the platform allows it. why? so the renaming trick won't have a problem in a system crash or power failure, where the file could be renamed but the contents never made it from the system file cache to the physical disk. she's thinking ahead, she's being responsible, she's that girl πŸ’œ

and finally, the part nobody wants to hear: if the copy fails for any reason, the state of newpath is undefined. it might be half a copy, it might be the untouched data of what was already there, it might be a zero-byte file, etc. etc. etc. πŸ™ˆ we simply do not know. mystery behaviour. chaos vibes.


πŸŽ€ FUNCTION PARAMETERS πŸŽ€

  • oldpath β€” the old path. the source. the origin story. the "before" pic πŸ“Έ
  • newpath β€” the new path. the destination. the glow-up. the "after" πŸ’…

⭐ RETURN VALUE ⭐

returns true on success or false on failure 🫢 and if it's false? call SDL_GetError() for more information, bestie, because she will tell you what went wrong. always check your errors, it's the bare minimum 🌸


🌈 THREAD SAFETY 🌈

it is safe to call this function from any thread πŸ‘‘ but β€” and you knew there was a but β€” this operation is not atomic, so the app might need to protect access to specific paths from other threads if appropriate. so like, if two threads are messing with the same path, that's a you problem, and you should probably do something about it πŸ’€


πŸ’« AVAILABILITY πŸ’«

this function is available since SDL 3.2.0. so if you're on something older... no she's not there yet, sorry babe πŸŽ€


the renaming trick, one more time, because it's the whole plot: copy to a temp file in the same directory as newpath β†’ if it worked, SDL_RenamePath() to swap it in β†’ readers see either the complete new data or the untouched old data, never a cursed franken-file ✨

and that's the page, bestie πŸ’– this was Simple Directmedia Layer, SDL 3.4.18, and the page is SDL_CopyFile(3) β€” stay atomic out there (or at least fake it with a rename) πŸ¦‹πŸ’…

πŸ“¦ where this page comes from