summaryrefslogtreecommitdiff
path: root/sysdeps/mach/hurd
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mach/hurd')
-rw-r--r--sysdeps/mach/hurd/closedir.c20
-rw-r--r--sysdeps/mach/hurd/dirstream.h5
-rw-r--r--sysdeps/mach/hurd/opendir.c6
-rw-r--r--sysdeps/mach/hurd/readdir.c19
-rw-r--r--sysdeps/mach/hurd/seekdir.c4
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);
}