summaryrefslogtreecommitdiff
path: root/usr/src/cmd/du
diff options
context:
space:
mode:
authorceastha <none@none>2007-07-05 10:52:11 -0700
committerceastha <none@none>2007-07-05 10:52:11 -0700
commit15deec582ef80846f1c88f9f61d26d8dbb992894 (patch)
treeb72e81007959defe2d76388d0ca4e1d6c857b6b9 /usr/src/cmd/du
parent7bda858a12915db1d90b1320ff735ad2a56830ae (diff)
downloadillumos-joyent-15deec582ef80846f1c88f9f61d26d8dbb992894.tar.gz
6575513 /bin/du -d in Solaris 10 hangs in pathconf on a symlink on stale NFS mount
Diffstat (limited to 'usr/src/cmd/du')
-rw-r--r--usr/src/cmd/du/du.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/usr/src/cmd/du/du.c b/usr/src/cmd/du/du.c
index df5b45b878..4307eadf8a 100644
--- a/usr/src/cmd/du/du.c
+++ b/usr/src/cmd/du/du.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -281,6 +281,7 @@ descend(char *curname, int curfd, int *retcode, dev_t device)
char *ebase0, *ebase;
struct stat stb, stb1;
int i, j, ret, fd, tmpflg;
+ int follow_symlinks;
blkcnt_t blocks = 0;
off_t curoff = 0;
ptrdiff_t offset;
@@ -303,10 +304,8 @@ descend(char *curname, int curfd, int *retcode, dev_t device)
* If a -H was specified, don't follow symlinks if the file is
* not a command line argument.
*/
- if (((Lflg == 0) && (Hflg == 0)) || ((Hflg) && !(cmdarg))) {
- i = fstatat(curfd, curname, &stb, AT_SYMLINK_NOFOLLOW);
- j = 0;
- } else {
+ follow_symlinks = (Lflg || (Hflg && cmdarg));
+ if (follow_symlinks) {
i = fstatat(curfd, curname, &stb, 0);
j = fstatat(curfd, curname, &stb1, AT_SYMLINK_NOFOLLOW);
@@ -317,6 +316,9 @@ descend(char *curname, int curfd, int *retcode, dev_t device)
if (Hflg) {
cmdarg = 0;
}
+ } else {
+ i = fstatat(curfd, curname, &stb, AT_SYMLINK_NOFOLLOW);
+ j = 0;
}
if ((i < 0) || (j < 0)) {
@@ -355,7 +357,7 @@ descend(char *curname, int curfd, int *retcode, dev_t device)
* symbolic link, we need to keep track of all inodes when -L
* is specified.
*/
- if ((Lflg) || ((stb.st_mode & S_IFMT) == S_IFDIR) ||
+ if (Lflg || ((stb.st_mode & S_IFMT) == S_IFDIR) ||
(stb.st_nlink > 1)) {
int rc;
if ((rc = add_tnode(&tree, stb.st_dev, stb.st_ino)) != 1) {
@@ -380,9 +382,13 @@ descend(char *curname, int curfd, int *retcode, dev_t device)
blocks = stb.st_blocks;
/*
* If there are extended attributes on the current file, add their
- * block usage onto the block count.
+ * block usage onto the block count. Note: Since pathconf() always
+ * follows symlinks, only test for extended attributes using pathconf()
+ * if we are following symlinks or the current file is not a symlink.
*/
- if (curname && pathconf(curname, _PC_XATTR_EXISTS) == 1) {
+ if (curname && (follow_symlinks ||
+ ((stb.st_mode & S_IFMT) != S_IFLNK)) &&
+ pathconf(curname, _PC_XATTR_EXISTS) == 1) {
if ((fd = attropen(curname, ".", O_RDONLY)) < 0) {
if (rflg)
perror(gettext(