telldir.c revision 69841
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 * 3. All advertising materials mentioning features or use of this software 141573Srgrimes * must display the following acknowledgement: 151573Srgrimes * This product includes software developed by the University of 161573Srgrimes * California, Berkeley and its contributors. 171573Srgrimes * 4. Neither the name of the University nor the names of its contributors 181573Srgrimes * may be used to endorse or promote products derived from this software 191573Srgrimes * without specific prior written permission. 201573Srgrimes * 211573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311573Srgrimes * SUCH DAMAGE. 3269656Sdeischen * 3369656Sdeischen * $FreeBSD: head/lib/libc/gen/telldir.c 69841 2000-12-11 04:00:36Z deischen $ 341573Srgrimes */ 351573Srgrimes 361573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 371573Srgrimesstatic char sccsid[] = "@(#)telldir.c 8.1 (Berkeley) 6/4/93"; 381573Srgrimes#endif /* LIBC_SCCS and not lint */ 391573Srgrimes 401573Srgrimes#include <sys/param.h> 4169841Sdeischen#include <sys/queue.h> 421573Srgrimes#include <dirent.h> 431573Srgrimes#include <stdlib.h> 441573Srgrimes#include <unistd.h> 451573Srgrimes 4669841Sdeischen#include "telldir.h" 4769841Sdeischen 481573Srgrimes/* 491573Srgrimes * The option SINGLEUSE may be defined to say that a telldir 501573Srgrimes * cookie may be used only once before it is freed. This option 511573Srgrimes * is used to avoid having memory usage grow without bound. 521573Srgrimes */ 531573Srgrimes#define SINGLEUSE 541573Srgrimes 551573Srgrimes/* 561573Srgrimes * return a pointer into a directory 571573Srgrimes */ 581573Srgrimeslong 591573Srgrimestelldir(dirp) 6069656Sdeischen DIR *dirp; 611573Srgrimes{ 6269841Sdeischen struct ddloc *lp; 631573Srgrimes 6469841Sdeischen if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL) 651573Srgrimes return (-1); 6669841Sdeischen lp->loc_index = dirp->dd_td->td_loccnt++; 671573Srgrimes lp->loc_seek = dirp->dd_seek; 681573Srgrimes lp->loc_loc = dirp->dd_loc; 6969841Sdeischen LIST_INSERT_HEAD(&dirp->dd_td->td_locq, lp, loc_lqe); 7069656Sdeischen return (lp->loc_index); 711573Srgrimes} 721573Srgrimes 731573Srgrimes/* 741573Srgrimes * seek to an entry in a directory. 751573Srgrimes * Only values returned by "telldir" should be passed to seekdir. 761573Srgrimes */ 771573Srgrimesvoid 781573Srgrimes_seekdir(dirp, loc) 7969656Sdeischen DIR *dirp; 801573Srgrimes long loc; 811573Srgrimes{ 8269841Sdeischen struct ddloc *lp; 831573Srgrimes struct dirent *dp; 841573Srgrimes 8569841Sdeischen LIST_FOREACH(lp, &dirp->dd_td->td_locq, loc_lqe) { 861573Srgrimes if (lp->loc_index == loc) 871573Srgrimes break; 881573Srgrimes } 891573Srgrimes if (lp == NULL) 901573Srgrimes return; 911573Srgrimes if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek) 921573Srgrimes goto found; 931573Srgrimes (void) lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET); 941573Srgrimes dirp->dd_seek = lp->loc_seek; 951573Srgrimes dirp->dd_loc = 0; 961573Srgrimes while (dirp->dd_loc < lp->loc_loc) { 971573Srgrimes dp = readdir(dirp); 981573Srgrimes if (dp == NULL) 991573Srgrimes break; 1001573Srgrimes } 1011573Srgrimesfound: 1021573Srgrimes#ifdef SINGLEUSE 10369656Sdeischen LIST_REMOVE(lp, loc_lqe); 1041573Srgrimes free((caddr_t)lp); 1051573Srgrimes#endif 1061573Srgrimes} 1075958Sdfr 1085958Sdfr/* 1095958Sdfr * Reclaim memory for telldir cookies which weren't used. 1105958Sdfr */ 1115958Sdfrvoid 1125958Sdfr_reclaim_telldir(dirp) 11369656Sdeischen DIR *dirp; 1145958Sdfr{ 11569841Sdeischen struct ddloc *lp; 11669841Sdeischen struct ddloc *templp; 1175958Sdfr 11869841Sdeischen lp = LIST_FIRST(&dirp->dd_td->td_locq); 11969656Sdeischen while (lp != NULL) { 12069656Sdeischen templp = lp; 12169656Sdeischen lp = LIST_NEXT(lp, loc_lqe); 12269656Sdeischen free(templp); 1235958Sdfr } 12469841Sdeischen LIST_INIT(&dirp->dd_td->td_locq); 1255958Sdfr} 126