diff options
author | as145665 <none@none> | 2006-09-22 10:36:59 -0700 |
---|---|---|
committer | as145665 <none@none> | 2006-09-22 10:36:59 -0700 |
commit | 014a7923f9b48f6ab3ba1a38049a3dacddc587cb (patch) | |
tree | 9e03bfae55370e119d4652490d36c3007957330b /usr/src | |
parent | 870619e96a055db0541d5a004fe75f07c2b4a988 (diff) | |
download | illumos-joyent-014a7923f9b48f6ab3ba1a38049a3dacddc587cb.tar.gz |
6459526 *rm* -r core dumps when attempting to remove a dir containing a hard link loop
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/rm/Makefile | 8 | ||||
-rw-r--r-- | usr/src/cmd/rm/rm.c | 35 |
2 files changed, 32 insertions, 11 deletions
diff --git a/usr/src/cmd/rm/Makefile b/usr/src/cmd/rm/Makefile index d1346e02d4..5bceb7cbbe 100644 --- a/usr/src/cmd/rm/Makefile +++ b/usr/src/cmd/rm/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,7 +21,7 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -34,6 +33,7 @@ include ../Makefile.cmd CFLAGS += $(CCVERBOSE) $(XPG4) := CFLAGS += -DXPG4 CPPFLAGS += -D_FILE_OFFSET_BITS=64 +LDLIBS += -lcmdutils .KEEP_STATE: diff --git a/usr/src/cmd/rm/rm.c b/usr/src/cmd/rm/rm.c index bbdbadf588..bd53d48b75 100644 --- a/usr/src/cmd/rm/rm.c +++ b/usr/src/cmd/rm/rm.c @@ -18,15 +18,15 @@ * * CDDL HEADER END */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -46,6 +46,8 @@ #include <stdlib.h> #include <errno.h> #include <sys/resource.h> +#include <sys/avl.h> +#include <libcmdutils.h> #define ARGCNT 5 /* Number of arguments */ #define CHILD 0 @@ -87,6 +89,7 @@ static rlim_t maxfiles; /* maximum number of open files */ static int first_dir = 1; /* flag set when first trying to remove a dir */ /* flag set when can't get dev/inode of a parent dir */ static int parent_err = 0; +static avl_tree_t *tree; /* tree to keep track of nodes visited */ struct dir_id { dev_t dev; @@ -168,10 +171,11 @@ main(int argc, char *argv[]) maxfiles = rl.rlim_cur - 2; while (argc-- > 0) { + tree = NULL; rm(*argv, 1); argv++; + destroy_tree(tree); } - cleanup(); return (errcode ? 2 : 0); /* NOTREACHED */ @@ -239,7 +243,6 @@ rm(char *path, int first) undir(path, first, buffer.st_dev, buffer.st_ino); return; } - filepath = get_filename(path); /* @@ -329,6 +332,7 @@ undir(char *path, int first, dev_t dev, ino_t ino) DIR *name; struct dirent *direct; int ismypath; + int ret; int chdir_failed = 0; size_t len; @@ -386,6 +390,25 @@ undir(char *path, int first, dev_t dev, ino_t ino) #endif /* + * Add this node to the search tree so we don't + * get into a endless loop. If the add fails then + * we have visited this node before. + */ + ret = add_tnode(&tree, dev, ino); + if (ret != 1) { + if (ret == 0) { + (void) fprintf(stderr, + gettext("rm: cycle detected for %s\n"), + fullpath); + } else if (ret == -1) { + perror("rm"); + } + errcode++; + pop_name(first); + return; + } + + /* * Open the directory for reading. */ if ((name = opendir(path)) == NULL) { @@ -718,7 +741,6 @@ static void pop_name(int first) { char *slash; - if (first) { *fullpath = '\0'; return; @@ -941,7 +963,6 @@ check_homedir(void) static void cleanup(void) { - struct dir_id *lastdir, *curdir; curdir = homedir.next; |