From 52dba6a5c45e8d8ba1e237a15213311dc11d91fb Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 26 Sep 2009 15:51:53 +0000 Subject: Fix some POSIX-compliance bugs in link, rename, mkdir. * syscalls.cc (link): Delete obsolete comment. Reject directories and missing source up front. (rename): Use correct errno for trailing '.'. Detect empty strings. Allow trailing slash to newpath iff oldpath is directory. * dir.cc (mkdir): Reject dangling symlink with trailing slash. * fhandler_disk_file.cc (fhandler_disk_file::link): Reject trailing slash. * fhandler.cc (fhandler_base::link): Match Linux errno. --- winsup/cygwin/dir.cc | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'winsup/cygwin/dir.cc') diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 2b9125f0b..4bca40cec 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -1,6 +1,7 @@ /* dir.cc: Posix directory-related routines - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2006, 2007 Red Hat, Inc. + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2006, 2007, + 2008, 2009 Red Hat, Inc. This file is part of Cygwin. @@ -21,6 +22,7 @@ details. */ #include "dtable.h" #include "cygheap.h" #include "cygtls.h" +#include "tls_pbuf.h" extern "C" int dirfd (DIR *dir) @@ -273,11 +275,30 @@ mkdir (const char *dir, mode_t mode) { int res = -1; fhandler_base *fh = NULL; + tmp_pathbuf tp; myfault efault; if (efault.faulted (EFAULT)) return -1; + /* POSIX says mkdir("symlink-to-missing/") should create the + directory "missing", but Linux rejects it with EEXIST. Copy + Linux behavior for now. */ + + if (!*dir) + { + set_errno (ENOENT); + goto done; + } + if (isdirsep (dir[strlen (dir) - 1])) + { + /* This converts // to /, but since both give EEXIST, we're okay. */ + char *buf; + char *p = stpcpy (buf = tp.c_get (), dir) - 1; + dir = buf; + while (p > dir && isdirsep (*p)) + *p-- = '\0'; + } if (!(fh = build_fh_name (dir, NULL, PC_SYM_NOFOLLOW))) goto done; /* errno already set */; -- cgit v1.2.3