11573Srgrimes/* 21573Srgrimes * Copyright (c) 1983, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 4. Neither the name of the University nor the names of its contributors 141573Srgrimes * may be used to endorse or promote products derived from this software 151573Srgrimes * without specific prior written permission. 161573Srgrimes * 171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271573Srgrimes * SUCH DAMAGE. 281573Srgrimes */ 291573Srgrimes 301573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 311573Srgrimesstatic char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93"; 321573Srgrimes#endif /* LIBC_SCCS and not lint */ 3390039Sobrien#include <sys/cdefs.h> 3490039Sobrien__FBSDID("$FreeBSD$"); 351573Srgrimes 3671579Sdeischen#include "namespace.h" 371573Srgrimes#include <sys/param.h> 3869841Sdeischen#include <sys/queue.h> 391573Srgrimes#include <dirent.h> 4071579Sdeischen#include <pthread.h> 411573Srgrimes#include <stdlib.h> 421573Srgrimes#include <unistd.h> 4371579Sdeischen#include "un-namespace.h" 441573Srgrimes 4571579Sdeischen#include "libc_private.h" 46235647Sgleb#include "gen-private.h" 4769841Sdeischen#include "telldir.h" 4869841Sdeischen 491573Srgrimes/* 501573Srgrimes * return a pointer into a directory 511573Srgrimes */ 521573Srgrimeslong 531573Srgrimestelldir(dirp) 5469656Sdeischen DIR *dirp; 551573Srgrimes{ 5669841Sdeischen struct ddloc *lp; 57270002Sjhb long idx; 581573Srgrimes 5971579Sdeischen if (__isthreaded) 60174221Sdes _pthread_mutex_lock(&dirp->dd_lock); 61270002Sjhb LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { 62270002Sjhb if (lp->loc_seek == dirp->dd_seek && 63270002Sjhb lp->loc_loc == dirp->dd_loc) 64270002Sjhb break; 65270002Sjhb } 66270002Sjhb if (lp == NULL) { 67270002Sjhb lp = malloc(sizeof(struct ddloc)); 68270002Sjhb if (lp == NULL) { 69270002Sjhb if (__isthreaded) 70270002Sjhb _pthread_mutex_unlock(&dirp->dd_lock); 71270002Sjhb return (-1); 72270002Sjhb } 73270002Sjhb lp->loc_index = dirp->dd_td->td_loccnt++; 74270002Sjhb lp->loc_seek = dirp->dd_seek; 75270002Sjhb lp->loc_loc = dirp->dd_loc; 76270002Sjhb LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe); 77270002Sjhb } 78270002Sjhb idx = lp->loc_index; 7971579Sdeischen if (__isthreaded) 80174221Sdes _pthread_mutex_unlock(&dirp->dd_lock); 81270002Sjhb return (idx); 821573Srgrimes} 831573Srgrimes 841573Srgrimes/* 851573Srgrimes * seek to an entry in a directory. 861573Srgrimes * Only values returned by "telldir" should be passed to seekdir. 871573Srgrimes */ 881573Srgrimesvoid 891573Srgrimes_seekdir(dirp, loc) 9069656Sdeischen DIR *dirp; 911573Srgrimes long loc; 921573Srgrimes{ 9369841Sdeischen struct ddloc *lp; 941573Srgrimes struct dirent *dp; 951573Srgrimes 9669841Sdeischen LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { 971573Srgrimes if (lp->loc_index == loc) 981573Srgrimes break; 991573Srgrimes } 1001573Srgrimes if (lp == NULL) 1011573Srgrimes return; 1021573Srgrimes if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek) 103270002Sjhb return; 1041573Srgrimes (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET); 1051573Srgrimes dirp->dd_seek = lp->loc_seek; 1061573Srgrimes dirp->dd_loc = 0; 1071573Srgrimes while (dirp->dd_loc < lp->loc_loc) { 108178772Skib dp = _readdir_unlocked(dirp, 0); 1091573Srgrimes if (dp == NULL) 1101573Srgrimes break; 1111573Srgrimes } 1121573Srgrimes} 1135958Sdfr 1145958Sdfr/* 1155958Sdfr * Reclaim memory for telldir cookies which weren't used. 1165958Sdfr */ 1175958Sdfrvoid 1185958Sdfr_reclaim_telldir(dirp) 11969656Sdeischen DIR *dirp; 1205958Sdfr{ 12169841Sdeischen struct ddloc *lp; 12269841Sdeischen struct ddloc *templp; 1235958Sdfr 12469841Sdeischen lp = LIST_FIRST(&dirp->dd_td->td_locq); 12569656Sdeischen while (lp != NULL) { 12669656Sdeischen templp = lp; 12769656Sdeischen lp = LIST_NEXT(lp, loc_lqe); 12869656Sdeischen free(templp); 1295958Sdfr } 13069841Sdeischen LIST_INIT(&dirp->dd_td->td_locq); 1315958Sdfr} 132