Following the logic of the binutils change upstream (the addition of the new unlink_if_ordinary() function), we update collect2 so that it will only unlink files if they are 'ordinary' (in other words, a regular file or a symlink). This allows us to do fun things like `gcc test.c -o /dev/null` and not have to worry about the toolchain doing unlink(/dev/null) on us (cause that sucks huge wang). For example, this is common on a parisc/mips machine: # gcc test.c -o /dev/null /usr/hppa2.0-unknown-linux-gnu/bin/ld: final link failed: Nonrepresentable section on output collect2: ld returned 1 exit status # ls /dev/null ls: /dev/null: No such file or directory http://bugs.gentoo.org/show_bug.cgi?id=79836 --- gcc/gcc/collect2.c +++ gcc/gcc/collect2.c @@ -34,6 +34,12 @@ #if ! defined( SIGCHLD ) && defined( SIGCLD ) # define SIGCHLD SIGCLD #endif +#ifdef HAVE_UNISTD_H +#include +#endif +#if HAVE_SYS_STAT_H +#include +#endif #ifdef vfork /* Autoconf may define this to fork for us. */ # define VFORK_STRING "fork" @@ -1574,14 +1603,24 @@ do_wait (prog); } -/* Unlink a file unless we are debugging. */ - +/* Unlink a file unless we are debugging or file is not normal. */ +#ifndef S_ISLNK +#ifdef S_IFLNK +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#else +#define S_ISLNK(m) 0 +#define lstat stat +#endif +#endif static void maybe_unlink (const char *file) { - if (!debug) - unlink (file); - else + if (!debug) { + struct stat st; + if (lstat (file, &st) == 0 + && (S_ISREG (st.st_mode) || S_ISLNK (st.st_mode))) + unlink (file); + } else notice ("[Leaving %s]\n", file); }