mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-09 02:40:08 +00:00
c150923988
* 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.
115 lines
2.9 KiB
C
115 lines
2.9 KiB
C
/* Copyright (C) 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
|
||
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. */
|
||
|
||
#include <ansidecl.h>
|
||
#include <errno.h>
|
||
#include <stddef.h>
|
||
#include <dirent.h>
|
||
#include <unistd.h>
|
||
#include <sys/types.h>
|
||
#include <stdlib.h>
|
||
#include "dirstream.h"
|
||
|
||
/* Internal data structure for telldir and seekdir. */
|
||
struct record
|
||
{
|
||
struct record *next; /* Link in chain. */
|
||
off_t cookie; /* Value returned by `telldir'. */
|
||
off_t pos;
|
||
size_t offset;
|
||
};
|
||
#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. */
|
||
off_t
|
||
DEFUN(telldir, (dirp), DIR *dirp)
|
||
{
|
||
struct record *new;
|
||
off_t pos;
|
||
|
||
__libc_lock_lock (lock);
|
||
|
||
new = malloc (sizeof *new);
|
||
if (new == NULL)
|
||
return (off_t) -1;
|
||
|
||
new->pos = dirp->filepos;
|
||
new->offset = dirp->offset;
|
||
new->cookie = ++lastpos;
|
||
new->next = records[new->cookie % NBUCKETS];
|
||
records[new->cookie % NBUCKETS] = new;
|
||
|
||
pos = new->cookie;
|
||
|
||
__libc_lock_unlock (lock);
|
||
|
||
return pos;
|
||
}
|
||
|
||
|
||
|
||
/* Seek to position POS in DIRP. */
|
||
void
|
||
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. */
|
||
/* Move to the saved position. */
|
||
__lseek (dirp->fd, r->pos, SEEK_SET);
|
||
dirp->filepos = r->pos;
|
||
dirp->offset = 0;
|
||
/* Read entries until we reach the saved offset. */
|
||
while (dirp->offset < r->offset)
|
||
{
|
||
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);
|
||
break;
|
||
}
|
||
|
||
__libc_lock_unlock (lock);
|
||
|
||
/* If we lost there is no way to indicate it. Oh well. */
|
||
}
|