From 27086d628e814b7b73a5c858ff2d9138c22d5543 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 11 Jan 2016 19:10:45 +0100 Subject: [PATCH] Fix previous fix for generating unique inode numbers for sockets * fhandler.h (fhandler_base::get_plain_ino): New inline method. Add comment to explain what it's supposed to be used for. * fhandler_socket.cc (fhandler_socket::get_proc_fd_name): Create filename using inode number. (fhandler_socket::fstat): Generate inode number from filename if ino is not set (that's the case in a stat(2) call). * pipe.cc: Throughout, use get_plain_ino when appropriate. Signed-off-by: Corinna Vinschen --- winsup/cygwin/fhandler.h | 2 ++ winsup/cygwin/fhandler_socket.cc | 6 ++++-- winsup/cygwin/pipe.cc | 12 ++++++------ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 8bcf83f0e..d94f38d98 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -304,6 +304,8 @@ class fhandler_base const char *get_name () const { return pc.get_posix (); } const char *get_win32_name () { return pc.get_win32 (); } virtual dev_t get_dev () { return get_device (); } + /* Use get_plain_ino if the caller needs to avoid hashing if ino is 0. */ + ino_t get_plain_ino () { return ino; } ino_t get_ino () { return ino ?: ino = hash_path_name (0, pc.get_nt_native_path ()); } int64_t get_unique_id () const { return unique_id; } /* Returns name used for /proc//fd in buf. */ diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 094cc65e8..7d3efad9b 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -250,7 +250,7 @@ fhandler_socket::~fhandler_socket () char * fhandler_socket::get_proc_fd_name (char *buf) { - __small_sprintf (buf, "socket:[%lu]", get_socket ()); + __small_sprintf (buf, "socket:[%lu]", get_plain_ino ()); return buf; } @@ -939,7 +939,9 @@ fhandler_socket::fstat (struct stat *buf) if (!res) { buf->st_dev = FHDEV (DEV_TCP_MAJOR, 0); - buf->st_ino = (ino_t) get_ino (); + if (!(buf->st_ino = get_plain_ino ())) + sscanf (get_name (), "/proc/%*d/fd/socket:[%lld]", + (long long *) &buf->st_ino); buf->st_mode = S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO; buf->st_size = 0; } diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 4ec4fa48e..4ccfef69c 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -142,7 +142,8 @@ fhandler_pipe::open (int flags, mode_t mode) __seterrno (); goto out; } - init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY, fh->get_ino ()); + init (nio_hdl, fh->get_access (), mode & O_TEXT ?: O_BINARY, + fh->get_plain_ino ()); cfree (fh); CloseHandle (proc); return 1; @@ -181,7 +182,7 @@ fhandler_pipe::ftruncate (off_t length, bool allow_truncate) char * fhandler_pipe::get_proc_fd_name (char *buf) { - __small_sprintf (buf, "pipe:[%D]", get_ino ()); + __small_sprintf (buf, "pipe:[%D]", get_plain_ino ()); return buf; } @@ -422,8 +423,7 @@ fhandler_pipe::fstat (struct stat *buf) if (!ret) { buf->st_dev = FH_PIPE; - /* Don't use get_ino, it doesn't return 0 but a hash instead. */ - if (!(buf->st_ino = get_unique_id ())) + if (!(buf->st_ino = get_plain_ino ())) sscanf (get_name (), "/proc/%*d/fd/pipe:[%lld]", (long long *) &buf->st_ino); } @@ -447,9 +447,9 @@ pipe_worker (int filedes[2], unsigned int psize, int mode) cygheap_fdnew fdin; cygheap_fdnew fdout (fdin, false); char buf[sizeof ("/dev/fd/pipe:[9223372036854775807]")]; - __small_sprintf (buf, "/dev/fd/pipe:[%D]", fhs[0]->get_ino ()); + __small_sprintf (buf, "/dev/fd/pipe:[%D]", fhs[0]->get_plain_ino ()); fhs[0]->pc.set_posix (buf); - __small_sprintf (buf, "pipe:[%D]", fhs[1]->get_ino ()); + __small_sprintf (buf, "pipe:[%D]", fhs[1]->get_plain_ino ()); fhs[1]->pc.set_posix (buf); fdin = fhs[0]; fdout = fhs[1];