From nobody@FreeBSD.org Fri Aug 25 18:43:56 2006 Return-Path: Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 642B616A4DA for ; Fri, 25 Aug 2006 18:43:56 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id AB9E143D6D for ; Fri, 25 Aug 2006 18:43:55 +0000 (GMT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k7PIhtgF092958 for ; Fri, 25 Aug 2006 18:43:55 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id k7PIhtBo092957; Fri, 25 Aug 2006 18:43:55 GMT (envelope-from nobody) Message-Id: <200608251843.k7PIhtBo092957@www.freebsd.org> Date: Fri, 25 Aug 2006 18:43:55 GMT From: Jin Guojun To: freebsd-gnats-submit@FreeBSD.org Subject: diff should not follow symlink in recursive (-r) mode X-Send-Pr-Version: www-2.3 >Number: 102510 >Category: bin >Synopsis: [patch] diff(1) should not follow symlink in recursive (-r) mode >Confidential: no >Severity: serious >Priority: medium >Responsible: edwin >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Aug 25 18:50:18 GMT 2006 >Closed-Date: Tue Aug 05 08:55:09 UTC 2008 >Last-Modified: Tue Aug 05 08:55:09 UTC 2008 >Originator: Jin Guojun >Release: All FreeBSD release >Organization: >Environment: Non hardware related issue >Description: /usr/bin/diff should not follow symlink in recursive mode (with option "-r"). Where "-r" option is used to compare two structures/trees, where one of them is a mirror or duplication of the other. It is not clear what is the historical reason "diff -r" follows symlink in this mode. It is hardly to see "diff -r" may be used to compare two completely different file structure or trees. Therefore, to compare two same/similar file trees, there is no any good reason to follow the symlink for diffing. If the node at the end of the link exists, it will be compared eventually anyway. If the symlink points to nowhere, then there is no meaning to follow it. It wastes time to follow symlink to do number of extra comparisons. Also, if user(s) create some long-multi-path links between directories/trees, diff -r will loop forever (no infinit, but may take a day) in comparing such file trees. >How-To-Repeat: I have send a simple example to hackers for comment, but have not heard any feedback. It can be found in mailing archive. The real problem on a large file tree/structure may take time to debug. However, it is not hard to see the problem through above description. A patch is provide to disable the feature of following symlink in "-r" mode. Since the patch is copy/pasted, it may not be directly applied via "patch", but it is very simple (tree line added, and one line changed), so manually apply it is easy. When I receive the reply,I will send the patch in via email if people agree this patch. If for some reason following symlink is needed in "-r" mode, then a switch (option) can be added for such purpose to enable following symlink feature in "-r" recursive mode. >Fix: *** /usr/src/contrib/diff/diff.c.orig Tue Aug 15 14:05:30 2006 --- /usr/src/contrib/diff/diff.c Tue Aug 15 14:04:45 2006 *************** *** 832,837 **** --- 832,840 ---- /* other popular file types */ /* S_ISLNK is impossible with `fstat' and `stat'. */ + #ifdef S_ISLNK + if (S_ISLNK (st->st_mode)) return "symlink"; + #endif #ifdef S_ISSOCK if (S_ISSOCK (st->st_mode)) return "socket"; #endif *************** *** 927,933 **** } } else ! stat_result = stat (inf[i].name, &inf[i].stat); if (stat_result != 0) { --- 930,936 ---- } } else ! stat_result = (recursive ? lstat : stat) (inf[i].name, &inf[i].stat) ; if (stat_result != 0) { >Release-Note: >Audit-Trail: Responsible-Changed-From-To: freebsd-bugs->edwin Responsible-Changed-By: edwin Responsible-Changed-When: Mon Aug 4 12:22:38 UTC 2008 Responsible-Changed-Why: Handle with mentor. http://www.freebsd.org/cgi/query-pr.cgi?pr=102510 State-Changed-From-To: open->closed State-Changed-By: edwin State-Changed-When: Tue Aug 5 08:52:11 UTC 2008 State-Changed-Why: The POSIX standard doesn't say anything about symlinks, it only talks about text-files, directories and FIFO and block files. The rest of the files are "The behavior of diff on other file types is implementation-defined when found in directories." We can't make the behaviour of diff different from the behaviour of diff on other platforms. Since we are using the GNU diff, I suggest you talk to them to change the behaviour (but I am afraid they will tell you the same story as I did). http://www.freebsd.org/cgi/query-pr.cgi?pr=102510 >Unformatted: