]> granicus.if.org Git - strace/blob - tests/ipc.c
Update copyright headers
[strace] / tests / ipc.c
1 /*
2  * Check decoding of ipc syscall.
3  *
4  * Copyright (c) 2016-2018 Dmitry V. Levin <ldv@altlinux.org>
5  * All rights reserved.
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9
10 #include "tests.h"
11 #include <asm/unistd.h>
12
13 #if defined __NR_ipc && defined HAVE_LINUX_IPC_H
14
15 # include <errno.h>
16 # include <stdio.h>
17 # include <unistd.h>
18 # include <linux/ipc.h>
19
20 # ifndef SEMCTL
21 #  define SEMCTL 3
22 # endif
23 # ifndef MSGRCV
24 #  define MSGRCV 12
25 # endif
26
27 static int
28 ipc_call(const unsigned short version, const unsigned short call,
29          long a1, long a2, long a3, long a4, long a5)
30 {
31         const unsigned long val =
32                 (unsigned long) 0xfacefeed00000000ULL |
33                 (unsigned int) version << 16 |
34                 call;
35
36         return syscall(__NR_ipc, val, a1, a2, a3, a4, a5);
37 }
38
39 static int
40 ipc_call0(const unsigned short version, const unsigned short call)
41 {
42         int rc = ipc_call(version, call, 0, 0, 0, 0, 0);
43         int saved_errno = errno;
44         printf("ipc(");
45         if (version)
46                 printf("%hu<<16|", version);
47         errno = saved_errno;
48         printf("%hu, 0, 0, 0, 0%s) = %d %s (%m)\n", call,
49 # ifdef __s390__
50                "",
51 # else
52                ", 0",
53 # endif
54                rc, errno2name());
55         return rc;
56 }
57
58 int
59 main(void)
60 {
61         void *const efault = tail_alloc(1) + 1;
62
63         int rc = ipc_call(0, SEMCTL, 0, 0, 0, (long) efault, 0);
64         if (rc != -1 || EFAULT != errno)
65                 perror_msg_and_skip("ipc");
66         printf("semctl(0, 0, IPC_RMID, %p) = -1 EFAULT (%m)\n", efault);
67
68         unsigned short call;
69         for (call = 0; call <= 40; call += 10) {
70                 ipc_call0(0, call);
71                 ipc_call0(42, call);
72         }
73
74         rc = ipc_call(42, SEMCTL, 0, 0, 0, (long) efault, 0);
75         int test_version = EFAULT == errno;
76         if (test_version)
77                 printf("semctl(0, 0, IPC_RMID, %p) = %d %s (%m)\n",
78                        efault, rc, errno2name());
79         else
80                 printf("ipc(42<<16|SEMCTL, 0, 0, 0, %p) = %d %s (%m)\n",
81                        efault, rc, errno2name());
82
83         if (test_version) {
84                 const int msqid = -2;
85                 const long msgsz = -3;
86                 const long msgtyp = 0;
87
88                 rc = ipc_call(1, MSGRCV,
89                               msqid, msgsz, IPC_NOWAIT, (long) efault, msgtyp);
90                 printf("msgrcv(%d, %p, %lu, %ld, IPC_NOWAIT) = %d %s (%m)\n",
91                        msqid, efault, msgsz, msgtyp, rc, errno2name());
92         }
93
94         puts("+++ exited with 0 +++");
95         return 0;
96 }
97
98 #else
99
100 SKIP_MAIN_UNDEFINED("__NR_ipc && HAVE_LINUX_IPC_H")
101
102 #endif