Tue Jul 9 09:37:55 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* sysdeps/mach/libc-lock.h: New file. * sysdeps/unix/readdir.c: Do locking. * sysdeps/unix/seekdir.c: Likewise. * sysdeps/unix/rewinddir.c: Likewise. * sysdeps/unix/closedir.c: Likewise. * sysdeps/unix/bsd/telldir.c: Likewise. * sysdeps/mach/hurd/seekdir.c: Likewise. * sysdeps/mach/hurd/readdir.c: Likewise. * sysdeps/mach/hurd/closedir.c: Likewise. * sysdeps/mach/hurd/opendir.c: Initialize the lock. * sysdeps/unix/opendir.c: Likewise. * sysdeps/mach/hurd/dirstream.h: Include <libc-lock.h>. (struct __dirstream): Add lock member using __libc_lock_define. * sysdeps/unix/dirstream.h: Likewise. * sysdeps/stub/libc-lock.h (__libc_lock_fini): New macro. * stdlib/mbstowcs.c: Pass address of pointer to mbsrtowcs. * stdlib/wcstombs.c: Use wcsrtombs instead of mbsrtowcs. Thu Jul 4 01:34:04 1996 Ulrich Drepper <drepper@cygnus.com> * locale/programs/stringtrans.c: Fix typo in copyright. * stdio-common/printf-prs.c: Add casts to prevent signed<->unsigned warnings. * stdio-common/printf-parse.h: Initialize state variable before calling mbrlen. * stdio-common/printf-prs.c: Don't initialize state variable here. * stdio-common/vfprintf.c: Don't initialize state variable. (vfprintf): While determining length of multibyte string don't try to be clever in determining characters to use for first call. Add real implementation of multibyte<->wide char conversion functions. The functions always convert between the fixed wide char format (ISO 10646 in UCS4) and the UTF8 representation of this character set. Conversion between the currently used 8bit character set and ISO 10646 will not take place. This is what iconv() is for. * wcsmbs/wchar.h (mbstate_t): Define as structure to replace dummy definition. Add optimized version of `mbrlen' function. * wcsmbs/btowc.c (btowc): Restrict range of legal characters to 0...0x7f. * wcsmbs/wctob.c (wctob): Restrict range of legal characters to 0..0x7f. * wcsmbs/mbrlen.c: Make mbrlen a weak alias of __mbrlen. This is needed in the wchar.h header. * wcsmbs/mbrtowc.c: Replace dummy implementation. Convert UTF8 encoded character to UCS4. * wcsmbs/mbsinit.c: Replace dummy implementation. Test COUNT element of `mbstate_t' for initial state. * wcsmbs/mbsrtowcs.c: Replace dummy implementation. Convert UTF8 encoded string to UCS4 string. * wcsmbs/wcrtomb.c: Replace dummy implementation. Convert UCS4 character to UTF8 encoded form. * wcsmbs/wcsrtombs.c: Replace dummy implementation. Convert UCS4 encoded string to UTF8 encoded form.
This commit is contained in:
parent
089b2b8ad8
commit
c150923988
64
ChangeLog
64
ChangeLog
@ -1,3 +1,67 @@
|
||||
Tue Jul 9 09:37:55 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* sysdeps/mach/libc-lock.h: New file.
|
||||
* sysdeps/unix/readdir.c: Do locking.
|
||||
* sysdeps/unix/seekdir.c: Likewise.
|
||||
* sysdeps/unix/rewinddir.c: Likewise.
|
||||
* sysdeps/unix/closedir.c: Likewise.
|
||||
* sysdeps/unix/bsd/telldir.c: Likewise.
|
||||
* sysdeps/mach/hurd/seekdir.c: Likewise.
|
||||
* sysdeps/mach/hurd/readdir.c: Likewise.
|
||||
* sysdeps/mach/hurd/closedir.c: Likewise.
|
||||
* sysdeps/mach/hurd/opendir.c: Initialize the lock.
|
||||
* sysdeps/unix/opendir.c: Likewise.
|
||||
* sysdeps/mach/hurd/dirstream.h: Include <libc-lock.h>.
|
||||
(struct __dirstream): Add lock member using __libc_lock_define.
|
||||
* sysdeps/unix/dirstream.h: Likewise.
|
||||
|
||||
* sysdeps/stub/libc-lock.h (__libc_lock_fini): New macro.
|
||||
|
||||
* stdlib/mbstowcs.c: Pass address of pointer to mbsrtowcs.
|
||||
|
||||
* stdlib/wcstombs.c: Use wcsrtombs instead of mbsrtowcs.
|
||||
|
||||
Thu Jul 4 01:34:04 1996 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* locale/programs/stringtrans.c: Fix typo in copyright.
|
||||
|
||||
* stdio-common/printf-prs.c: Add casts to prevent
|
||||
signed<->unsigned warnings.
|
||||
|
||||
* stdio-common/printf-parse.h: Initialize state variable before
|
||||
calling mbrlen.
|
||||
* stdio-common/printf-prs.c: Don't initialize state variable here.
|
||||
* stdio-common/vfprintf.c: Don't initialize state variable.
|
||||
(vfprintf): While determining length of multibyte string don't
|
||||
try to be clever in determining characters to use for first
|
||||
call.
|
||||
|
||||
Add real implementation of multibyte<->wide char conversion
|
||||
functions. The functions always convert between the fixed wide
|
||||
char format (ISO 10646 in UCS4) and the UTF8 representation of
|
||||
this character set. Conversion between the currently used
|
||||
8bit character set and ISO 10646 will not take place. This is
|
||||
what iconv() is for.
|
||||
* wcsmbs/wchar.h (mbstate_t): Define as structure to replace
|
||||
dummy definition.
|
||||
Add optimized version of `mbrlen' function.
|
||||
* wcsmbs/btowc.c (btowc): Restrict range of legal characters
|
||||
to 0...0x7f.
|
||||
* wcsmbs/wctob.c (wctob): Restrict range of legal characters
|
||||
to 0..0x7f.
|
||||
* wcsmbs/mbrlen.c: Make mbrlen a weak alias of __mbrlen.
|
||||
This is needed in the wchar.h header.
|
||||
* wcsmbs/mbrtowc.c: Replace dummy implementation. Convert UTF8
|
||||
encoded character to UCS4.
|
||||
* wcsmbs/mbsinit.c: Replace dummy implementation. Test COUNT
|
||||
element of `mbstate_t' for initial state.
|
||||
* wcsmbs/mbsrtowcs.c: Replace dummy implementation. Convert UTF8
|
||||
encoded string to UCS4 string.
|
||||
* wcsmbs/wcrtomb.c: Replace dummy implementation. Convert UCS4
|
||||
character to UTF8 encoded form.
|
||||
* wcsmbs/wcsrtombs.c: Replace dummy implementation. Convert UCS4
|
||||
encoded string to UTF8 encoded form.
|
||||
|
||||
Tue Jul 9 06:19:29 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* sysdeps/unix/sysv/linux/configure.in: Use version number in cache
|
||||
|
@ -36,7 +36,7 @@ mbstowcs (wchar_t *pwcs, const char *s, size_t n)
|
||||
mbstate_t save_shift = __no_r_state;
|
||||
size_t written;
|
||||
|
||||
written = mbsrtowcs (pwcs, s, n, &__no_r_state);
|
||||
written = mbsrtowcs (pwcs, &s, n, &__no_r_state);
|
||||
|
||||
/* Restore the old shift state. */
|
||||
__no_r_state = save_shift;
|
||||
|
@ -36,7 +36,7 @@ wcstombs (char *s, const wchar_t *pwcs, size_t n)
|
||||
mbstate_t save_shift = __no_r_state;
|
||||
size_t written;
|
||||
|
||||
written = mbsrtowcs (pwcs, s, n, &__no_r_state);
|
||||
written = wcsrtombs (s, &pwcs, n, &__no_r_state);
|
||||
|
||||
/* Restore the old shift state. */
|
||||
__no_r_state = save_shift;
|
||||
|
@ -110,6 +110,9 @@ const char *_sys_errlist[] =
|
||||
#ifdef EAGAIN
|
||||
[EAGAIN] = N_("Resource temporarily unavailable"),
|
||||
#endif
|
||||
#if defined (EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||||
[EWOULDBLOCK] = N_("Operation would block"),
|
||||
#endif
|
||||
#ifdef EINPROGRESS
|
||||
[EINPROGRESS] = N_("Operation now in progress"),
|
||||
#endif
|
||||
@ -268,6 +271,150 @@ const char *_sys_errlist[] =
|
||||
#endif
|
||||
#ifdef EGRATUITOUS
|
||||
[EGRATUITOUS] = N_("Gratuitous error"),
|
||||
#endif
|
||||
#ifdef ERESTART
|
||||
[ERESTART] = N_("Interrupted system call should be restarted"),
|
||||
#endif
|
||||
#ifdef ENOMSG
|
||||
[ENOMSG] = N_("No message of desired type"),
|
||||
#endif
|
||||
#ifdef EIDRM
|
||||
[EIDRM] = N_("Identifier removed"),
|
||||
#endif
|
||||
#ifdef ECHRNG
|
||||
[ECHRNG] = N_("Channel number out of range"),
|
||||
#endif
|
||||
#ifdef EL2NSYNC
|
||||
[EL2NSYNC] = N_("Level 2 not synchronized"),
|
||||
#endif
|
||||
#ifdef EL3HLT
|
||||
[EL3HLT] = N_("Level 3 halted"),
|
||||
#endif
|
||||
#ifdef EL3RST
|
||||
[EL3RST] = N_("Level 3 reset"),
|
||||
#endif
|
||||
#ifdef ELNRNG
|
||||
[ELNRNG] = N_("Link number out of range"),
|
||||
#endif
|
||||
#ifdef EUNATCH
|
||||
[EUNATCH] = N_("Protocol driver not attached"),
|
||||
#endif
|
||||
#ifdef ENOCSI
|
||||
[ENOCSI] = N_("No CSI structure available"),
|
||||
#endif
|
||||
#ifdef EL2HLT
|
||||
[EL2HLT] = N_("Level 2 halted"),
|
||||
#endif
|
||||
#ifdef EBADE
|
||||
[EBADE] = N_("Invalid exchange"),
|
||||
#endif
|
||||
#ifdef EBADR
|
||||
[EBADR] = N_("Invalid request descriptor"),
|
||||
#endif
|
||||
#ifdef EXFULL
|
||||
[EXFULL] = N_("Exchange full"),
|
||||
#endif
|
||||
#ifdef ENOANO
|
||||
[ENOANO] = N_("No anode"),
|
||||
#endif
|
||||
#ifdef EBADRQC
|
||||
[EBADRQC] = N_("Invalid request code"),
|
||||
#endif
|
||||
#ifdef EBADSLT
|
||||
[EBADSLT] = N_("Invalid slot"),
|
||||
#endif
|
||||
#if defined (EDEADLOCK) && EDEADLOCK != EDEADLK
|
||||
[EDEADLOCK] = N_("File locking deadlock error"),
|
||||
#endif
|
||||
#ifdef EBFONT
|
||||
[EBFONT] = N_("Bad font file format"),
|
||||
#endif
|
||||
#ifdef ENOSTR
|
||||
[ENOSTR] = N_("Device not a stream"),
|
||||
#endif
|
||||
#ifdef ENODATA
|
||||
[ENODATA] = N_("No data available"),
|
||||
#endif
|
||||
#ifdef ETIME
|
||||
[ETIME] = N_("Timer expired"),
|
||||
#endif
|
||||
#ifdef ENOSR
|
||||
[ENOSR] = N_("Out of streams resources"),
|
||||
#endif
|
||||
#ifdef ENONET
|
||||
[ENONET] = N_("Machine is not on the network"),
|
||||
#endif
|
||||
#ifdef ENOPKG
|
||||
[ENOPKG] = N_("Package not installed"),
|
||||
#endif
|
||||
#ifdef ENOLINK
|
||||
[ENOLINK] = N_("Link has been severed"),
|
||||
#endif
|
||||
#ifdef EADV
|
||||
[EADV] = N_("Advertise error"),
|
||||
#endif
|
||||
#ifdef ESRMNT
|
||||
[ESRMNT] = N_("Srmount error"),
|
||||
#endif
|
||||
#ifdef ECOMM
|
||||
[ECOMM] = N_("Communication error on send"),
|
||||
#endif
|
||||
#ifdef EPROTO
|
||||
[EPROTO] = N_("Protocol error"),
|
||||
#endif
|
||||
#ifdef EMULTIHOP
|
||||
[EMULTIHOP] = N_("Multihop attempted"),
|
||||
#endif
|
||||
#ifdef EDOTDOT
|
||||
[EDOTDOT] = N_("RFS specific error"),
|
||||
#endif
|
||||
#ifdef EBADMSG
|
||||
[EBADMSG] = N_("Not a data message"),
|
||||
#endif
|
||||
#ifdef EOVERFLOW
|
||||
[EOVERFLOW] = N_("Value too large for defined data type"),
|
||||
#endif
|
||||
#ifdef ENOTUNIQ
|
||||
[ENOTUNIQ] = N_("Name not unique on network"),
|
||||
#endif
|
||||
#ifdef EBADFD
|
||||
[EBADFD] = N_("File descriptor in bad state"),
|
||||
#endif
|
||||
#ifdef EREMCHG
|
||||
[EREMCHG] = N_("Remote address changed"),
|
||||
#endif
|
||||
#ifdef ELIBACC
|
||||
[ELIBACC] = N_("Can not access a needed shared library"),
|
||||
#endif
|
||||
#ifdef ELIBBAD
|
||||
[ELIBBAD] = N_("Accessing a corrupted shared library"),
|
||||
#endif
|
||||
#ifdef ELIBSCN
|
||||
[ELIBSCN] = N_(".lib section in a.out corrupted"),
|
||||
#endif
|
||||
#ifdef ELIBMAX
|
||||
[ELIBMAX] = N_("Attempting to link in too many shared libraries"),
|
||||
#endif
|
||||
#ifdef ELIBEXEC
|
||||
[ELIBEXEC] = N_("Cannot exec a shared library directly"),
|
||||
#endif
|
||||
#ifdef ESTRPIPE
|
||||
[ESTRPIPE] = N_("Streams pipe error"),
|
||||
#endif
|
||||
#ifdef EUCLEAN
|
||||
[EUCLEAN] = N_("Structure needs cleaning"),
|
||||
#endif
|
||||
#ifdef ENOTNAM
|
||||
[ENOTNAM] = N_("Not a XENIX named type file"),
|
||||
#endif
|
||||
#ifdef ENAVAIL
|
||||
[ENAVAIL] = N_("No XENIX semaphores available"),
|
||||
#endif
|
||||
#ifdef EISNAM
|
||||
[EISNAM] = N_("Is a named type file"),
|
||||
#endif
|
||||
#ifdef EREMOTEIO
|
||||
[EREMOTEIO] = N_("Remote I/O error"),
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
60
sysdeps/mach/libc-lock.h
Normal file
60
sysdeps/mach/libc-lock.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* libc-internal interface for mutex locks. Mach cthreads version.
|
||||
Copyright (C) 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
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _LIBC_LOCK_H
|
||||
#define _LIBC_LOCK_H 1
|
||||
|
||||
#ifdef _LIBC
|
||||
#include <cthreads.h>
|
||||
#define __libc_lock_t struct mutex
|
||||
#else
|
||||
typedef struct __libc_lock_opaque__ __libc_lock_t;
|
||||
#endif
|
||||
|
||||
/* Define a lock variable NAME with storage class CLASS. The lock must be
|
||||
initialized with __libc_lock_init before it can be used (or define it
|
||||
with __libc_lock_define_initialized, below). Use `extern' for CLASS to
|
||||
declare a lock defined in another module. In public structure
|
||||
definitions, the lock element must come last, because its storage size
|
||||
will not be known outside of libc. (Or you can use a pointer to the
|
||||
lock structure; i.e. NAME begins with a `*'.) */
|
||||
#define __libc_lock_define(CLASS,NAME)
|
||||
CLASS __libc_lock_t NAME;
|
||||
|
||||
/* Define an initialized lock variable NAME with storage class CLASS. */
|
||||
#define __libc_lock_define_initialized(CLASS,NAME) \
|
||||
CLASS __libc_lock_t NAME = MUTEX_INITIALIZER;
|
||||
|
||||
/* Initialize the named lock variable, leaving it in a consistent, unlocked
|
||||
state. */
|
||||
#define __libc_lock_init(NAME) __mutex_init (&(NAME))
|
||||
|
||||
/* Finalize the named lock variable, which must be locked. It cannot be
|
||||
used again until __libc_lock_init is called again on it. This must be
|
||||
called on a lock variable before the containing storage is reused. */
|
||||
#define __libc_lock_fini(NAME) __mutex_unlock (&(NAME))
|
||||
|
||||
/* Lock the named lock variable. */
|
||||
#define __libc_lock_lock(NAME) __mutex_lock (&(NAME))
|
||||
|
||||
/* Unlock the named lock variable. */
|
||||
#define __libc_lock_unlock(NAME) __mutex_unlock (&(NAME))
|
||||
|
||||
|
||||
#endif /* libc-lock.h */
|
@ -24,7 +24,10 @@ Cambridge, MA 02139, USA. */
|
||||
/* Define a lock variable NAME with storage class CLASS. The lock must be
|
||||
initialized with __libc_lock_init before it can be used (or define it
|
||||
with __libc_lock_define_initialized, below). Use `extern' for CLASS to
|
||||
declare a lock defined in another module. */
|
||||
declare a lock defined in another module. In public structure
|
||||
definitions, the lock element must come last, because its storage size
|
||||
will not be known outside of libc. (Or you can use a pointer to the
|
||||
lock structure; i.e. NAME begins with a `*'.) */
|
||||
#define __libc_lock_define(CLASS,NAME)
|
||||
|
||||
/* Define an initialized lock variable NAME with storage class CLASS. */
|
||||
@ -34,6 +37,11 @@ Cambridge, MA 02139, USA. */
|
||||
state. */
|
||||
#define __libc_lock_init(NAME)
|
||||
|
||||
/* Finalize the named lock variable, which must be locked. It cannot be
|
||||
used again until __libc_lock_init is called again on it. This must be
|
||||
called on a lock variable before the containing storage is reused. */
|
||||
#define __libc_lock_fini(NAME)
|
||||
|
||||
/* Lock the named lock variable. */
|
||||
#define __libc_lock_lock(NAME)
|
||||
|
||||
|
@ -36,6 +36,7 @@ struct record
|
||||
#define NBUCKETS 32
|
||||
static struct record *records[32];
|
||||
static off_t lastpos;
|
||||
__libc_lock_define_initialized(static, lock); /* Locks above data. */
|
||||
|
||||
|
||||
/* Return the current position of DIRP. */
|
||||
@ -43,6 +44,9 @@ off_t
|
||||
DEFUN(telldir, (dirp), DIR *dirp)
|
||||
{
|
||||
struct record *new;
|
||||
off_t pos;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new = malloc (sizeof *new);
|
||||
if (new == NULL)
|
||||
@ -54,7 +58,11 @@ DEFUN(telldir, (dirp), DIR *dirp)
|
||||
new->next = records[new->cookie % NBUCKETS];
|
||||
records[new->cookie % NBUCKETS] = new;
|
||||
|
||||
return new->cookie;
|
||||
pos = new->cookie;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
@ -65,11 +73,14 @@ DEFUN(seekdir, (dirp, pos), DIR *dirp AND __off_t pos)
|
||||
{
|
||||
struct record *r, **prevr;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
for (prevr = &records[pos % NBUCKETS], r = *prevr;
|
||||
r != NULL;
|
||||
prevr = &r->next, r = r->next)
|
||||
if (r->cookie == pos)
|
||||
{
|
||||
__libc_lock_lock (dirp->__lock);
|
||||
if (dirp->filepos != r->pos || dirp->offset != r->offset)
|
||||
{
|
||||
dirp->size = 0; /* Must read a fresh buffer. */
|
||||
@ -79,16 +90,25 @@ DEFUN(seekdir, (dirp, pos), DIR *dirp AND __off_t pos)
|
||||
dirp->offset = 0;
|
||||
/* Read entries until we reach the saved offset. */
|
||||
while (dirp->offset < r->offset)
|
||||
if (readdir (dirp) == NULL)
|
||||
break;
|
||||
{
|
||||
struct dirent *scan;
|
||||
__libc_lock_unlock (dirp->__lock);
|
||||
scan = readdir (dirp);
|
||||
__libc_lock_lock (dirp->__lock);
|
||||
if (! scan)
|
||||
break;
|
||||
}
|
||||
}
|
||||
__libc_lock_unlock (dirp->__lock);
|
||||
|
||||
/* To prevent leaking memory, cookies returned from telldir
|
||||
can only be used once. So free this one's record now. */
|
||||
*prevr = r->next;
|
||||
free (r);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We lost, but have no way to indicate it. Oh well. */
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
/* If we lost there is no way to indicate it. Oh well. */
|
||||
}
|
||||
|
@ -37,9 +37,13 @@ DEFUN(closedir, (dirp), DIR *dirp)
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = dirp->fd;
|
||||
__libc_lock_lock (dirp->lock);
|
||||
|
||||
fd = dirp->fd;
|
||||
free ((PTR) dirp->data);
|
||||
|
||||
__libc_lock_fini (dirp->lock);
|
||||
|
||||
free ((PTR) dirp);
|
||||
|
||||
return __close (fd);
|
||||
|
@ -22,6 +22,8 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <libc-lock.h>
|
||||
|
||||
/* Directory stream type.
|
||||
|
||||
The miscellaneous Unix `readdir' implementations read directory data
|
||||
@ -37,6 +39,8 @@ struct __dirstream
|
||||
size_t offset; /* Current offset into the block. */
|
||||
|
||||
off_t filepos; /* Position of next entry to read. */
|
||||
|
||||
__libc_lock_define (, lock); /* Mutex lock for this structure. */
|
||||
};
|
||||
|
||||
#define _DIR_dirfd(dirp) ((dirp)->fd)
|
||||
|
@ -90,5 +90,8 @@ opendir (const char *name)
|
||||
}
|
||||
|
||||
dirp->fd = fd;
|
||||
|
||||
__libc_lock_init (dirp->lock);
|
||||
|
||||
return dirp;
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ readdir (DIR *dirp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__libc_lock_lock (dirp->lock);
|
||||
|
||||
do
|
||||
{
|
||||
size_t reclen;
|
||||
@ -62,7 +64,10 @@ readdir (DIR *dirp)
|
||||
base = dirp->filepos;
|
||||
bytes = __getdirentries (dirp->fd, dirp->data, maxread, &base);
|
||||
if (bytes <= 0)
|
||||
return NULL;
|
||||
{
|
||||
dp = NULL;
|
||||
break;
|
||||
}
|
||||
dirp->size = (size_t) bytes;
|
||||
|
||||
/* Reset the offset into the buffer. */
|
||||
@ -96,5 +101,7 @@ readdir (DIR *dirp)
|
||||
/* Skip deleted files. */
|
||||
} while (dp->d_ino == 0);
|
||||
|
||||
__libc_lock_unlock (dirp->lock);
|
||||
|
||||
return dp;
|
||||
}
|
||||
|
@ -27,7 +27,9 @@ Cambridge, MA 02139, USA. */
|
||||
void
|
||||
DEFUN(rewinddir, (dirp), DIR *dirp)
|
||||
{
|
||||
__libc_lock_lock (dirp->lock);
|
||||
(void) lseek(dirp->fd, (off_t) 0, SEEK_SET);
|
||||
dirp->offset = 0;
|
||||
dirp->size = 0;
|
||||
__libc_lock_unlock (dirp->lock);
|
||||
}
|
||||
|
@ -27,7 +27,9 @@ Cambridge, MA 02139, USA. */
|
||||
void
|
||||
DEFUN(seekdir, (dirp, pos), DIR *dirp AND __off_t pos)
|
||||
{
|
||||
__libc_lock_lock (dirp->lock);
|
||||
(void) __lseek(dirp->fd, pos, SEEK_SET);
|
||||
dirp->size = 0;
|
||||
dirp->offset = 0;
|
||||
__libc_lock_unlock (dirp->lock);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user