From owner-freebsd-bugs@FreeBSD.ORG Tue Feb 24 09:57:40 2009 Return-Path: Delivered-To: freebsd-bugs@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E7D1B106564A; Tue, 24 Feb 2009 09:57:40 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from fallbackmx06.syd.optusnet.com.au (fallbackmx06.syd.optusnet.com.au [211.29.132.8]) by mx1.freebsd.org (Postfix) with ESMTP id 8935B8FC23; Tue, 24 Feb 2009 09:57:39 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail09.syd.optusnet.com.au (mail09.syd.optusnet.com.au [211.29.132.190]) by fallbackmx06.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id n1O6JNXP007939; Tue, 24 Feb 2009 17:19:23 +1100 Received: from c122-107-120-227.carlnfd1.nsw.optusnet.com.au (c122-107-120-227.carlnfd1.nsw.optusnet.com.au [122.107.120.227]) by mail09.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id n1O6JH4e022471 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 24 Feb 2009 17:19:20 +1100 Date: Tue, 24 Feb 2009 17:19:17 +1100 (EST) From: Bruce Evans X-X-Sender: bde@delplex.bde.org To: Deomid Ryabkov In-Reply-To: <200902230725.n1N7PQN7023379@www.freebsd.org> Message-ID: <20090224170808.K10627@delplex.bde.org> References: <200902230725.n1N7PQN7023379@www.freebsd.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-bugs@freebsd.org, freebsd-gnats-submit@freebsd.org Subject: Re: misc/131999: chflags: unable to unset flags on symlinks when link target exists X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Feb 2009 09:57:41 -0000 On Mon, 23 Feb 2009, Deomid Ryabkov wrote: >> Synopsis: chflags: unable to unset flags on symlinks when link target exists Also, setting only works accidentally in some cases. > truss of chflags reveals the problem: usage of stat() where lstat() should have been used. > > # truss chflags -h noschg logs > [...] > stat("logs",{ mode=drwxr-x--- ,inode=22303757,size=512,blksize=4096 }) = 0 (0x0) > process exit, rval = 0 > > this way, lchflags(2) is never actually called because chflags(3) doesn't think it is necessary. And for chflags -h schg logs, lchflags() is only called because the wrong flags returned by stat() happen to have their schg bit clear. If the schg bit were set in the symlink target, then this chflags would do nothing too. >> Fix: > i had a glance at bin/chflags/chflags.c and it seems to be using fts_* functions to traverse the tree. somehow those need to be told to use lstat to return information, when appropriate. Setting FTS_PHYSICAL seems to fix it: % Index: chflags.c % =================================================================== % RCS file: /home/ncvs/src/bin/chflags/chflags.c,v % retrieving revision 1.24 % diff -u -2 -r1.24 chflags.c % --- chflags.c 9 Mar 2008 12:10:24 -0000 1.24 % +++ chflags.c 24 Feb 2009 06:13:00 -0000 % @@ -115,5 +115,7 @@ % fts_options |= FTS_LOGICAL; % } % - } else % + } else if (hflag) % + fts_options = FTS_PHYSICAL; % + else % fts_options = FTS_LOGICAL; % Bruce