mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-20 09:30:31 +00:00
Improve handling of weird reparse points
On Windows file system tools like `ls` would print errors when they find things like WSL symlinks, which can't be read by WIN32. I don't know how they got on my hard drive but this change ensures Cosmo will handle them more gracefully. If a reparse point can't be followed, then fstatat will return information about the link itself. If readlink encounters reparse points that are WIN32 symlinks, then it'll log more helpful details when using MODE=dbg (a.k.a. cosmocc -mdbg). Speaking of which, this change is also going to help you troubleshoot locks; when you build your app using the cosmocc -mdbg flag your --strace logs will now show lock acquisition
This commit is contained in:
parent
90460ceb3c
commit
79516bf08e
4 changed files with 57 additions and 48 deletions
|
@ -16,11 +16,11 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/fds.h"
|
||||
#include "libc/calls/struct/sigset.internal.h"
|
||||
#include "libc/calls/struct/stat.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/fds.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
|
@ -97,14 +97,27 @@ TryAgain:
|
|||
0)) != -1) {
|
||||
rc = st ? sys_fstat_nt_handle(fh, path16, st) : 0;
|
||||
CloseHandle(fh);
|
||||
} else if (dwDesiredAccess == kNtFileGenericRead &&
|
||||
(GetLastError() == kNtErrorAccessDenied ||
|
||||
GetLastError() == kNtErrorSharingViolation)) {
|
||||
dwDesiredAccess = kNtFileReadAttributes;
|
||||
errno = e;
|
||||
goto TryAgain;
|
||||
} else {
|
||||
rc = __winerr();
|
||||
uint32_t dwErrorCode = GetLastError();
|
||||
if (dwDesiredAccess == kNtFileGenericRead &&
|
||||
(dwErrorCode == kNtErrorAccessDenied ||
|
||||
dwErrorCode == kNtErrorSharingViolation)) {
|
||||
dwDesiredAccess = kNtFileReadAttributes;
|
||||
errno = e;
|
||||
goto TryAgain;
|
||||
} else if (!(flags & AT_SYMLINK_NOFOLLOW) &&
|
||||
dwErrorCode == kNtErrorCantAccessFile) {
|
||||
// ERROR_CANT_ACCESS_FILE (1920) usually means that the I/O system
|
||||
// a WSL symlink is accessed from WIN32 API. Falling back with the
|
||||
// failed to traverse a filesystem reparse point. For example when
|
||||
// details of the link itself is better than providing nothing. It
|
||||
// should never be like this on UNIX but Windows gets a bit screwy
|
||||
flags |= AT_SYMLINK_NOFOLLOW;
|
||||
errno = e;
|
||||
goto TryAgain;
|
||||
} else {
|
||||
rc = __winerr();
|
||||
}
|
||||
}
|
||||
ALLOW_SIGNALS;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue