2004-04-08  Ulrich Drepper  <drepper@redhat.com>

	* rt/tst-mqueue3.c: New file.
	* rt/Makefile (tests): Add tst-mqueue3.

2004-04-08  Jakub Jelinek  <jakub@redhat.com>

	* rt/tst-mqueue1.c: New file.
	* rt/tst-mqueue2.c: New file.
	* rt/tst-mqueue4.c: New file.
	* rt/Makefile (tests): Add tst-mqueue1, tst-mqueue2, tst-mqueue4.

	* rt/Versions (librt): Add mq_*@@GLIBC_2.3.4.
	* rt/Makefile (headers): Add mqueue.h and bits/mqueue.h.
	(mq-routines): Set.
	(librt-routines): Use it.
	* rt/mqueue.h: New file.
	* include/mqueue.h: New file.
	* sysdeps/generic/bits/mqueue.h: New file.
	* sysdeps/generic/mq_setattr.c: New file.
	* sysdeps/generic/mq_getattr.c: New file.
	* sysdeps/generic/mq_notify.c: New file.
	* sysdeps/generic/mq_close.c: New file.
	* sysdeps/generic/mq_send.c: New file.
	* sysdeps/generic/mq_unlink.c: New file.
	* sysdeps/generic/mq_receive.c: New file.
	* sysdeps/generic/mq_timedreceive.c: New file.
	* sysdeps/generic/mq_timedsend.c: New file.
	* sysdeps/generic/mq_open.c: New file.
	* sysdeps/unix/sysv/linux/bits/local_lim.h (MQ_PRIO_MAX): Define.
	* sysdeps/unix/sysv/linux/bits/mqueue.h: New file.
	* sysdeps/unix/sysv/linux/syscalls.list: Add mq_timedsend,
	mq_timedreceive and mq_setattr.
	* sysdeps/unix/sysv/linux/mq_getattr.c: New file.
	* sysdeps/unix/sysv/linux/mq_notify.c: New file.
	* sysdeps/unix/sysv/linux/mq_close.c: New file.
	* sysdeps/unix/sysv/linux/mq_send.c: New file.
	* sysdeps/unix/sysv/linux/mq_unlink.c: New file.
	* sysdeps/unix/sysv/linux/mq_receive.c: New file.
	* sysdeps/unix/sysv/linux/mq_open.c: New file.

2004-04-09  Thorsten Kukuk  <kukuk@suse.de>

	* sysdeps/s390/ffs.c: Don't add ffsl weak alias on s390x.

2004-04-09  Steven Munroe  <sjmunroe@us.ibm.com>

	* sysdeps/unix/sysv/linux/powerpc/powerpc64/umount.c: New file.
This commit is contained in:
Ulrich Drepper 2004-04-13 02:15:43 +00:00
parent 381a0c26d7
commit 1b82c6c77d
49 changed files with 2690 additions and 30 deletions

View File

@ -1,3 +1,44 @@
2004-04-08 Ulrich Drepper <drepper@redhat.com>
* rt/tst-mqueue3.c: New file.
* rt/Makefile (tests): Add tst-mqueue3.
2004-04-08 Jakub Jelinek <jakub@redhat.com>
* rt/tst-mqueue1.c: New file.
* rt/tst-mqueue2.c: New file.
* rt/tst-mqueue4.c: New file.
* rt/Makefile (tests): Add tst-mqueue1, tst-mqueue2, tst-mqueue4.
* rt/Versions (librt): Add mq_*@@GLIBC_2.3.4.
* rt/Makefile (headers): Add mqueue.h and bits/mqueue.h.
(mq-routines): Set.
(librt-routines): Use it.
* rt/mqueue.h: New file.
* include/mqueue.h: New file.
* sysdeps/generic/bits/mqueue.h: New file.
* sysdeps/generic/mq_setattr.c: New file.
* sysdeps/generic/mq_getattr.c: New file.
* sysdeps/generic/mq_notify.c: New file.
* sysdeps/generic/mq_close.c: New file.
* sysdeps/generic/mq_send.c: New file.
* sysdeps/generic/mq_unlink.c: New file.
* sysdeps/generic/mq_receive.c: New file.
* sysdeps/generic/mq_timedreceive.c: New file.
* sysdeps/generic/mq_timedsend.c: New file.
* sysdeps/generic/mq_open.c: New file.
* sysdeps/unix/sysv/linux/bits/local_lim.h (MQ_PRIO_MAX): Define.
* sysdeps/unix/sysv/linux/bits/mqueue.h: New file.
* sysdeps/unix/sysv/linux/syscalls.list: Add mq_timedsend,
mq_timedreceive and mq_setattr.
* sysdeps/unix/sysv/linux/mq_getattr.c: New file.
* sysdeps/unix/sysv/linux/mq_notify.c: New file.
* sysdeps/unix/sysv/linux/mq_close.c: New file.
* sysdeps/unix/sysv/linux/mq_send.c: New file.
* sysdeps/unix/sysv/linux/mq_unlink.c: New file.
* sysdeps/unix/sysv/linux/mq_receive.c: New file.
* sysdeps/unix/sysv/linux/mq_open.c: New file.
2004-04-09 Andreas Schwab <schwab@suse.de>
* sysdeps/unix/sysv/linux/ia64/sysdep.h (DO_INLINE_SYSCALL): Move
@ -18,14 +59,6 @@
(LOAD_REGS_5, LOAD_REGS_6): New macros to actually load the
syscall argument registers.
2004-04-09 Thorsten Kukuk <kukuk@suse.de>
* sysdeps/s390/ffs.c: Don't add ffsl weak alias on s390x.
2004-04-09 Steven Munroe <sjmunroe@us.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/powerpc64/umount.c: New file.
2004-04-09 Andreas Schwab <schwab@suse.de>
* sysdeps/unix/sysv/linux/m68k/sysdep.h (INTERNAL_SYSCALL): Add
@ -37,6 +70,14 @@
(LOAD_REGS_5, LOAD_REGS_6): New macros to actually load the
syscall argument registers.
2004-04-09 Thorsten Kukuk <kukuk@suse.de>
* sysdeps/s390/ffs.c: Don't add ffsl weak alias on s390x.
2004-04-09 Steven Munroe <sjmunroe@us.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/powerpc64/umount.c: New file.
2004-04-08 Ulrich Drepper <drepper@redhat.com>
* po/nl.po: Update from translation team.

31
bits/mqueue.h Normal file
View File

@ -0,0 +1,31 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _MQUEUE_H
# error "Never use <bits/mqueue.h> directly; include <mqueue.h> instead."
#endif
typedef int mqd_t;
struct mq_attr
{
long int mq_flags; /* Message queue flags. */
long int mq_maxmsg; /* Maximum number of messages. */
long int mq_msgsize; /* Maximum message size. */
long int mq_curmsgs; /* Number of messages currently queued. */
};

7
include/mqueue.h Normal file
View File

@ -0,0 +1,7 @@
#include <rt/mqueue.h>
#ifdef IS_IN_librt
hidden_proto (mq_timedsend)
hidden_proto (mq_timedreceive)
hidden_proto (mq_setattr)
#endif

View File

@ -1,3 +1,14 @@
2004-04-08 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/bits/local_lim.h (MQ_PRIO_MAX): Define.
* sysdeps/unix/sysv/linux/alpha/bits/local_lim.h (MQ_PRIO_MAX): Define.
* sysdeps/unix/sysv/linux/ia64/bits/local_lim.h (MQ_PRIO_MAX): Define.
* sysdeps/unix/sysv/linux/sparc/bits/local_lim.h (MQ_PRIO_MAX): Define.
* sysdeps/unix/sysv/linux/bits/posix_opt.h (_POSIX_MESSAGE_PASSING):
Define.
* sysdeps/unix/sysv/linux/i386/bits/posix_opt.h
(_POSIX_MESSAGE_PASSING): Define.
2004-04-10 Andreas Jaeger <aj@suse.de>
* sysdeps/x86_64/pt-machine.h: Add used attribute to stack_pointer

View File

@ -87,3 +87,6 @@
/* Maximum host name length. */
#define HOST_NAME_MAX 64
/* Maximum message queue priority level. */
#define MQ_PRIO_MAX 32768

View File

@ -87,3 +87,6 @@
/* Maximum host name length. */
#define HOST_NAME_MAX 64
/* Maximum message queue priority level. */
#define MQ_PRIO_MAX 32768

View File

@ -1,5 +1,5 @@
/* Define POSIX options for Linux.
Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -129,8 +129,8 @@
/* The barrier functions are available. */
#define _POSIX_BARRIERS 200112L
/* POSIX message queues are not yet supported. */
#undef _POSIX_MESSAGE_PASSING
/* POSIX message queues are available. */
#define _POSIX_MESSAGE_PASSING 200112L
/* The monotonic clock might be available. */
#define _POSIX_MONOTONIC_CLOCK 0

View File

@ -1,5 +1,5 @@
/* Define POSIX options for Linux/ix86.
Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -135,8 +135,8 @@
/* The barrier functions are available. */
#define _POSIX_BARRIERS 200112L
/* POSIX message queues are not yet supported. */
#undef _POSIX_MESSAGE_PASSING
/* POSIX message queues are available. */
#define _POSIX_MESSAGE_PASSING 200112L
/* The monotonic clock might be available. */
#define _POSIX_MONOTONIC_CLOCK 0

View File

@ -87,3 +87,6 @@
/* Maximum host name length. */
#define HOST_NAME_MAX 64
/* Maximum message queue priority level. */
#define MQ_PRIO_MAX 32768

View File

@ -87,3 +87,6 @@
/* Maximum host name length. */
#define HOST_NAME_MAX 64
/* Maximum message queue priority level. */
#define MQ_PRIO_MAX 32768

View File

@ -1,3 +1,22 @@
2004-04-12 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/mq-notify.c: New file.
2004-04-08 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/bits/local_lim.h (MQ_PRIO_MAX): Define.
* sysdeps/unix/sysv/linux/alpha/bits/local_lim.h (MQ_PRIO_MAX): Define.
* sysdeps/unix/sysv/linux/ia64/bits/local_lim.h (MQ_PRIO_MAX): Define.
* sysdeps/unix/sysv/linux/sparc/bits/local_lim.h (MQ_PRIO_MAX): Define.
* sysdeps/unix/sysv/linux/bits/posix_opt.h (_POSIX_MESSAGE_PASSING):
Define.
* sysdeps/unix/sysv/linux/i386/bits/posix_opt.h
(_POSIX_MESSAGE_PASSING): Define.
* sysdeps/unix/sysv/linux/ia64/bits/posix_opt.h
(_POSIX_MESSAGE_PASSING): Define.
* sysdeps/unix/sysv/linux/x86_64/bits/posix_opt.h
(_POSIX_MESSAGE_PASSING): Define.
2004-04-04 Ulrich Drepper <drepper@redhat.com>
* tst-context1.c (fct): Check whether correct stack is used.

View File

@ -84,3 +84,6 @@
/* Maximum host name length. */
#define HOST_NAME_MAX 64
/* Maximum message queue priority level. */
#define MQ_PRIO_MAX 32768

View File

@ -84,3 +84,6 @@
/* Maximum host name length. */
#define HOST_NAME_MAX 64
/* Maximum message queue priority level. */
#define MQ_PRIO_MAX 32768

View File

@ -1,5 +1,5 @@
/* Define POSIX options for Linux.
Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -126,8 +126,8 @@
/* The barrier functions are available. */
#define _POSIX_BARRIERS 200112L
/* POSIX message queues are not yet supported. */
#undef _POSIX_MESSAGE_PASSING
/* POSIX message queues are available. */
#define _POSIX_MESSAGE_PASSING 200112L
/* Thread process-shared synchronization is supported. */
#define _POSIX_THREAD_PROCESS_SHARED 200112L

View File

@ -1,5 +1,5 @@
/* Define POSIX options for Linux.
Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -132,8 +132,8 @@
/* The barrier functions are available. */
#define _POSIX_BARRIERS 200112L
/* POSIX message queues are not yet supported. */
#undef _POSIX_MESSAGE_PASSING
/* POSIX message queues are available. */
#define _POSIX_MESSAGE_PASSING 200112L
/* Thread process-shared synchronization is supported. */
#define _POSIX_THREAD_PROCESS_SHARED 200112L

View File

@ -84,3 +84,6 @@
/* Maximum host name length. */
#define HOST_NAME_MAX 64
/* Maximum message queue priority level. */
#define MQ_PRIO_MAX 32768

View File

@ -1,5 +1,5 @@
/* Define POSIX options for Linux.
Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -132,8 +132,8 @@
/* The barrier functions are available. */
#define _POSIX_BARRIERS 200112L
/* POSIX message queues are not yet supported. */
#undef _POSIX_MESSAGE_PASSING
/* POSIX message queues are available. */
#define _POSIX_MESSAGE_PASSING 200112L
/* Thread process-shared synchronization is supported. */
#define _POSIX_THREAD_PROCESS_SHARED 200112L

View File

@ -0,0 +1,285 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contribute by Ulrich Drepper <drepper@redhat.com>, 2004.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <mqueue.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include <sysdep.h>
#include <unistd.h>
#include <sys/socket.h>
#include <not-cancel.h>
#ifdef __NR_mq_notify
/* Defined in the kernel headers: */
#define NOTIFY_COOKIE_LEN 32 /* Length of the cookie used. */
#define NOTIFY_WOKENUP 1 /* Code for notifcation. */
#define NOTIFY_REMOVED 2 /* Code for closed message queue
of de-notifcation. */
/* Data structure for the queued notification requests. */
union notify_data
{
struct
{
void (*fct) (union sigval); /* The function to run. */
union sigval param; /* The parameter to pass. */
pthread_attr_t *attr; /* Attributes to create the thread with. */
/* NB: on 64-bit machines the struct as a size of 24 bytes. Which means
byte 31 can still be used for returning the status. */
};
char raw[NOTIFY_COOKIE_LEN];
};
/* Keep track of the initialization. */
static pthread_once_t once = PTHREAD_ONCE_INIT;
/* The netlink socket. */
static int netlink_socket = -1;
/* Barrier used to make sure data passed to the new thread is not
resused by the parent. */
static pthread_barrier_t notify_barrier;
/* Modify the signal mask. We move this into a separate function so
that the stack space needed for sigset_t is not deducted from what
the thread can use. */
static int
__attribute__ ((noinline))
change_sigmask (int how, sigset_t *oss)
{
sigset_t ss;
sigfillset (&ss);
return pthread_sigmask (how, &ss, oss);
}
/* The function used for the notification. */
static void *
notification_function (void *arg)
{
/* Copy the function and parameter so that the parent thread can go
on with its life. */
volatile union notify_data *data = (volatile union notify_data *) arg;
void (*fct) (union sigval) = data->fct;
union sigval param = data->param;
/* Let the parent go. */
(void) pthread_barrier_wait (&notify_barrier);
/* Make the thread detached. */
(void) pthread_detach (pthread_self ());
/* The parent thread has all signals blocked. This is probably a
bit surprising for this thread. So we unblock all of them. */
(void) change_sigmask (SIG_UNBLOCK, NULL);
/* Now run the user code. */
fct (param);
/* And we are done. */
return NULL;
}
/* Helper thread. */
static void *
helper_thread (void *arg)
{
while (1)
{
union notify_data data;
ssize_t n = recv (netlink_socket, &data, sizeof (data),
MSG_NOSIGNAL | MSG_WAITALL);
if (n < NOTIFY_COOKIE_LEN)
continue;
if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_WOKENUP)
{
/* Just create the thread as instructed. There is no way to
report a problem with creating a thread. */
pthread_t th;
if (__builtin_expect (pthread_create (&th, data.attr,
notification_function, &data)
== 0, 0))
/* Since we passed a pointer to DATA to the new thread we have
to wait until it is done with it. */
(void) pthread_barrier_wait (&notify_barrier);
}
else if (data.raw[NOTIFY_COOKIE_LEN - 1] == NOTIFY_REMOVED)
/* The only state we keep is the copy of the thread attributes. */
free (data.attr);
}
}
static void
reset_once (void)
{
once = PTHREAD_ONCE_INIT;
}
static void
init_mq_netlink (void)
{
/* This code might be called a second time after fork(). The file
descriptor is inherited from the parent. */
if (netlink_socket == -1)
{
/* Just a normal netlink socket, not bound. */
netlink_socket = socket (AF_NETLINK, SOCK_RAW, 0);
/* No need to do more if we have no socket. */
if (netlink_socket == -1)
return;
/* Make sure the descriptor is closed on exec. */
if (fcntl (netlink_socket, F_SETFD, FD_CLOEXEC) != 0)
goto errout;
}
int err = 1;
/* Initialize the barrier. */
if (__builtin_expect (pthread_barrier_init (&notify_barrier, NULL, 2) == 0,
0))
{
/* Create the helper thread. */
pthread_attr_t attr;
(void) pthread_attr_init (&attr);
(void) pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
/* We do not need much stack space, the bare minimum will be enough. */
(void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN);
/* Temporarily block all signals so that the newly created
thread inherits the mask. */
sigset_t oss;
int have_no_oss = change_sigmask (SIG_BLOCK, &oss);
pthread_t th;
err = pthread_create (&th, &attr, helper_thread, NULL);
/* Reset the signal mask. */
if (!have_no_oss)
pthread_sigmask (SIG_SETMASK, &oss, NULL);
(void) pthread_attr_destroy (&attr);
if (err == 0)
{
static int added_atfork;
if (added_atfork == 0
&& pthread_atfork (NULL, NULL, reset_once) != 0)
{
/* The child thread will call recv() which is a
cancellation point. */
(void) pthread_cancel (th);
err = 1;
}
else
added_atfork = 1;
}
}
if (err != 0)
{
errout:
close_not_cancel_no_status (netlink_socket);
netlink_socket = -1;
}
}
/* Register notification upon message arrival to an empty message queue
MQDES. */
int
mq_notify (mqd_t mqdes, const struct sigevent *notification)
{
/* Make sure the type is correctly defined. */
assert (sizeof (union notify_data) == NOTIFY_COOKIE_LEN);
/* Special treatment needed for SIGEV_THREAD. */
if (notification == NULL || notification->sigev_notify != SIGEV_THREAD)
return INLINE_SYSCALL (mq_notify, 2, mqdes, notification);
/* The kernel cannot directly start threads. This will have to be
done at userlevel. Since we cannot start threads from signal
handlers we have to create a dedicated thread which waits for
notifications for arriving messages and creates threads in
response. */
/* Initialize only once. */
pthread_once (&once, init_mq_netlink);
/* If we cannot create the netlink socket we cannot provide
SIGEV_THREAD support. */
if (__builtin_expect (netlink_socket == -1, 0))
{
__set_errno (ENOSYS);
return -1;
}
/* Create the cookie. It will hold almost all the state. */
union notify_data data;
memset (&data, '\0', sizeof (data));
data.fct = notification->sigev_notify_function;
data.param = notification->sigev_value;
if (notification->sigev_notify_attributes != NULL)
{
/* The thread attribute has to be allocated separately. */
data.attr = (pthread_attr_t *) malloc (sizeof (pthread_attr_t));
if (data.attr == NULL)
return -1;
memcpy (data.attr, notification->sigev_notify_attributes,
sizeof (pthread_attr_t));
}
/* Construct the new request. */
struct sigevent se;
se.sigev_notify = SIGEV_THREAD;
se.sigev_signo = netlink_socket;
se.sigev_value.sival_ptr = &data;
/* Tell the kernel. */
int retval = INLINE_SYSCALL (mq_notify, 2, mqdes, &se);
/* If it failed, free the allocated memory. */
if (__builtin_expect (retval != 0, 0))
free (data.attr);
return retval;
}
#else
# include <sysdeps/generic/mq_notify.c>
#endif

View File

@ -84,3 +84,6 @@
/* Maximum host name length. */
#define HOST_NAME_MAX 64
/* Maximum message queue priority level. */
#define MQ_PRIO_MAX 32768

View File

@ -1,5 +1,5 @@
/* Define POSIX options for Linux.
Copyright (C) 1996-2001, 2002, 2003 Free Software Foundation, Inc.
Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -132,8 +132,8 @@
/* The barrier functions are available. */
#define _POSIX_BARRIERS 200112L
/* POSIX message queues are not yet supported. */
#undef _POSIX_MESSAGE_PASSING
/* POSIX message queues are available. */
#define _POSIX_MESSAGE_PASSING 200112L
/* Thread process-shared synchronization is supported. */
#define _POSIX_THREAD_PROCESS_SHARED 200112L

View File

@ -1,4 +1,4 @@
# Copyright (C) 1997-2001, 2002, 2003 Free Software Foundation, Inc.
# Copyright (C) 1997-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@ -21,7 +21,7 @@
#
subdir := rt
headers := aio.h
headers := aio.h mqueue.h bits/mqueue.h
aio-routines := aio_cancel aio_error aio_fsync aio_misc aio_read \
aio_read64 aio_return aio_suspend aio_write \
@ -33,14 +33,17 @@ clock-routines := get_clockfreq clock_getcpuclockid \
timer-routines := timer_create timer_delete timer_getoverr \
timer_gettime timer_settime
shm-routines := shm_open shm_unlink
mq-routines := mq_open mq_close mq_unlink mq_getattr mq_setattr \
mq_notify mq_send mq_receive mq_timedsend \
mq_timedreceive
librt-routines = $(aio-routines) \
$(clock-routines) $(timer-routines) \
$(shm-routines)
$(shm-routines) $(mq-routines)
tests := tst-shm tst-clock tst-clock_nanosleep tst-timer tst-timer2 \
tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \
tst-aio7
tst-aio7 tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4
extra-libs := librt
extra-libs-others := $(extra-libs)
@ -53,6 +56,8 @@ CFLAGS-aio_suspend.c = -fexceptions
CFLAGS-clock_nanosleep.c = -fexceptions -fasynchronous-unwind-tables
CFLAGS-librt-cancellation.c = -fasynchronous-unwind-tables
LDFLAGS-rt.so = -Wl,--enable-new-dtags,-z,nodelete
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
# This ensures they will load libc.so for needed symbols if loaded by
# a statically-linked program that hasn't already loaded it.

View File

@ -17,4 +17,9 @@ librt {
timer_create; timer_delete; timer_getoverrun; timer_gettime;
timer_settime;
}
GLIBC_2.3.4 {
# m*
mq_open; mq_close; mq_unlink; mq_getattr; mq_setattr;
mq_notify; mq_send; mq_receive; mq_timedsend; mq_timedreceive;
}
}

91
rt/mqueue.h Normal file
View File

@ -0,0 +1,91 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _MQUEUE_H
#define _MQUEUE_H 1
#include <features.h>
#include <sys/types.h>
#include <fcntl.h>
#define __need_sigevent_t
#include <bits/siginfo.h>
#define __need_timespec
#include <time.h>
/* Get the definition of mqd_t and struct mq_attr. */
#include <bits/mqueue.h>
__BEGIN_DECLS
/* Establish connection between a process and a message queue NAME and
return message queue descriptor or (mqd_t) -1 on error. OFLAG determines
the type of access used. If O_CREAT is on OFLAG, the third argument is
taken as a `mode_t', the mode of the created message queue, and the fourth
argument is taken as `struct mq_attr *', pointer to message queue
attributes. If the fourth argument is NULL, default attributes are
used. */
extern mqd_t mq_open (const char *__name, int __oflag, ...) __THROW;
/* Removes the association between message queue descriptor MQDES and its
message queue. */
extern int mq_close (mqd_t __mqdes) __THROW;
/* Query status and attributes of message queue MQDES. */
extern int mq_getattr (mqd_t __mqdes, struct mq_attr *__mqstat) __THROW;
/* Set attributes associated with message queue MQDES and if OMQSTAT is
not NULL also query its old attributes. */
extern int mq_setattr (mqd_t __mqdes,
const struct mq_attr *__restrict __mqstat,
struct mq_attr *__restrict __omqstat) __THROW;
/* Remove message queue named NAME. */
extern int mq_unlink (const char *__name) __THROW;
/* Register notification upon message arrival to an empty message queue
MQDES. */
extern int mq_notify (mqd_t __mqdes, const struct sigevent *__notification)
__THROW;
/* Receive the oldest from highest priority messages in message queue
MQDES. */
extern ssize_t mq_receive (mqd_t __mqdes, char *__msg_ptr, size_t __msg_len,
unsigned int *__msg_prio);
/* Add message pointed by MSG_PTR to message queue MQDES. */
extern int mq_send (mqd_t __mqdes, const char *__msg_ptr, size_t __msg_len,
unsigned int __msg_prio);
#ifdef __USE_XOPEN2K
/* Receive the oldest from highest priority messages in message queue
MQDES, stop waiting if ABS_TIMEOUT expires. */
extern ssize_t mq_timedreceive (mqd_t __mqdes, char *__restrict __msg_ptr,
size_t __msg_len,
unsigned int *__restrict __msg_prio,
const struct timespec *__restrict __abs_timeout);
/* Add message pointed by MSG_PTR to message queue MQDES, stop blocking
on full message queue if ABS_TIMEOUT expires. */
extern int mq_timedsend (mqd_t __mqdes, const char *__msg_ptr,
size_t __msg_len, unsigned int __msg_prio,
const struct timespec *__abs_timeout);
#endif
__END_DECLS
#endif /* mqueue.h */

62
rt/tst-mqueue.h Normal file
View File

@ -0,0 +1,62 @@
/* Common code for message queue passing tests.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <mqueue.h>
#include <search.h>
#include <stdlib.h>
#include <string.h>
/* List of temporary files. */
struct temp_mq_list
{
struct qelem q;
char name[1];
} *temp_mq_list;
/* Add temporary files in list. */
static void
__attribute__ ((unused))
add_temp_mq (const char *name)
{
size_t len = strlen (name);
struct temp_mq_list *newp
= (struct temp_mq_list *) calloc (sizeof (*newp) + len, 1);
if (newp != NULL)
{
memcpy (newp->name, name, len + 1);
if (temp_mq_list == NULL)
temp_mq_list = (struct temp_mq_list *) &newp->q;
else
insque (newp, temp_mq_list);
}
}
/* Delete all temporary files. */
static void
delete_temp_mqs (void)
{
while (temp_mq_list != NULL)
{
mq_unlink (temp_mq_list->name);
temp_mq_list = (struct temp_mq_list *) temp_mq_list->q.q_forw;
}
}
#define CLEANUP_HANDLER delete_temp_mqs ()

416
rt/tst-mqueue1.c Normal file
View File

@ -0,0 +1,416 @@
/* Test message queue passing.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <fcntl.h>
#include <mqueue.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include "tst-mqueue.h"
static int
intcmp (const void *a, const void *b)
{
if (*(unsigned char *)a < *(unsigned char *)b)
return 1;
if (*(unsigned char *)a > *(unsigned char *)b)
return -1;
return 0;
}
static int
check_attrs (struct mq_attr *attr, int nonblock, long cnt)
{
int result = 0;
if (attr->mq_maxmsg != 10 || attr->mq_msgsize != 1)
{
printf ("attributes don't match those passed to mq_open\n"
"mq_maxmsg %ld, mq_msgsize %ld\n",
attr->mq_maxmsg, attr->mq_msgsize);
result = 1;
}
if ((attr->mq_flags & O_NONBLOCK) != nonblock)
{
printf ("mq_flags %lx != %x\n", (attr->mq_flags & O_NONBLOCK), nonblock);
result = 1;
}
if (attr->mq_curmsgs != cnt)
{
printf ("mq_curmsgs %ld != %ld\n", attr->mq_curmsgs, cnt);
result = 1;
}
return result;
}
static int
do_one_test (mqd_t q, const char *name, int nonblock)
{
int result = 0;
unsigned char v []
= { 0x32, 0x62, 0x22, 0x31, 0x11, 0x73, 0x61, 0x21, 0x72, 0x71, 0x81 };
struct mq_attr attr;
memset (&attr, 0xaa, sizeof (attr));
if (mq_getattr (q, &attr) != 0)
{
printf ("mq_getattr failed: %m\n");
result = 1;
}
else
result = check_attrs (&attr, nonblock, 0);
if (mq_receive (q, &v[0], 1, NULL) != -1)
{
puts ("mq_receive on O_WRONLY mqd_t unexpectedly succeeded");
result = 1;
}
else if (errno != EBADF)
{
printf ("mq_receive on O_WRONLY mqd_t did not fail with EBADF: %m\n");
result = 1;
}
struct timespec ts;
if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
--ts.tv_sec;
else
{
ts.tv_sec = time (NULL) - 1;
ts.tv_nsec = 0;
}
int ret;
for (int i = 0; i < 10; ++i)
{
if (i & 1)
ret = mq_send (q, &v[i], 1, v[i] >> 4);
else
ret = mq_timedsend (q, &v[i], 1, v[i] >> 4, &ts);
if (ret)
{
printf ("mq_%ssend failed: %m\n", (i & 1) ? "" : "timed");
result = 1;
}
}
ret = mq_timedsend (q, &v[10], 1, 8, &ts);
if (ret != -1)
{
puts ("mq_timedsend on full queue did not fail");
result = 1;
}
else if (errno != (nonblock ? EAGAIN : ETIMEDOUT))
{
printf ("mq_timedsend on full queue did not fail with %s: %m\n",
nonblock ? "EAGAIN" : "ETIMEDOUT");
result = 1;
}
if (nonblock)
{
ret = mq_send (q, &v[10], 1, 8);
if (ret != -1)
{
puts ("mq_send on full non-blocking queue did not fail");
result = 1;
}
else if (errno != EAGAIN)
{
printf ("mq_send on full non-blocking queue did not fail"
"with EAGAIN: %m\n");
result = 1;
}
}
memset (&attr, 0xaa, sizeof (attr));
if (mq_getattr (q, &attr) != 0)
{
printf ("mq_getattr failed: %m\n");
result = 1;
}
else
result = check_attrs (&attr, nonblock, 10);
pid_t pid = fork ();
if (pid == -1)
{
printf ("fork failed: %m\n");
result = 1;
}
else if (pid == 0)
{
result = 0;
if (mq_close (q) != 0)
{
printf ("mq_close in child failed: %m\n");
result = 1;
}
q = mq_open (name, O_RDONLY | nonblock);
if (q == (mqd_t) -1)
{
printf ("mq_open in child failed: %m\n");
exit (1);
}
memset (&attr, 0xaa, sizeof (attr));
if (mq_getattr (q, &attr) != 0)
{
printf ("mq_getattr failed: %m\n");
result = 1;
}
else
result = check_attrs (&attr, nonblock, 10);
unsigned char vr[11] = { };
unsigned int prio;
ssize_t rets;
if (mq_send (q, &v[0], 1, 1) != -1)
{
puts ("mq_send on O_RDONLY mqd_t unexpectedly succeeded");
result = 1;
}
else if (errno != EBADF)
{
printf ("mq_send on O_WRONLY mqd_t did not fail with EBADF: %m\n");
result = 1;
}
for (int i = 0; i < 10; ++i)
{
if (i & 1)
rets = mq_receive (q, &vr[i], 1, &prio);
else
rets = mq_timedreceive (q, &vr[i], 1, &prio, &ts);
if (rets != 1)
{
if (rets == -1)
printf ("mq_%sreceive failed: %m\n", (i & 1) ? "" : "timed");
else
printf ("mq_%sreceive returned %zd != 1\n",
(i & 1) ? "" : "timed", rets);
result = 1;
}
else if (prio != (unsigned int) vr[i] >> 4)
{
printf ("unexpected priority %x for value %02x\n", prio,
vr[i]);
result = 1;
}
}
qsort (v, 10, 1, intcmp);
if (memcmp (v, vr, 10) != 0)
{
puts ("messages not received in expected order");
result = 1;
}
rets = mq_timedreceive (q, &vr[10], 1, &prio, &ts);
if (rets != -1)
{
puts ("mq_timedreceive on empty queue did not fail");
result = 1;
}
else if (errno != (nonblock ? EAGAIN : ETIMEDOUT))
{
printf ("mq_timedreceive on empty queue did not fail with %s: %m\n",
nonblock ? "EAGAIN" : "ETIMEDOUT");
result = 1;
}
if (nonblock)
{
ret = mq_receive (q, &vr[10], 1, &prio);
if (ret != -1)
{
puts ("mq_receive on empty non-blocking queue did not fail");
result = 1;
}
else if (errno != EAGAIN)
{
printf ("mq_receive on empty non-blocking queue did not fail"
"with EAGAIN: %m\n");
result = 1;
}
}
memset (&attr, 0xaa, sizeof (attr));
if (mq_getattr (q, &attr) != 0)
{
printf ("mq_getattr failed: %m\n");
result = 1;
}
else
result = check_attrs (&attr, nonblock, 0);
if (mq_close (q) != 0)
{
printf ("mq_close in child failed: %m\n");
result = 1;
}
exit (result);
}
int status;
if (waitpid (pid, &status, 0) != pid)
{
printf ("waitpid failed: %m\n");
result = 1;
}
else if (!WIFEXITED (status) || WEXITSTATUS (status))
{
printf ("child failed: %d\n", status);
result = 1;
}
memset (&attr, 0xaa, sizeof (attr));
if (mq_getattr (q, &attr) != 0)
{
printf ("mq_getattr failed: %m\n");
result = 1;
}
else
result = check_attrs (&attr, nonblock, 0);
return result;
}
#define TEST_FUNCTION do_test ()
static int
do_test (void)
{
int result = 0;
char name[sizeof "/tst-mqueue-" + sizeof (pid_t) * 3];
snprintf (name, sizeof (name), "/tst-mqueue-%u", getpid ());
struct mq_attr attr = { .mq_maxmsg = 10, .mq_msgsize = 1 };
mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_WRONLY, 0600, &attr);
if (q == (mqd_t) -1)
{
printf ("mq_open failed with: %m\n");
return result;
}
else
add_temp_mq (name);
result = do_one_test (q, name, 0);
mqd_t q2 = mq_open (name, O_WRONLY | O_NONBLOCK);
if (q2 == (mqd_t) -1)
{
printf ("mq_open failed with: %m\n");
q2 = q;
result = 1;
}
else
{
if (mq_close (q) != 0)
{
printf ("mq_close in parent failed: %m\n");
result = 1;
}
q = q2;
result |= do_one_test (q, name, O_NONBLOCK);
if (mq_getattr (q, &attr) != 0)
{
printf ("mq_getattr failed: %m\n");
result = 1;
}
else
{
attr.mq_flags ^= O_NONBLOCK;
struct mq_attr attr2;
memset (&attr2, 0x55, sizeof (attr2));
if (mq_setattr (q, &attr, &attr2) != 0)
{
printf ("mq_setattr failed: %m\n");
result = 1;
}
else if (attr.mq_flags != (attr2.mq_flags ^ O_NONBLOCK)
|| attr.mq_maxmsg != attr2.mq_maxmsg
|| attr.mq_msgsize != attr2.mq_msgsize
|| attr.mq_curmsgs != 0
|| attr2.mq_curmsgs != 0)
{
puts ("mq_setattr returned unexpected values in *omqstat");
result = 1;
}
else
{
result |= do_one_test (q, name, 0);
if (mq_setattr (q, &attr2, NULL) != 0)
{
printf ("mq_setattr failed: %m\n");
result = 1;
}
else
result |= do_one_test (q, name, O_NONBLOCK);
}
}
}
if (mq_unlink (name) != 0)
{
printf ("mq_unlink failed: %m\n");
result = 1;
}
if (mq_close (q) != 0)
{
printf ("mq_close in parent failed: %m\n");
result = 1;
}
if (mq_close (q) != -1)
{
puts ("second mq_close did not fail");
result = 1;
}
else if (errno != EBADF)
{
printf ("second mq_close did not fail with EBADF: %m\n");
result = 1;
}
return result;
}
#include "../test-skeleton.c"

477
rt/tst-mqueue2.c Normal file
View File

@ -0,0 +1,477 @@
/* Test message queue passing.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <fcntl.h>
#include <mqueue.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include "tst-mqueue.h"
static void
alrm_handler (int sig)
{
}
#define TIMEOUT 10
#define TEST_FUNCTION do_test ()
static int
do_test (void)
{
int result = 0;
char name[sizeof "/tst-mqueue2-" + sizeof (pid_t) * 3];
snprintf (name, sizeof (name), "/tst-mqueue2-%u", getpid ());
struct mq_attr attr = { .mq_maxmsg = 2, .mq_msgsize = 2 };
mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
if (q == (mqd_t) -1)
{
printf ("mq_open failed with: %m\n");
return result;
}
else
add_temp_mq (name);
mqd_t q2 = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
if (q2 != (mqd_t) -1)
{
puts ("mq_open with O_EXCL unexpectedly succeeded");
result = 1;
}
else if (errno != EEXIST)
{
printf ("mq_open did not fail with EEXIST: %m\n");
result = 1;
}
char name2[sizeof "/tst-mqueue2-2-" + sizeof (pid_t) * 3];
snprintf (name2, sizeof (name2), "/tst-mqueue2-2-%u", getpid ());
attr.mq_maxmsg = -2;
q2 = mq_open (name2, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
if (q2 != (mqd_t) -1)
{
puts ("mq_open with invalid mq_maxmsg unexpectedly succeeded");
add_temp_mq (name2);
result = 1;
}
else if (errno != EINVAL)
{
printf ("mq_open with invalid mq_maxmsg did not fail with "
"EINVAL: %m\n");
result = 1;
}
attr.mq_maxmsg = 2;
attr.mq_msgsize = -56;
q2 = mq_open (name2, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
if (q2 != (mqd_t) -1)
{
puts ("mq_open with invalid mq_msgsize unexpectedly succeeded");
add_temp_mq (name2);
result = 1;
}
else if (errno != EINVAL)
{
printf ("mq_open with invalid mq_msgsize did not fail with "
"EINVAL: %m\n");
result = 1;
}
char buf[3];
struct timespec ts;
if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
ts.tv_sec += 10;
else
{
ts.tv_sec = time (NULL) + 10;
ts.tv_nsec = 0;
}
if (mq_timedreceive (q, buf, 1, NULL, &ts) == 0)
{
puts ("mq_timedreceive with too small msg_len did not fail");
result = 1;
}
else if (errno != EMSGSIZE)
{
printf ("mq_timedreceive with too small msg_len did not fail with "
"EMSGSIZE: %m\n");
result = 1;
}
ts.tv_nsec = -1;
if (mq_timedreceive (q, buf, 2, NULL, &ts) == 0)
{
puts ("mq_timedreceive with negative tv_nsec did not fail");
result = 1;
}
else if (errno != EINVAL)
{
printf ("mq_timedreceive with negative tv_nsec did not fail with "
"EINVAL: %m\n");
result = 1;
}
ts.tv_nsec = 1000000000;
if (mq_timedreceive (q, buf, 2, NULL, &ts) == 0)
{
puts ("mq_timedreceive with tv_nsec >= 1000000000 did not fail");
result = 1;
}
else if (errno != EINVAL)
{
printf ("mq_timedreceive with tv_nsec >= 1000000000 did not fail with "
"EINVAL: %m\n");
result = 1;
}
struct sigaction sa = { .sa_handler = alrm_handler, .sa_flags = 0 };
sigemptyset (&sa.sa_mask);
sigaction (SIGALRM, &sa, NULL);
struct itimerval it = { .it_value = { .tv_sec = 1 } };
setitimer (ITIMER_REAL, &it, NULL);
if (mq_receive (q, buf, 2, NULL) == 0)
{
puts ("mq_receive on empty queue did not block");
result = 1;
}
else if (errno != EINTR)
{
printf ("mq_receive on empty queue did not fail with EINTR: %m\n");
result = 1;
}
setitimer (ITIMER_REAL, &it, NULL);
ts.tv_nsec = 0;
if (mq_timedreceive (q, buf, 2, NULL, &ts) == 0)
{
puts ("mq_timedreceive on empty queue did not block");
result = 1;
}
else if (errno != EINTR)
{
printf ("mq_timedreceive on empty queue did not fail with EINTR: %m\n");
result = 1;
}
buf[0] = '6';
buf[1] = '7';
if (mq_send (q, buf, 2, 3) != 0
|| (buf[0] = '8', mq_send (q, buf, 1, 4) != 0))
{
printf ("mq_send failed: %m\n");
result = 1;
}
memset (buf, ' ', sizeof (buf));
unsigned int prio;
ssize_t rets = mq_receive (q, buf, 3, &prio);
if (rets != 1)
{
if (rets == -1)
printf ("mq_receive failed: %m\n");
else
printf ("mq_receive returned %zd != 1\n", rets);
result = 1;
}
else if (prio != 4 || memcmp (buf, "8 ", 3) != 0)
{
printf ("mq_receive prio %u (4) buf \"%c%c%c\" (\"8 \")\n",
prio, buf[0], buf[1], buf[2]);
result = 1;
}
rets = mq_receive (q, buf, 2, NULL);
if (rets != 2)
{
if (rets == -1)
printf ("mq_receive failed: %m\n");
else
printf ("mq_receive returned %zd != 2\n", rets);
result = 1;
}
else if (memcmp (buf, "67 ", 3) != 0)
{
printf ("mq_receive buf \"%c%c%c\" != \"67 \"\n",
buf[0], buf[1], buf[2]);
result = 1;
}
buf[0] = '2';
buf[1] = '1';
if (clock_gettime (CLOCK_REALTIME, &ts) != 0)
ts.tv_sec = time (NULL);
ts.tv_nsec = -1000000001;
if ((mq_timedsend (q, buf, 2, 5, &ts) != 0
&& (errno != EINVAL || mq_send (q, buf, 2, 5) != 0))
|| (buf[0] = '3', ts.tv_nsec = -ts.tv_nsec,
(mq_timedsend (q, buf, 1, 4, &ts) != 0
&& (errno != EINVAL || mq_send (q, buf, 1, 4) != 0))))
{
printf ("mq_timedsend failed: %m\n");
result = 1;
}
buf[0] = '-';
ts.tv_nsec = 1000000001;
if (mq_timedsend (q, buf, 1, 6, &ts) == 0)
{
puts ("mq_timedsend with tv_nsec >= 1000000000 did not fail");
result = 1;
}
else if (errno != EINVAL)
{
printf ("mq_timedsend with tv_nsec >= 1000000000 did not fail with "
"EINVAL: %m\n");
result = 1;
}
ts.tv_nsec = -2;
if (mq_timedsend (q, buf, 1, 6, &ts) == 0)
{
puts ("mq_timedsend with negative tv_nsec did not fail");
result = 1;
}
else if (errno != EINVAL)
{
printf ("mq_timedsend with megatove tv_nsec did not fail with "
"EINVAL: %m\n");
result = 1;
}
setitimer (ITIMER_REAL, &it, NULL);
if (mq_send (q, buf, 2, 8) == 0)
{
puts ("mq_send on full queue did not block");
result = 1;
}
else if (errno != EINTR)
{
printf ("mq_send on full queue did not fail with EINTR: %m\n");
result = 1;
}
setitimer (ITIMER_REAL, &it, NULL);
ts.tv_sec += 10;
ts.tv_nsec = 0;
if (mq_timedsend (q, buf, 2, 7, &ts) == 0)
{
puts ("mq_timedsend on full queue did not block");
result = 1;
}
else if (errno != EINTR)
{
printf ("mq_timedsend on full queue did not fail with EINTR: %m\n");
result = 1;
}
memset (buf, ' ', sizeof (buf));
if (clock_gettime (CLOCK_REALTIME, &ts) != 0)
ts.tv_sec = time (NULL);
ts.tv_nsec = -1000000001;
rets = mq_timedreceive (q, buf, 2, &prio, &ts);
if (rets == -1 && errno == EINVAL)
rets = mq_receive (q, buf, 2, &prio);
if (rets != 2)
{
if (rets == -1)
printf ("mq_timedreceive failed: %m\n");
else
printf ("mq_timedreceive returned %zd != 2\n", rets);
result = 1;
}
else if (prio != 5 || memcmp (buf, "21 ", 3) != 0)
{
printf ("mq_timedreceive prio %u (5) buf \"%c%c%c\" (\"21 \")\n",
prio, buf[0], buf[1], buf[2]);
result = 1;
}
if (mq_receive (q, buf, 1, NULL) == 0)
{
puts ("mq_receive with too small msg_len did not fail");
result = 1;
}
else if (errno != EMSGSIZE)
{
printf ("mq_receive with too small msg_len did not fail with "
"EMSGSIZE: %m\n");
result = 1;
}
ts.tv_nsec = -ts.tv_nsec;
rets = mq_timedreceive (q, buf, 2, NULL, &ts);
if (rets == -1 && errno == EINVAL)
rets = mq_receive (q, buf, 2, NULL);
if (rets != 1)
{
if (rets == -1)
printf ("mq_timedreceive failed: %m\n");
else
printf ("mq_timedreceive returned %zd != 1\n", rets);
result = 1;
}
else if (memcmp (buf, "31 ", 3) != 0)
{
printf ("mq_timedreceive buf \"%c%c%c\" != \"31 \"\n",
buf[0], buf[1], buf[2]);
result = 1;
}
if (mq_send (q, "", 0, 2) != 0)
{
printf ("mq_send with msg_len 0 failed: %m\n");
result = 1;
}
rets = mq_receive (q, buf, 2, &prio);
if (rets)
{
if (rets == -1)
printf ("mq_receive failed: %m\n");
else
printf ("mq_receive returned %zd != 0\n", rets);
result = 1;
}
long mq_prio_max = sysconf (_SC_MQ_PRIO_MAX);
if (mq_prio_max > 0 && (unsigned int) mq_prio_max == mq_prio_max)
{
if (mq_send (q, buf, 1, mq_prio_max) == 0)
{
puts ("mq_send with MQ_PRIO_MAX priority unpexpectedly succeeded");
result = 1;
}
else if (errno != EINVAL)
{
printf ("mq_send with MQ_PRIO_MAX priority did not fail with "
"EINVAL: %m\n");
result = 1;
}
if (mq_send (q, buf, 1, mq_prio_max - 1) != 0)
{
printf ("mq_send with MQ_PRIO_MAX-1 priority failed: %m\n");
result = 1;
}
}
if (mq_unlink (name) != 0)
{
printf ("mq_unlink failed: %m\n");
result = 1;
}
q2 = mq_open (name, O_RDWR);
if (q2 != (mqd_t) -1)
{
printf ("mq_open of unlinked %s without O_CREAT unexpectedly"
"succeeded\n", name);
result = 1;
}
else if (errno != ENOENT)
{
printf ("mq_open of unlinked %s without O_CREAT did not fail with "
"ENOENT: %m\n", name);
result = 1;
}
if (mq_close (q) != 0)
{
printf ("mq_close in parent failed: %m\n");
result = 1;
}
if (mq_receive (q, buf, 2, NULL) == 0)
{
puts ("mq_receive on invalid mqd_t did not fail");
result = 1;
}
else if (errno != EBADF)
{
printf ("mq_receive on invalid mqd_t did not fail with EBADF: %m\n");
result = 1;
}
if (mq_send (q, buf, 1, 2) == 0)
{
puts ("mq_send on invalid mqd_t did not fail");
result = 1;
}
else if (errno != EBADF)
{
printf ("mq_send on invalid mqd_t did not fail with EBADF: %m\n");
result = 1;
}
if (mq_getattr (q, &attr) == 0)
{
puts ("mq_getattr on invalid mqd_t did not fail");
result = 1;
}
else if (errno != EBADF)
{
printf ("mq_getattr on invalid mqd_t did not fail with EBADF: %m\n");
result = 1;
}
memset (&attr, 0, sizeof (attr));
if (mq_setattr (q, &attr, NULL) == 0)
{
puts ("mq_setattr on invalid mqd_t did not fail");
result = 1;
}
else if (errno != EBADF)
{
printf ("mq_setattr on invalid mqd_t did not fail with EBADF: %m\n");
result = 1;
}
if (mq_unlink ("/tst-mqueue2-which-should-never-exist") != -1)
{
puts ("mq_unlink of non-existant message queue unexpectedly succeeded");
result = 1;
}
else if (errno != ENOENT)
{
printf ("mq_unlink of non-existant message queue did not fail with "
"ENOENT: %m\n");
result = 1;
}
return result;
}
#include "../test-skeleton.c"

238
rt/tst-mqueue3.c Normal file
View File

@ -0,0 +1,238 @@
/* Test SIGEV_THREAD handling for POSIX message queues.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
#include <signal.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <unistd.h>
#if _POSIX_THREADS
# include <pthread.h>
static pid_t pid;
static mqd_t m;
static const char message[] = "hello";
# define MAXMSG 10
# define MSGSIZE 10
# define UNIQUE 42
static void
fct (union sigval s)
{
/* Put the mq in non-blocking mode. */
struct mq_attr attr;
if (mq_getattr (m, &attr) != 0)
{
printf ("%s: mq_getattr failed: %m\n", __FUNCTION__);
exit (1);
}
attr.mq_flags |= O_NONBLOCK;
if (mq_setattr (m, &attr, NULL) != 0)
{
printf ("%s: mq_setattr failed: %m\n", __FUNCTION__);
exit (1);
}
/* Check the values. */
if (attr.mq_maxmsg != MAXMSG)
{
printf ("%s: mq_maxmsg wrong: is %ld, expecte %d\n",
__FUNCTION__, attr.mq_maxmsg, MAXMSG);
exit (1);
}
if (attr.mq_msgsize != MAXMSG)
{
printf ("%s: mq_msgsize wrong: is %ld, expecte %d\n",
__FUNCTION__, attr.mq_msgsize, MSGSIZE);
exit (1);
}
/* Read the message. */
char buf[attr.mq_msgsize];
ssize_t n = TEMP_FAILURE_RETRY (mq_receive (m, buf, attr.mq_msgsize, NULL));
if (n != sizeof (message))
{
printf ("%s: length of message wrong: is %zd, expected %zu\n",
__FUNCTION__, n, sizeof (message));
exit (1);
}
if (memcmp (buf, message, sizeof (message)) != 0)
{
printf ("%s: message wrong: is \"%s\", expected \"%s\"\n",
__FUNCTION__, buf, message);
exit (1);
}
exit (UNIQUE);
}
int
do_test (void)
{
char tmpfname[] = "/tmp/tst-mqueue3-barrier.XXXXXX";
int fd = mkstemp (tmpfname);
if (fd == -1)
{
printf ("cannot open temporary file: %m\n");
return 1;
}
/* Make sure it is always removed. */
unlink (tmpfname);
/* Create one page of data. */
size_t ps = sysconf (_SC_PAGESIZE);
char data[ps];
memset (data, '\0', ps);
/* Write the data to the file. */
if (write (fd, data, ps) != (ssize_t) ps)
{
puts ("short write");
return 1;
}
void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mem == MAP_FAILED)
{
printf ("mmap failed: %m\n");
return 1;
}
pthread_barrier_t *b;
b = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t))
& ~(__alignof (pthread_barrier_t) - 1));
pthread_barrierattr_t a;
if (pthread_barrierattr_init (&a) != 0)
{
puts ("barrierattr_init failed");
return 1;
}
if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
{
puts ("barrierattr_setpshared failed, could not test");
return 0;
}
if (pthread_barrier_init (b, &a, 2) != 0)
{
puts ("barrier_init failed");
return 1;
}
if (pthread_barrierattr_destroy (&a) != 0)
{
puts ("barrierattr_destroy failed");
return 1;
}
/* Name for the message queue. */
char mqname[sizeof ("/tst-mqueue3-") + 3 * sizeof (pid_t)];
snprintf (mqname, sizeof (mqname) - 1, "/tst-mqueue3-%ld",
(long int) getpid ());
/* Create the message queue. */
struct mq_attr attr = { .mq_maxmsg = MAXMSG, .mq_msgsize = MSGSIZE };
m = mq_open (mqname, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
if (m == -1)
{
puts ("mq_open failed");
return 1;
}
/* Unlink the message queue right away. */
if (mq_unlink (mqname) != 0)
{
puts ("mq_unlink failed");
return 1;
}
pid = fork ();
if (pid == -1)
{
puts ("fork failed");
return 1;
}
if (pid == 0)
{
/* Request notification via thread. */
struct sigevent ev;
ev.sigev_notify = SIGEV_THREAD;
ev.sigev_notify_function = fct;
ev.sigev_value.sival_ptr = NULL;
ev.sigev_notify_attributes = NULL;
/* Tell the kernel. */
if (mq_notify (m,&ev) != 0)
{
puts ("mq_notify failed");
exit (1);
}
/* Tell the parent we are ready. */
(void) pthread_barrier_wait (b);
/* Make sure the process goes away eventually. */
alarm (10);
/* Do nothing forever. */
while (1)
pause ();
}
/* Wait for the child process to register to notification method. */
(void) pthread_barrier_wait (b);
/* Send the message. */
if (mq_send (m, message, sizeof (message), 1) != 0)
{
kill (pid, SIGKILL);
puts ("mq_send failed");
return 1;
}
int r;
if (TEMP_FAILURE_RETRY (waitpid (pid, &r, 0)) != pid)
{
kill (pid, SIGKILL);
puts ("waitpid failed");
return 1;
}
return WIFEXITED (r) && WEXITSTATUS (r) == UNIQUE ? 0 : 1;
}
# define TEST_FUNCTION do_test ()
#else
# define TEST_FUNCTION 0
#endif
#include "../test-skeleton.c"

276
rt/tst-mqueue4.c Normal file
View File

@ -0,0 +1,276 @@
/* Test message queue passing.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <fcntl.h>
#include <mqueue.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include "tst-mqueue.h"
#define TIMEOUT 4
#define TEST_FUNCTION do_test ()
static int
do_test (void)
{
int result = 0;
char name[sizeof "/tst-mqueue4-" + sizeof (pid_t) * 3 + NAME_MAX];
char *p;
p = name + snprintf (name, sizeof (name), "/tst-mqueue4-%u", getpid ());
struct mq_attr attr = { .mq_maxmsg = 2, .mq_msgsize = 2 };
mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
if (q == (mqd_t) -1)
{
printf ("mq_open failed with: %m\n");
return result;
}
else
add_temp_mq (name);
*p = '.';
memset (p + 1, 'x', NAME_MAX + 1 - (p - name));
name[NAME_MAX + 1] = '\0';
mqd_t q2 = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
if (q2 == (mqd_t) -1)
{
printf ("mq_open with NAME_MAX long name compoment failed with: %m\n");
result = 1;
}
if (mq_unlink (name) != 0)
{
printf ("mq_unlink failed: %m\n");
result = 1;
}
if (mq_close (q2) != 0)
{
printf ("mq_close failed: %m\n");
result = 1;
}
name[NAME_MAX + 1] = 'x';
name[NAME_MAX + 2] = '\0';
q2 = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
if (q2 != (mqd_t) -1)
{
puts ("mq_open with too long name component unexpectedly succeeded");
mq_unlink (name);
mq_close (q2);
result = 1;
}
else if (errno != ENAMETOOLONG)
{
printf ("mq_open with too long name component did not fail with "
"ENAMETOOLONG: %m\n");
result = 1;
}
*p = '\0';
attr.mq_maxmsg = 1;
attr.mq_msgsize = 3;
q2 = mq_open (name, O_CREAT | O_RDWR, 0600, &attr);
if (q2 == (mqd_t) -1)
{
printf ("mq_open without O_EXCL failed with %m\n");
result = 1;
}
char buf[3];
strcpy (buf, "jk");
if (mq_send (q, buf, 2, 4) != 0)
{
printf ("mq_send failed: %m\n");
result = 1;
}
if (mq_send (q, buf + 1, 1, 5) != 0)
{
printf ("mq_send failed: %m\n");
result = 1;
}
if (mq_getattr (q2, &attr) != 0)
{
printf ("mq_getattr failed: %m\n");
result = 1;
}
if ((attr.mq_flags & O_NONBLOCK)
|| attr.mq_maxmsg != 2
|| attr.mq_msgsize != 2
|| attr.mq_curmsgs != 2)
{
printf ("mq_getattr returned unexpected { .mq_flags = %ld,\n"
".mq_maxmsg = %ld, .mq_msgsize = %ld, .mq_curmsgs = %ld }\n",
attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
result = 1;
}
struct timespec ts;
if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
++ts.tv_sec;
else
{
ts.tv_sec = time (NULL) + 1;
ts.tv_nsec = 0;
}
if (mq_timedsend (q2, buf, 1, 1, &ts) == 0)
{
puts ("mq_timedsend unexpectedly succeeded");
result = 1;
}
else if (errno != ETIMEDOUT)
{
printf ("mq_timedsend did not fail with ETIMEDOUT: %m\n");
result = 1;
}
if (mq_close (q2) != 0)
{
printf ("mq_close failed: %m\n");
result = 1;
}
q2 = mq_open (name, O_RDONLY, 0600);
if (q2 == (mqd_t) -1)
{
printf ("mq_open without O_CREAT failed with %m\n");
result = 1;
}
mqd_t q3 = mq_open (name, O_RDONLY, 0600);
if (q3 == (mqd_t) -1)
{
printf ("mq_open without O_CREAT failed with %m\n");
result = 1;
}
memset (buf, ' ', sizeof (buf));
unsigned int prio;
ssize_t rets = mq_receive (q2, buf, 2, &prio);
if (rets != 1)
{
if (rets == -1)
printf ("mq_receive failed with: %m\n");
else
printf ("mq_receive returned %zd != 1\n", rets);
result = 1;
}
else if (prio != 5 || memcmp (buf, "k ", 3) != 0)
{
printf ("mq_receive returned prio %u (2) buf \"%c%c%c\" (\"k \")\n",
prio, buf[0], buf[1], buf[2]);
result = 1;
}
if (mq_getattr (q3, &attr) != 0)
{
printf ("mq_getattr failed: %m\n");
result = 1;
}
if ((attr.mq_flags & O_NONBLOCK)
|| attr.mq_maxmsg != 2
|| attr.mq_msgsize != 2
|| attr.mq_curmsgs != 1)
{
printf ("mq_getattr returned unexpected { .mq_flags = %ld,\n"
".mq_maxmsg = %ld, .mq_msgsize = %ld, .mq_curmsgs = %ld }\n",
attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
result = 1;
}
rets = mq_receive (q3, buf, 2, NULL);
if (rets != 2)
{
if (rets == -1)
printf ("mq_receive failed with: %m\n");
else
printf ("mq_receive returned %zd != 2\n", rets);
result = 1;
}
else if (memcmp (buf, "jk ", 3) != 0)
{
printf ("mq_receive returned buf \"%c%c%c\" != \"jk \"\n",
buf[0], buf[1], buf[2]);
result = 1;
}
if (clock_gettime (CLOCK_REALTIME, &ts) == 0)
++ts.tv_sec;
else
{
ts.tv_sec = time (NULL) + 1;
ts.tv_nsec = 0;
}
if (mq_timedreceive (q2, buf, 2, NULL, &ts) != -1)
{
puts ("mq_timedreceive on empty queue unexpectedly succeeded");
result = 1;
}
else if (errno != ETIMEDOUT)
{
printf ("mq_timedreceive on empty queue did not fail with "
"ETIMEDOUT: %m\n");
result = 1;
}
if (mq_unlink (name) != 0)
{
printf ("mq_unlink failed: %m\n");
result = 1;
}
if (mq_close (q) != 0)
{
printf ("mq_close failed: %m\n");
result = 1;
}
if (mq_close (q2) != 0)
{
printf ("mq_close failed: %m\n");
result = 1;
}
if (mq_close (q3) != 0)
{
printf ("mq_close failed: %m\n");
result = 1;
}
return result;
}
#include "../test-skeleton.c"

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _MQUEUE_H
# error "Never use <bits/mqueue.h> directly; include <mqueue.h> instead."
#endif
typedef int mqd_t;
struct mq_attr
{
long int mq_flags; /* Message queue flags. */
long int mq_maxmsg; /* Maximum number of messages. */
long int mq_msgsize; /* Maximum message size. */
long int mq_curmsgs; /* Number of messages currently queued. */
};

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Removes the association between message queue descriptor MQDES and its
message queue. */
int
mq_close (mqd_t mqdes)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (mq_close)
#include <stub-tag.h>

View File

@ -0,0 +1,30 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Query status and attributes of message queue MQDES. */
int
mq_getattr (mqd_t mqdes, struct mq_attr *mqstat)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (mq_getattr)
#include <stub-tag.h>

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Register notification upon message arrival to an empty message queue
MQDES. */
int
mq_notify (mqd_t mqdes, const struct sigevent *notification)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (mq_notify)
#include <stub-tag.h>

36
sysdeps/generic/mq_open.c Normal file
View File

@ -0,0 +1,36 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Establish connection between a process and a message queue NAME and
return message queue descriptor or (mqd_t) -1 on error. OFLAG determines
the type of access used. If O_CREAT is on OFLAG, the third argument is
taken as a `mode_t', the mode of the created message queue, and the fourth
argument is taken as `struct mq_attr *', pointer to message queue
attributes. If the fourth argument is NULL, default attributes are
used. */
mqd_t
mq_open (const char *name, int oflag, ...)
{
__set_errno (ENOSYS);
return (mqd_t) -1;
}
stub_warning (mq_open)
#include <stub-tag.h>

View File

@ -0,0 +1,32 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Receive the oldest from highest priority messages in message queue
MQDES. */
ssize_t
mq_receive (mqd_t mqdes, char *msg_ptr, size_t msg_len,
unsigned int *msg_prio)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (mq_receive)
#include <stub-tag.h>

31
sysdeps/generic/mq_send.c Normal file
View File

@ -0,0 +1,31 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Add message pointed by MSG_PTR to message queue MQDES. */
int
mq_send (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
unsigned int msg_prio)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (mq_send)
#include <stub-tag.h>

View File

@ -0,0 +1,33 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Set attributes associated with message queue MQDES and if OMQSTAT is
not NULL also query its old attributes. */
int
mq_setattr (mqd_t mqdes, const struct mq_attr *__restrict mqstat,
struct mq_attr *__restrict omqstat)
{
__set_errno (ENOSYS);
return -1;
}
hidden_def (mq_setattr)
stub_warning (mq_setattr)
#include <stub-tag.h>

View File

@ -0,0 +1,34 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Receive the oldest from highest priority messages in message queue
MQDES, stop waiting if ABS_TIMEOUT expires. */
ssize_t
mq_timedreceive (mqd_t mqdes, char *__restrict msg_ptr, size_t msg_len,
unsigned int *__restrict msg_prio,
const struct timespec *__restrict abs_timeout)
{
__set_errno (ENOSYS);
return -1;
}
hidden_def (mq_timedreceive)
stub_warning (mq_timedreceive)
#include <stub-tag.h>

View File

@ -0,0 +1,33 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Add message pointed by MSG_PTR to message queue MQDES, stop blocking
on full message queue if ABS_TIMEOUT expires. */
int
mq_timedsend (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
unsigned int msg_prio, const struct timespec *abs_timeout)
{
__set_errno (ENOSYS);
return -1;
}
hidden_def (mq_timedsend)
stub_warning (mq_timedsend)
#include <stub-tag.h>

View File

@ -0,0 +1,30 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
/* Remove message queue named NAME. */
int
mq_unlink (const char *name)
{
__set_errno (ENOSYS);
return -1;
}
stub_warning (mq_unlink)
#include <stub-tag.h>

View File

@ -63,3 +63,6 @@
/* Maximum host name length. */
#define HOST_NAME_MAX 64
/* Maximum message queue priority level. */
#define MQ_PRIO_MAX 32768

View File

@ -0,0 +1,32 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _MQUEUE_H
# error "Never use <bits/mqueue.h> directly; include <mqueue.h> instead."
#endif
typedef int mqd_t;
struct mq_attr
{
long int mq_flags; /* Message queue flags. */
long int mq_maxmsg; /* Maximum number of messages. */
long int mq_msgsize; /* Maximum message size. */
long int mq_curmsgs; /* Number of messages currently queued. */
long int __pad[4];
};

View File

@ -0,0 +1,35 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
#include <sysdep.h>
#ifdef __NR_mq_open
/* Removes the association between message queue descriptor MQDES and its
message queue. */
int
mq_close (mqd_t mqdes)
{
return INLINE_SYSCALL (close, 1, mqdes);
}
#else
# include <sysdeps/generic/mq_close.c>
#endif

View File

@ -0,0 +1,34 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
#include <sysdep.h>
#ifdef __NR_mq_getsetattr
/* Query status and attributes of message queue MQDES. */
int
mq_getattr (mqd_t mqdes, struct mq_attr *mqstat)
{
return mq_setattr (mqdes, NULL, mqstat);
}
#else
# include <sysdeps/generic/mq_getattr.c>
#endif

View File

@ -0,0 +1,43 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
#include <sysdep.h>
#ifdef __NR_mq_notify
/* Register notification upon message arrival to an empty message queue
MQDES. */
int
mq_notify (mqd_t mqdes, const struct sigevent *notification)
{
/* mq_notify which handles SIGEV_THREAD is included in the thread
add-on. */
if (notification != NULL
&& notification->sigev_notify == SIGEV_THREAD)
{
__set_errno (ENOSYS);
return -1;
}
return INLINE_SYSCALL (mq_notify, 2, mqdes, notification);
}
#else
# include <sysdeps/generic/mq_notify.c>
#endif

View File

@ -0,0 +1,59 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
#include <stdarg.h>
#include <sysdep.h>
#ifdef __NR_mq_open
/* Establish connection between a process and a message queue NAME and
return message queue descriptor or (mqd_t) -1 on error. OFLAG determines
the type of access used. If O_CREAT is on OFLAG, the third argument is
taken as a `mode_t', the mode of the created message queue, and the fourth
argument is taken as `struct mq_attr *', pointer to message queue
attributes. If the fourth argument is NULL, default attributes are
used. */
mqd_t
mq_open (const char *name, int oflag, ...)
{
if (name[0] != '/')
{
__set_errno (EINVAL);
return -1;
}
mode_t mode = 0;
struct mq_attr *attr = NULL;
if (oflag & O_CREAT)
{
va_list ap;
va_start (ap, oflag);
mode = va_arg (ap, mode_t);
attr = va_arg (ap, struct mq_attr *);
va_end (ap);
}
return INLINE_SYSCALL (mq_open, 4, name + 1, oflag, mode, attr);
}
#else
# include <sysdeps/generic/mq_open.c>
#endif

View File

@ -0,0 +1,36 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
#include <sysdep.h>
#ifdef __NR_mq_timedreceive
/* Receive the oldest from highest priority messages in message queue
MQDES. */
ssize_t
mq_receive (mqd_t mqdes, char *msg_ptr, size_t msg_len,
unsigned int *msg_prio)
{
return mq_timedreceive (mqdes, msg_ptr, msg_len, msg_prio, NULL);
}
#else
# include <sysdeps/generic/mq_receive.c>
#endif

View File

@ -0,0 +1,35 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
#include <sysdep.h>
#ifdef __NR_mq_timedsend
/* Add message pointed by MSG_PTR to message queue MQDES. */
int
mq_send (mqd_t mqdes, const char *msg_ptr, size_t msg_len,
unsigned int msg_prio)
{
return mq_timedsend (mqdes, msg_ptr, msg_len, msg_prio, NULL);
}
#else
# include <sysdeps/generic/mq_send.c>
#endif

View File

@ -0,0 +1,39 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <mqueue.h>
#include <sysdep.h>
#ifdef __NR_mq_unlink
/* Remove message queue named NAME. */
int
mq_unlink (const char *name)
{
if (name[0] != '/')
{
__set_errno (EINVAL);
return -1;
}
return INLINE_SYSCALL (mq_unlink, 1, name + 1);
}
#else
# include <sysdeps/generic/mq_unlink.c>
#endif

View File

@ -86,3 +86,7 @@ flistxattr - flistxattr i:isi flistxattr
removexattr - removexattr i:ss removexattr
lremovexattr - lremovexattr i:ss lremovexattr
fremovexattr - fremovexattr i:is fremovexattr
mq_timedsend - mq_timedsend Ci:ipiip __GI_mq_timedsend mq_timedsend
mq_timedreceive - mq_timedreceive Ci:ipipp __GI_mq_timedreceive mq_timedreceive
mq_setattr - mq_getsetattr i:ipp __GI_mq_setattr mq_setattr