1  /* Copyright (C) 2004-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <mqueue.h>
      20  #include <stdarg.h>
      21  #include <stddef.h>
      22  #include <stdio.h>
      23  #include <sysdep.h>
      24  #include <shlib-compat.h>
      25  
      26  /* Establish connection between a process and a message queue NAME and
      27     return message queue descriptor or (mqd_t) -1 on error.  OFLAG determines
      28     the type of access used.  If O_CREAT is on OFLAG, the third argument is
      29     taken as a `mode_t', the mode of the created message queue, and the fourth
      30     argument is taken as `struct mq_attr *', pointer to message queue
      31     attributes.  If the fourth argument is NULL, default attributes are
      32     used.  */
      33  mqd_t
      34  __mq_open (const char *name, int oflag, ...)
      35  {
      36    if (name[0] != '/')
      37      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
      38  
      39    mode_t mode = 0;
      40    struct mq_attr *attr = NULL;
      41    if (oflag & O_CREAT)
      42      {
      43        va_list ap;
      44  
      45        va_start (ap, oflag);
      46        mode = va_arg (ap, mode_t);
      47        attr = va_arg (ap, struct mq_attr *);
      48        va_end (ap);
      49      }
      50  
      51    return INLINE_SYSCALL (mq_open, 4, name + 1, oflag, mode, attr);
      52  }
      53  versioned_symbol (libc, __mq_open, mq_open, GLIBC_2_34);
      54  #if OTHER_SHLIB_COMPAT (librt, GLIBC_2_3_4, GLIBC_2_34)
      55  compat_symbol (libc, __mq_open, mq_open, GLIBC_2_3_4);
      56  #endif
      57  
      58  mqd_t
      59  ___mq_open_2 (const char *name, int oflag)
      60  {
      61    if (oflag & O_CREAT)
      62      __fortify_fail ("invalid mq_open call: O_CREAT without mode and attr");
      63  
      64    return __mq_open (name, oflag);
      65  }
      66  versioned_symbol (libc, ___mq_open_2, __mq_open_2, GLIBC_2_34);
      67  #if OTHER_SHLIB_COMPAT (librt, GLIBC_2_7, GLIBC_2_34)
      68  compat_symbol (libc, ___mq_open_2, __mq_open_2, GLIBC_2_7);
      69  #endif