diff options
Diffstat (limited to 'sysdeps/mach/hurd')
-rw-r--r-- | sysdeps/mach/hurd/closedir.c | 20 | ||||
-rw-r--r-- | sysdeps/mach/hurd/dirstream.h | 5 | ||||
-rw-r--r-- | sysdeps/mach/hurd/opendir.c | 6 | ||||
-rw-r--r-- | sysdeps/mach/hurd/readdir.c | 19 | ||||
-rw-r--r-- | sysdeps/mach/hurd/seekdir.c | 4 |
5 files changed, 40 insertions, 14 deletions
diff --git a/sysdeps/mach/hurd/closedir.c b/sysdeps/mach/hurd/closedir.c index 521787d02d..4c62783584 100644 --- a/sysdeps/mach/hurd/closedir.c +++ b/sysdeps/mach/hurd/closedir.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -39,14 +39,22 @@ DEFUN(closedir, (dirp), DIR *dirp) return -1; } - if (err = __vm_deallocate (__mach_task_self (), - (vm_address_t) dirp->__data, dirp->__allocation)) - return __hurd_fail (err); + __libc_lock_lock (dirp->__lock); + err = __vm_deallocate (__mach_task_self (), + (vm_address_t) dirp->__data, dirp->__allocation); dirp->__data = NULL; + err = _hurd_fd_close (dirp->__fd); - if (err = _hurd_fd_close (dirp->__fd)) - return __hurd_fail (err); + if (err) + { + /* Unlock the DIR. A failing closedir can be repeated (and may fail + again, but shouldn't deadlock). */ + __libc_lock_unlock (dirp->__lock); + return __hurd_fail (err); + } + /* Clean up the lock and free the structure. */ + __libc_lock_fini (dirp->__lock); free (dirp); return 0; diff --git a/sysdeps/mach/hurd/dirstream.h b/sysdeps/mach/hurd/dirstream.h index a8c5fd12cb..d17baf2b03 100644 --- a/sysdeps/mach/hurd/dirstream.h +++ b/sysdeps/mach/hurd/dirstream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -20,6 +20,8 @@ Cambridge, MA 02139, USA. */ #define _DIRSTREAM_H 1 +#include <libc-lock.h> + /* Directory stream type. The Hurd directory format is the same as `struct dirent', so `readdir' @@ -34,6 +36,7 @@ struct __dirstream int __entry_ptr; /* Entry number `__ptr' corresponds to. */ unsigned long int __allocation; /* Space allocated for the block. */ unsigned long int __size; /* Total valid data in the block. */ + __libc_lock_define (, __lock); /* Mutex lock for this structure. */ }; #endif /* dirstream.h */ diff --git a/sysdeps/mach/hurd/opendir.c b/sysdeps/mach/hurd/opendir.c index 8ab964a11d..bab84d52f0 100644 --- a/sysdeps/mach/hurd/opendir.c +++ b/sysdeps/mach/hurd/opendir.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -49,7 +49,7 @@ DEFUN(opendir, (name), CONST char *name) { __close (fd); return NULL; - } + } /* Extract the pointer to the descriptor structure. */ __mutex_lock (&_hurd_dtable_lock); @@ -66,5 +66,7 @@ DEFUN(opendir, (name), CONST char *name) dirp->__allocation = 0; dirp->__size = 0; + __libc_lock_init (dirp->__lock); + return dirp; } diff --git a/sysdeps/mach/hurd/readdir.c b/sysdeps/mach/hurd/readdir.c index 3c17d248e1..715f9278a2 100644 --- a/sysdeps/mach/hurd/readdir.c +++ b/sysdeps/mach/hurd/readdir.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -41,6 +41,8 @@ DEFUN(readdir, (dirp), DIR *dirp) return NULL; } + __libc_lock_lock (dirp->__lock); + do { if (dirp->__ptr - dirp->__data >= dirp->__size) @@ -56,7 +58,11 @@ DEFUN(readdir, (dirp), DIR *dirp) &data, &dirp->__size, dirp->__entry_ptr, -1, 0, &nentries))) - return __hurd_fail (err), NULL; + { + __hurd_fail (err); + dp = NULL; + break; + } /* DATA now corresponds to entry index DIRP->__entry_ptr. */ dirp->__entry_data = dirp->__entry_ptr; @@ -77,8 +83,11 @@ DEFUN(readdir, (dirp), DIR *dirp) dirp->__ptr = dirp->__data; if (nentries == 0) - /* End of file. */ - return NULL; + { + /* End of file. */ + dp = NULL; + break; + } /* We trust the filesystem to return correct data and so we ignore NENTRIES. */ @@ -91,5 +100,7 @@ DEFUN(readdir, (dirp), DIR *dirp) /* Loop to ignore deleted files. */ } while (dp->d_fileno == 0); + __libc_lock_unlock (dirp->__lock); + return dp; } diff --git a/sysdeps/mach/hurd/seekdir.c b/sysdeps/mach/hurd/seekdir.c index fa4f1f4f52..a44ac7d246 100644 --- a/sysdeps/mach/hurd/seekdir.c +++ b/sysdeps/mach/hurd/seekdir.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,10 +27,12 @@ Cambridge, MA 02139, USA. */ void DEFUN(seekdir, (dirp, pos), DIR *dirp AND __off_t pos) { + __libc_lock_lock (dirp->__lock); /* Change our entry index pointer to POS and discard any data already read. The next `readdir' call will notice the empty block and read anew from the location in DIRP->__entry_ptr and reset the other state variables. */ dirp->__entry_ptr = pos; dirp->__size = 0; + __libc_lock_unlock (dirp->__lock); } |