diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 5e298a82f..bd63933c2 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -3111,6 +3111,8 @@ class fhandler_mqueue: public fhandler_disk_file off_t filesize; off_t position; + bool valid_path (); + struct mq_info *_mqinfo (SIZE_T, mode_t, int, bool); struct mq_info *mqinfo_create (struct mq_attr *, mode_t, int); diff --git a/winsup/cygwin/fhandler_mqueue.cc b/winsup/cygwin/fhandler_mqueue.cc index 04a6c3611..f074474d7 100644 --- a/winsup/cygwin/fhandler_mqueue.cc +++ b/winsup/cygwin/fhandler_mqueue.cc @@ -34,9 +34,24 @@ fhandler_mqueue::~fhandler_mqueue () cfree (filebuf); } +bool +fhandler_mqueue::valid_path () +{ + const char *posix_basename = get_name () + MQ_LEN; + size_t len = strlen (posix_basename); + if (len > 0 && len <= NAME_MAX && !strpbrk (posix_basename, "/\\")) + return true; + return false; +} + int fhandler_mqueue::open (int flags, mode_t mode) { + if (!valid_path ()) + { + set_errno (EINVAL); + return 0; + } /* FIXME: reopen by handle semantics missing yet */ flags &= ~(O_NOCTTY | O_PATH | O_BINARY | O_TEXT); return mq_open (flags, mode, NULL); diff --git a/winsup/cygwin/mqueue_types.h b/winsup/cygwin/mqueue_types.h index 4d0d910e4..1e4fe127e 100644 --- a/winsup/cygwin/mqueue_types.h +++ b/winsup/cygwin/mqueue_types.h @@ -10,6 +10,9 @@ details. */ #define MQI_MAGIC 0x98765432UL +#define MQ_PATH "/dev/mqueue/" +#define MQ_LEN (sizeof (MQ_PATH) - 1) + /* The mq_attr structure is defined using long datatypes per POSIX. The mq_fattr is the in-file representation of the mq_attr struct. Originally created this way for 32/64 bit interoperability, this diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 53cdc282d..6a07f0d06 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1188,6 +1188,10 @@ path_conv::check (const char *src, unsigned opt, return; } + /* Restore last path component */ + if (tail < path_end && tail > path_copy + 1) + *tail = '/'; + if (dev.isfs ()) { /* If FS hasn't been checked already in symlink_info::check, @@ -1227,16 +1231,8 @@ path_conv::check (const char *src, unsigned opt, set_exec (0); /* FIXME: bad hack alert!!! We need a better solution */ - -#define MQ_PATH "/dev/mqueue/" -#define MQ_LEN (sizeof (MQ_PATH) - 1) - - if (!strncmp (src, MQ_PATH, MQ_LEN)) - { - size_t len = strlen (src + MQ_LEN); - if (len > 0 && len <= NAME_MAX && !strpbrk (src + MQ_LEN, "/\\")) - dev.parse (FH_MQUEUE); - } + if (!strncmp (path_copy, MQ_PATH, MQ_LEN) && path_copy[MQ_LEN]) + dev.parse (FH_MQUEUE); } if (opt & PC_NOFULL) @@ -1270,11 +1266,7 @@ path_conv::check (const char *src, unsigned opt, path_flags |= PATH_CTTY; if (opt & PC_POSIX) - { - if (tail < path_end && tail > path_copy + 1) - *tail = '/'; - set_posix (path_copy); - } + set_posix (path_copy); #if 0 if (!error)