diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2014-08-22 13:21:33 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2014-08-22 13:21:33 +0400 |
commit | 3f3bd10104550243781f0b4d9248975e35d91ac7 (patch) | |
tree | c7ac2839d2c3da2321bd9979a1574667ed39bc26 /winsup/cygwin/dir.cc | |
parent | 33ed7bb5bc2cb41259df064229968933d9c898ca (diff) |
* Throughout, use __try/__except/__endtry blocks, rather than myfault
handler.
* cygtls.cc (_cygtls::remove): Accommodate the fact that pathbufs
has been moved from _local_storage to _cygtls.
* cygtls.h (class tls_pathbuf): Add comment to hint to gendef usage
of counters. Change type of counters to uint32_t for clarity.
Remove _cygtls as friend class.
(struct _local_storage): Move pathbufs from here...
(struct _cygtls): ...to here, allowing to access it from _sigbe.
(class san): Only define on 32 bit. Remove errno, _c_cnt and _w_cnt
members.
(san::setup): Drop parameter. Don't initialize removed members.
(san::leave): Don't set removed members.
(class myfault): Only define on 32 bit.
(myfault::faulted): Only keep implementation not taking any parameter.
Drop argument in call to sebastian.setup.
(__try/__leave/__except/__endtry): Implement to support real SEH. For
now stick to SJLJ on 32 bit.
* dcrt0.cc (dll_crt0_0): Drop 64 bit call to
exception::install_myfault_handler.
* exception.h (exception_handler): Define with EXCEPTION_DISPOSITION
as return type.
(PDISPATCHER_CONTEXT): Define as void * on 32 bit. Define as pointer
to _DISPATCHER_CONTEXT on 64 bit.
(class exception): Define separately for 32 and 64 bit.
(exception::myfault): Add handler for myfault SEH handling on 64 bit.
(exception::exception): Fix mangled method name to account for change
in type of last parameter.
(exception::install_myfault_handler): Remove.
* exceptions.cc (exception::myfault_handle): Remove.
(exception::myfault): New SEH handler for 64 bit.
* gendef (_sigbe): Set tls_pathbuf counters to 0 explicitely when
returning to the caller.
* ntdll.h: Move a comment to a better place.
(struct _SCOPE_TABLE): Define on 64 bit.
* thread.cc (verifyable_object_isvalid): Remove gcc 4.7 workaround.
* tls_pbuf.cc (tls_pbuf): Fix to accommodate new place of pathbufs.
(tls_pathbuf::destroy): Change type of loop variables to uint32_t.
* tls_pbuf.h (class tmp_pathbuf): Change type of buffer counters to
uint32_t. Accommodate new place of pathbufs.
* tlsoffsets.h: Regenerate.
* tlsoffsets64.h: Regenerate.
Diffstat (limited to 'winsup/cygwin/dir.cc')
-rw-r--r-- | winsup/cygwin/dir.cc | 337 |
1 files changed, 173 insertions, 164 deletions
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index bdc1a859b..a8eeb2327 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -28,16 +28,16 @@ details. */ extern "C" int dirfd (DIR *dir) { - myfault efault; - if (efault.faulted (EFAULT)) - return -1; - if (dir->__d_cookie != __DIRENT_COOKIE) + __try { - set_errno (EINVAL); + if (dir->__d_cookie == __DIRENT_COOKIE) + return dir->__d_fd; syscall_printf ("-1 = dirfd (%p)", dir); - return -1; + set_errno (EINVAL); } - return dir->__d_fd; + __except (EFAULT) {} + __endtry + return -1; } /* Symbol kept for backward compatibility. Don't remove. Don't declare @@ -93,79 +93,86 @@ fdopendir (int fd) static int readdir_worker (DIR *dir, dirent *de) { - myfault efault; - if (efault.faulted ()) - return EFAULT; + int res = 0; - if (dir->__d_cookie != __DIRENT_COOKIE) + __try { - syscall_printf ("%p = readdir (%p)", NULL, dir); - return EBADF; - } - - de->d_ino = 0; - de->d_type = DT_UNKNOWN; - memset (&de->__d_unused1, 0, sizeof (de->__d_unused1)); - - int res = ((fhandler_base *) dir->__fh)->readdir (dir, de); - - if (res == ENMFILE) - { - if (!(dir->__flags & dirent_saw_dot)) - { - strcpy (de->d_name, "."); - dir->__flags |= dirent_saw_dot; - dir->__d_position++; - res = 0; - } - else if (!(dir->__flags & dirent_saw_dot_dot)) + if (dir->__d_cookie != __DIRENT_COOKIE) { - strcpy (de->d_name, ".."); - dir->__flags |= dirent_saw_dot_dot; - dir->__d_position++; - res = 0; + syscall_printf ("%p = readdir (%p)", NULL, dir); + res = EBADF; + __leave; } - } - if (!res && !de->d_ino) - { - bool is_dot = false; - bool is_dot_dot = false; + de->d_ino = 0; + de->d_type = DT_UNKNOWN; + memset (&de->__d_unused1, 0, sizeof (de->__d_unused1)); - if (de->d_name[0] == '.') + res = ((fhandler_base *) dir->__fh)->readdir (dir, de); + + if (res == ENMFILE) { - if (de->d_name[1] == '\0') - is_dot = true; - else if (de->d_name[1] == '.' && de->d_name[2] == '\0') - is_dot_dot = true; + if (!(dir->__flags & dirent_saw_dot)) + { + strcpy (de->d_name, "."); + dir->__flags |= dirent_saw_dot; + dir->__d_position++; + res = 0; + } + else if (!(dir->__flags & dirent_saw_dot_dot)) + { + strcpy (de->d_name, ".."); + dir->__flags |= dirent_saw_dot_dot; + dir->__d_position++; + res = 0; + } } - if (is_dot_dot && !(dir->__flags & dirent_isroot)) - de->d_ino = readdir_get_ino (((fhandler_base *) dir->__fh)->get_name (), - true); - else + if (!res && !de->d_ino) { - /* Compute d_ino by combining filename hash with directory hash. */ - de->d_ino = ((fhandler_base *) dir->__fh)->get_ino (); - if (!is_dot && !is_dot_dot) + bool is_dot = false; + bool is_dot_dot = false; + + if (de->d_name[0] == '.') + { + if (de->d_name[1] == '\0') + is_dot = true; + else if (de->d_name[1] == '.' && de->d_name[2] == '\0') + is_dot_dot = true; + } + + if (is_dot_dot && !(dir->__flags & dirent_isroot)) + de->d_ino = readdir_get_ino (((fhandler_base *) + dir->__fh)->get_name (), + true); + else { - PUNICODE_STRING w32name = - ((fhandler_base *) dir->__fh)->pc.get_nt_native_path (); - DWORD devn = ((fhandler_base *) dir->__fh)->get_device (); - /* Paths below /proc don't have a Win32 pendant. */ - if (isproc_dev (devn)) - de->d_ino = hash_path_name (de->d_ino, L"/"); - else if (w32name->Buffer[w32name->Length / sizeof (WCHAR) - 1] - != L'\\') - de->d_ino = hash_path_name (de->d_ino, L"\\"); - de->d_ino = hash_path_name (de->d_ino, de->d_name); + /* Compute d_ino by combining filename hash with directory hash. */ + de->d_ino = ((fhandler_base *) dir->__fh)->get_ino (); + if (!is_dot && !is_dot_dot) + { + PUNICODE_STRING w32name = + ((fhandler_base *) dir->__fh)->pc.get_nt_native_path (); + DWORD devn = ((fhandler_base *) dir->__fh)->get_device (); + /* Paths below /proc don't have a Win32 pendant. */ + if (isproc_dev (devn)) + de->d_ino = hash_path_name (de->d_ino, L"/"); + else if (w32name->Buffer[w32name->Length / sizeof (WCHAR) - 1] + != L'\\') + de->d_ino = hash_path_name (de->d_ino, L"\\"); + de->d_ino = hash_path_name (de->d_ino, de->d_name); + } } } + /* This fills out the old 32 bit d_ino field for old applications, + build under Cygwin before 1.5.x. */ + de->__d_internal1 = de->d_ino; } - /* This fills out the old 32 bit d_ino field for old applications, - build under Cygwin before 1.5.x. */ - de->__d_internal1 = de->d_ino; - + __except (NO_ERROR) + { + res = EFAULT; + } + __endtry return res; } @@ -200,16 +207,15 @@ readdir_r (DIR *__restrict dir, dirent *__restrict de, dirent **__restrict ode) extern "C" long telldir (DIR *dir) { - myfault efault; - if (efault.faulted (EFAULT)) - return -1; - - if (dir->__d_cookie != __DIRENT_COOKIE) + __try { + if (dir->__d_cookie == __DIRENT_COOKIE) + return ((fhandler_base *) dir->__fh)->telldir (dir); set_errno (EBADF); - return -1; } - return ((fhandler_base *) dir->__fh)->telldir (dir); + __except (EFAULT) {} + __endtry + return -1; } /* telldir was never defined using off_t in POSIX, only in early versions @@ -225,14 +231,17 @@ telldir64 (DIR *dir) extern "C" void seekdir (DIR *dir, long loc) { - myfault efault; - if (efault.faulted (EFAULT)) - return; - - if (dir->__d_cookie != __DIRENT_COOKIE) - return; - dir->__flags &= dirent_info_mask; - return ((fhandler_base *) dir->__fh)->seekdir (dir, loc); + __try + { + if (dir->__d_cookie == __DIRENT_COOKIE) + { + dir->__flags &= dirent_info_mask; + ((fhandler_base *) dir->__fh)->seekdir (dir, loc); + } + set_errno (EINVAL); /* Diagnosis */ + } + __except (EFAULT) {} + __endtry } /* seekdir was never defined using off_t in POSIX, only in early versions @@ -248,42 +257,45 @@ seekdir64 (DIR *dir, off_t loc) extern "C" void rewinddir (DIR *dir) { - myfault efault; - if (efault.faulted (EFAULT)) - return; - - if (dir->__d_cookie != __DIRENT_COOKIE) - return; - dir->__flags &= dirent_info_mask; - return ((fhandler_base *) dir->__fh)->rewinddir (dir); + __try + { + if (dir->__d_cookie == __DIRENT_COOKIE) + { + dir->__flags &= dirent_info_mask; + ((fhandler_base *) dir->__fh)->rewinddir (dir); + } + set_errno (EINVAL); /* Diagnosis */ + } + __except (EFAULT) {} + __endtry } /* closedir: POSIX 5.1.2.1 */ extern "C" int closedir (DIR *dir) { - myfault efault; - if (efault.faulted (EFAULT)) - return -1; - - if (dir->__d_cookie != __DIRENT_COOKIE) + __try { - set_errno (EBADF); - syscall_printf ("%R = closedir(%p)", -1, dir); - return -1; - } - - /* Reset the marker in case the caller tries to use `dir' again. */ - dir->__d_cookie = 0; + if (dir->__d_cookie == __DIRENT_COOKIE) + { + /* Reset the marker in case the caller tries to use `dir' again. */ + dir->__d_cookie = 0; - int res = ((fhandler_base *) dir->__fh)->closedir (dir); + int res = ((fhandler_base *) dir->__fh)->closedir (dir); - close (dir->__d_fd); - free (dir->__d_dirname); - free (dir->__d_dirent); - free (dir); - syscall_printf ("%R = closedir(%p)", res, dir); - return res; + close (dir->__d_fd); + free (dir->__d_dirname); + free (dir->__d_dirent); + free (dir); + syscall_printf ("%R = closedir(%p)", res, dir); + return res; + } + set_errno (EBADF); + } + __except (EFAULT) {} + __endtry + syscall_printf ("%R = closedir(%p)", -1, dir); + return -1; } /* mkdir: POSIX 5.4.1.1 */ @@ -294,43 +306,42 @@ mkdir (const char *dir, mode_t mode) fhandler_base *fh = NULL; tmp_pathbuf tp; - myfault efault; - if (efault.faulted (EFAULT)) - return -1; - - /* POSIX says mkdir("symlink-to-missing/") should create the - directory "missing", but Linux rejects it with EEXIST. Copy - Linux behavior for now. */ - - if (!*dir) - { - set_errno (ENOENT); - goto done; - } - if (isdirsep (dir[strlen (dir) - 1])) + __try { - /* This converts // to /, but since both give EEXIST, we're okay. */ - char *buf; - char *p = stpcpy (buf = tp.c_get (), dir) - 1; - dir = buf; - while (p > dir && isdirsep (*p)) - *p-- = '\0'; - } - if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW))) - goto done; /* errno already set */; + /* POSIX says mkdir("symlink-to-missing/") should create the + directory "missing", but Linux rejects it with EEXIST. Copy + Linux behavior for now. */ - if (fh->error ()) - { - debug_printf ("got %d error from build_fh_name", fh->error ()); - set_errno (fh->error ()); - } - else if (has_dot_last_component (dir, true)) - set_errno (fh->exists () ? EEXIST : ENOENT); - else if (!fh->mkdir (mode)) - res = 0; - delete fh; + if (!*dir) + { + set_errno (ENOENT); + __leave; + } + if (isdirsep (dir[strlen (dir) - 1])) + { + /* This converts // to /, but since both give EEXIST, we're okay. */ + char *buf; + char *p = stpcpy (buf = tp.c_get (), dir) - 1; + dir = buf; + while (p > dir && isdirsep (*p)) + *p-- = '\0'; + } + if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW))) + __leave; /* errno already set */; - done: + if (fh->error ()) + { + debug_printf ("got %d error from build_fh_name", fh->error ()); + set_errno (fh->error ()); + } + else if (has_dot_last_component (dir, true)) + set_errno (fh->exists () ? EEXIST : ENOENT); + else if (!fh->mkdir (mode)) + res = 0; + delete fh; + } + __except (EFAULT) {} + __endtry syscall_printf ("%R = mkdir(%s, %d)", res, dir, mode); return res; } @@ -342,30 +353,28 @@ rmdir (const char *dir) int res = -1; fhandler_base *fh = NULL; - myfault efault; - if (efault.faulted (EFAULT)) - return -1; - - if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW))) - goto done; /* errno already set */; - - if (fh->error ()) + __try { - debug_printf ("got %d error from build_fh_name", fh->error ()); - set_errno (fh->error ()); + if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW))) + __leave; /* errno already set */; + + if (fh->error ()) + { + debug_printf ("got %d error from build_fh_name", fh->error ()); + set_errno (fh->error ()); + } + else if (!fh->exists ()) + set_errno (ENOENT); + else if (has_dot_last_component (dir, false)) + set_errno (EINVAL); + else if (isdev_dev (fh->dev ())) + set_errno (ENOTEMPTY); + else if (!fh->rmdir ()) + res = 0; + delete fh; } - else if (!fh->exists ()) - set_errno (ENOENT); - else if (has_dot_last_component (dir, false)) - set_errno (EINVAL); - else if (isdev_dev (fh->dev ())) - set_errno (ENOTEMPTY); - else if (!fh->rmdir ()) - res = 0; - - delete fh; - - done: + __except (EFAULT) {} + __endtry syscall_printf ("%R = rmdir(%s)", res, dir); return res; } |