<div dir="ltr"><div>Let's have a look at the POSIX spec for open(): <a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html">https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html</a> It very clearly distinguishes between *2* disjoint sets of flags:</div><div><br></div><div>   * You have to use exactly one of O_EXEC, O_RDONLY, O_RDWR, O_SEARCH, and O_WRONLY.</div><div><br></div><div>   * In addition, you can specify any combination of O_APPEND, O_CLOEXEC, O_CREAT, O_DIRECTORY, O_DSYNC, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_NONBLOCK, O_RSYNC, O_SYNC, O_TRUNC, and O_TTY_INIT.</div><br><div>Alas, GHC.IO.FD and GHC.IO.IOMode completely ignore this distinction already and add tons of special cases:</div><div><br></div><div>   * They add an ad hoc combination of O_WRONLY and O_APPEND (AppendMode).</div><div><br></div><div>   * They leave out O_EXEC and O_SEARCH.</div><div><br></div><div>   * They add  an ad hoc boolean flag for non-blocking I/O to openFile, i.e. pick 1 of the 13 possible additional flags.</div><div><br></div><div>   * For some obscure reason, O_NOCTTY is always added.</div><div><br></div><div>   * HandleType doesn't reflect the first set of flags.</div><div><br></div><div>My proposal is to not make this mess even worse by adding yet another ad hoc combination, but to think about how to expose these two sets in a sane way.</div><div><br></div><div>I didn't have a look at the Windows counterpart or into all the *nix variants yet, but I guess that the overlap in the API is quite big. But even the intersection of all the relevant platforms will very probably have the distinction between the 2 sets of flags, so we should reflect that in the Haskell API, too.</div></div>