Send bytes directly to `path-list-string->path-list`, since it can
handle bytes and convert directly to paths. Also check that the
argument to `path-list-string->path-list` has no nul character or byte.
Commit a110c58e52 broke the interaction with `PLTCOMPILEDROOTS`.
Instead of reverting to the old behavior that coerced 'same to a path,
this change makes `path-list-string->path-list` a little more
flexible.
Closes#3704
Since file links and directory links on Windows are disjoint, and the
difference is relevant for operations such as deleting a file,
`link-exists?` is not enough information. Add `file-or-directory-type`
to provide more information and also avoid separate calls to
`file-exists?`, `directory-exists?`, etc.
The `delete-directory/files` function now uses `file-or-directory-type`
so that it will work right with Windows directory links.
Relevant to #3288
It most cases, it's more important for `compiler/cm` to reliably
replace a file that might be busy than to make the file update atomic.
To suport that kind of use, `call-with-atomic-output-file` implemented
a fairly reliable, multi-step, non-atomic process for replacing a file
on Windows.
For recompilation of bytecode in machine-independent form, however,
`compiler/cm` now really wants to atomically write a replacement
bytecode file. That's not generally possible on Windows (except on
NTFS with transactions, which are discouraged...), but MoveFileEx work
atomically in some cases and it's likely to work for the cases needed
by `compiler/cm`. Probably.
So, add a mode to `call-with-atomic-output-file` to get "more atomic"
updates on Windows. This mode is enabled by a callback that makes the
caller responsible for deciding what to do with the move fails, such
as waiting a while and trying again. And `compiler/cm` now waits a
while and tries again, up to a limit, which should be good enough for
recompilation.
* When you delete a file in Windows, then the name doesn't go away
until the file is closed in all processes (and background tasks like
search indexing may open files behind your back). Worse, attempting
to create a new file with the same name reports a permission error,
not a file-exists error; there's seems to be no way to tell whether
a permission error was really a file-exists error.
This creates trouble for `make-temporary-file` when files are
created, deleted, and created again quickly enough and when
something like a search indexer runs in the background (which is the
usual Windows configuration). In practice, that kind of collision
happens often for `raco setup` on my machine.
To compensate, make `make-temporary-file` try up to 32 times on a
permission error. A collision that many times seems extremely
unlikely, and it seems ok to delay an actual permission error.
Windows provides a GetTempFileName function from "kernel.dll" that
must be able to deal with this somehow --- perhaps because it's in
the kernel --- but it doesn't solve the problem for making temporary
directories, hence the 32-tries approach for now.
* When a deleted file's name persists because the file is open in some
process, then a directory containing the file cannot be deleted.
This creates trouble for `delete-directory/files`, since
`delete-file` on a directory's content doesn't necessarily make the
directory empty. In practice, this happens often for package
upgrades on my machine, where the package system wants to delete a
short-lived working space that the indexer is trying to scan.
To compenstate, change `delete-directory/files` to delete a file by
first moving it to the temporary directory with a fresh name, and
then delete the file there. It may take a while for a file to
disappear from the temporary directory, but meanwhile it's not in
the way of the original enclosing directory.
* When a file is open by any process, it prevents renaming any
ancestor directory of the file.
This creates trouble for the package system, which installs a
package by unpacking it in a temporary place and then moving it by
renaming. The package system also removes a package by renaming it
to a subdirectory of a ".trash" directory. If a background indexer
has a package file open, the move fails. In practice, a move fails
often on my machine when I'm attempting to upgrade many packages.
To compensate, make the package system fall back to copy + delete
if moving fails with a permission error.
Detangle the target and host DLL and library directories by
making `get-lib-search-dirs` and `get-dll-dir` report the
host system's directories, and add `get-cross-lib-search-dirs`
and `get-cross-dll-dir`.
A new `-C`/`--cross` flag causes `racket` to save a host config and
collection directory and make them available via `(find-system-path
'host-{config,collects}-dir)`, while plus `(system-type 'cross)`
reports whether `-C` mode is in effect. Besides making the host paths
available, this change allows a same-platform build to run in
corss-platform mode.
The immediate problem to solve was the creation of Windows installers
on Windows, where recent changes to support 'gui-bin-dir configuration
need a clear distinction between the host Racket and the target Racket
being built, even if they're the same platform. (The "GRacket.exe"
executable didn't work, for example.)
The changes in this commit are more than needed for the immediate
problem, but they naturally build on the necessary `-C` flag, and they
support cross-platform package setup where native libraries are needed
during setup.
Although "macOS" is the correct name for Apple's current desktop OS,
we've decided to go with "Mac OS" to cover all of Apple's Unix-like
desktop OS versions. The label "Mac OS" is more readable, clear in
context (i.e., unlikely to be confused with the Mac OSes that
proceeded Mac OS X), and as likely to match Apple's future OS names
as anything.
On Unix and OS X, the check to avoid replacing an existing
file or directory is made by Racket, rather than the OS,
so don't claim a system error if the operation fails for
that reason.
Also, update the docs to clarify that the check is not
atomic with the move.
Closes issue #1158
The expression in a `define-runtime-path` form is used in
both a run-time context and a compile-time context. The
latter is used for `raco exe`. In a cross-build context,
you might need to load OpenSSL support for Linux (say)
at build time while generating executables that refer to
Windows (say) OpenSSL support. In that case, `#:runtime?-id`
lets you choose between `(cross-system-type)` and
`(system-type)`.
Merge to v6.4
Also, add `#:skip-filtered-directory?` to `find-files`.
Less significantly, adjust `pathlist-closure` to be consistent in the
way that it includes a separator at the end of a directory path.
Port `examples`, `interactions`, etc., to use the new `examples`
form of `scribble/examples`. The main intended effect is to ensure
that errors are produced by examples only as specifically
indicated.
If a file or directory delete fails, try adjusting the file or directory
permissions to allow writes, then try deleting again. This process should
provide a more Unix-like experience and make programs behave more
consistently.
A new `current-force-delete-permissions` parameter provides access to
the raw native behavior.