Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Apr 1997 15:29:11 +0300 (EEST)
From:      tri@iki.fi
To:        FreeBSD-gnats-submit@freebsd.org
Cc:        tri-bcc@pooh.tky.hut.fi
Subject:   kern/3384: Bug in telldir-closedir-opendir-seekdir
Message-ID:  <199704251229.PAA01865@pooh.tky.hut.fi>
Resent-Message-ID: <199704251230.FAA11730@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         3384
>Category:       kern
>Synopsis:       telldir-seekdir can cause livelock
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 25 05:30:00 PDT 1997
>Last-Modified:
>Originator:     Timo J. Rinne
>Organization:
Helsinki University of Technology
>Release:        FreeBSD 3.0-CURRENT i386
>Environment:

	i386 - Pentium 3.0-current 970209 - 9704??

>Description:

	When traversing through directory structure like this pseudocode:

	traverse(d) {
            opendir(d)
            while(e = readdir(d))
                if (directory-p(e))
                    x = telldir(d)
                    closedir(d)
                    traverse(e)
                    opendir(d)
                    seekdir(d, x)
            closedir(d)
        }

	Restoring of the current directory after subtreetraversal
	causes the directory read to start from beginning leading
	to livelock.

>How-To-Repeat:

My colleague Jukka Partanen kindly provided a test program.  
Gets stuck when ran in directory with ordinary files and subdirectories.
Works in NetBSD and Linux, gets stuck in FreeBSD.

>Fix:
	
	Sorry.  No time to debug.  We use different OS in our
	production system.
>Audit-Trail:
>Unformatted:
>>>>>>>>>>>>>>>>>>   C U T   H E R E   >>>>>>>>>>>>>>>>>>

/*
 *
 * dirtest.c
 *
 * Author: Jukka Partanen <jukka.partanen@research.nokia.com>
 *
 * Copyright (c) 1997 Nokia Research Center
 * All rights reserved
 *
 * Created      : Thu Apr 24 14:53:03 1997 partanen
 * Last modified: Fri Apr 25 09:47:13 1997 partanen
 *
 * $Id$
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>

static int process_dir(int namelen);

static char file[PATH_MAX+1];

int main(int argc, char *argv[])
{
    char *name = argc > 1 ? argv[1] : ".";
    int   namelen;
    
    strcpy(file, name);
    namelen = strlen(file);
    if (namelen && file[namelen - 1] == '/')
        namelen--;
    return process_dir(namelen);
}

static int process_dir(int namelen)
{
    long dirpos;
    DIR *dirp;
    struct dirent *dp;
    struct stat statbuf;

    dirp = opendir(file);
    if (!dirp) {
        perror(file);
        return 1;
    }
    while ((dp = readdir(dirp)) != NULL) {
        file[namelen] = '/';
        strcpy(file + namelen + 1, dp->d_name);
        if (stat(file, &statbuf) < 0) {
            perror(file);
        } else {
            printf("%s\n", file);
            if ((statbuf.st_mode & S_IFDIR) &&
                strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
                dirpos = telldir(dirp);
                closedir(dirp);
                process_dir(namelen + strlen(dp->d_name) + 1);
                file[namelen] = '\0';
                dirp = opendir(file);
                if (!dirp) {
                    perror(file);
                    return 1;
                }
                seekdir(dirp, dirpos);
            }
        }
        file[namelen] = '\0';
    }
    closedir(dirp);
    return 0;
}

>>>>>>>>>>>>>>>>>>   C U T   H E R E   >>>>>>>>>>>>>>>>>>




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199704251229.PAA01865>