From owner-freebsd-bugs Fri Apr 25 05:30:04 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id FAA11740 for bugs-outgoing; Fri, 25 Apr 1997 05:30:04 -0700 (PDT) Received: (from gnats@localhost) by hub.freebsd.org (8.8.5/8.8.5) id FAA11730; Fri, 25 Apr 1997 05:30:02 -0700 (PDT) Resent-Date: Fri, 25 Apr 1997 05:30:02 -0700 (PDT) Resent-Message-Id: <199704251230.FAA11730@hub.freebsd.org> Resent-From: gnats (GNATS Management) Resent-To: freebsd-bugs Resent-Reply-To: FreeBSD-gnats@freefall.FreeBSD.org, tri@iki.fi Received: from vipunen.hut.fi (root@vipunen.hut.fi [130.233.224.20]) by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id FAA11656 for ; Fri, 25 Apr 1997 05:29:20 -0700 (PDT) Received: from pooh.tky.hut.fi (pooh.tky.hut.fi [130.233.23.135]) by vipunen.hut.fi (8.8.5/8.8.2) with ESMTP id PAA125394 for ; Fri, 25 Apr 1997 15:29:12 +0300 Received: by pooh.tky.hut.fi (PAA01865); Fri, 25 Apr 1997 15:29:11 +0300 (EEST) Message-Id: <199704251229.PAA01865@pooh.tky.hut.fi> Date: Fri, 25 Apr 1997 15:29:11 +0300 (EEST) From: tri@iki.fi Reply-To: tri@iki.fi To: FreeBSD-gnats-submit@freebsd.org Cc: tri-bcc@pooh.tky.hut.fi X-Send-Pr-Version: 3.2 Subject: kern/3384: Bug in telldir-closedir-opendir-seekdir Sender: owner-bugs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk >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 * * 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 #include #include #include #include #include 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 >>>>>>>>>>>>>>>>>>