(root)/
strace-6.5/
tests-m32/
semtimedop-common.c
       1  /*
       2   * This file is part of semtimedop* strace tests.
       3   *
       4   * Copyright (c) 2016-2021 The strace developers.
       5   * All rights reserved.
       6   *
       7   * SPDX-License-Identifier: GPL-2.0-or-later
       8   */
       9  
      10  #include <sys/ipc.h>
      11  #include <sys/sem.h>
      12  #include <stdint.h>
      13  #include <stdio.h>
      14  #include <stdlib.h>
      15  #include <unistd.h>
      16  #include "kernel_timespec.h"
      17  
      18  #define XLAT_MACROS_ONLY
      19  # include "xlat/semop_flags.h"
      20  #undef XLAT_MACROS_ONLY
      21  
      22  static long
      23  k_semtimedop_imp(const kernel_ulong_t semid,
      24  		 const kernel_ulong_t sops,
      25  		 const kernel_ulong_t nsops,
      26  		 const kernel_ulong_t timeout);
      27  
      28  static const char *errstr;
      29  
      30  static long
      31  k_semtimedop(const unsigned int semid,
      32  	     void *const sops,
      33  	     const size_t nsops,
      34  	     const void *const timeout)
      35  {
      36  	static const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced0defacedULL;
      37  	static const kernel_ulong_t k_1 = (kernel_ulong_t) -1;
      38  	const kernel_ulong_t k_semid = semid | (fill & (k_1 - -1U));
      39  	const kernel_ulong_t k_sops = f8ill_ptr_to_kulong(sops);
      40  	const kernel_ulong_t k_nsops = nsops | (fill & (k_1 - (size_t) -1));
      41  	const kernel_ulong_t k_timeout = f8ill_ptr_to_kulong(timeout);
      42  	const long rc = k_semtimedop_imp(k_semid, k_sops, k_nsops, k_timeout);
      43  	errstr = sprintrc(rc);
      44  	return rc;
      45  }
      46  
      47  static int id = -1;
      48  
      49  static void
      50  cleanup(void)
      51  {
      52  	semctl(id, 0, IPC_RMID, 0);
      53  	id = -1;
      54  }
      55  
      56  int
      57  main(void)
      58  {
      59  	static const int bogus_semid = 0xfdb97531;
      60  	static void * const bogus_sops = (void *) -1UL;
      61  	static const size_t bogus_nsops = (size_t) 0xdefaceddeadbeefULL;
      62  
      63  	TAIL_ALLOC_OBJECT_CONST_PTR(semtimedop_timespec_t, ts);
      64  
      65  	id = semget(IPC_PRIVATE, 1, 0600);
      66  	if (id < 0)
      67  		perror_msg_and_skip("semget");
      68  	atexit(cleanup);
      69  
      70  	union {
      71  		int val;
      72  		void *buf;
      73  	} sem_union = { .val = 0 };
      74  	if (semctl(id, 0, SETVAL, sem_union) == -1)
      75  		perror_msg_and_skip("semctl");
      76  
      77  	TAIL_ALLOC_OBJECT_CONST_PTR(struct sembuf, sem_b);
      78  	TAIL_ALLOC_OBJECT_CONST_PTR(struct sembuf, sem_b2);
      79  
      80  	k_semtimedop(bogus_semid, NULL, bogus_nsops, NULL);
      81  	printf("%s(%d, NULL, %u, NULL) = %s\n",
      82  	       SYSCALL_NAME, bogus_semid, (unsigned) bogus_nsops, errstr);
      83  
      84  	k_semtimedop(bogus_semid, bogus_sops, 1, NULL);
      85  	printf("%s(%d, %p, %u, NULL) = %s\n",
      86  	       SYSCALL_NAME, bogus_semid, bogus_sops, 1, errstr);
      87  
      88  	sem_b->sem_num = 0;
      89  	sem_b->sem_op = 1;
      90  	sem_b->sem_flg = SEM_UNDO;
      91  
      92  	sem_b2->sem_num = 0xface;
      93  	sem_b2->sem_op = 0xf00d;
      94  	sem_b2->sem_flg = 0xbeef;
      95  
      96  	k_semtimedop(bogus_semid, sem_b2, 2, NULL);
      97  	printf("%s(%d, [{sem_num=%hu, sem_op=%hd, sem_flg=%s%s%#hx}"
      98  	       ", ... /* %p */], %u, NULL) = %s\n",
      99  	       SYSCALL_NAME, bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
     100  	       sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",
     101  	       sem_b2->sem_flg & IPC_NOWAIT ? "IPC_NOWAIT|" : "",
     102  	       (short) (sem_b2->sem_flg & ~(SEM_UNDO | IPC_NOWAIT)),
     103  	       sem_b2 + 1, 2, errstr);
     104  
     105  	if (k_semtimedop(id, sem_b, 1, NULL))
     106  		perror_msg_and_skip(SYSCALL_NAME ", 1");
     107  	printf("%s(%d, [{sem_num=0, sem_op=1, sem_flg=SEM_UNDO}], 1, NULL) = 0\n", SYSCALL_NAME, id);
     108  
     109  	sem_b->sem_op = -1;
     110  	if (k_semtimedop(id, sem_b, 1, NULL))
     111  		perror_msg_and_skip(SYSCALL_NAME ", -1");
     112  	printf("%s(%d, [{sem_num=0, sem_op=-1, sem_flg=SEM_UNDO}], 1, NULL) = 0\n", SYSCALL_NAME, id);
     113  
     114  	k_semtimedop(bogus_semid, NULL, bogus_nsops, NULL);
     115  	printf("%s(%d, NULL, %u, NULL) = %s\n",
     116  	       SYSCALL_NAME, bogus_semid, (unsigned) bogus_nsops, errstr);
     117  
     118  	k_semtimedop(id, sem_b + 1, 1, ts + 1);
     119  	printf("%s(%d, %p, 1, %p) = %s\n",
     120  	       SYSCALL_NAME, id, sem_b + 1, ts + 1, errstr);
     121  
     122  	ts->tv_sec = 1;
     123  	ts->tv_nsec = 123456789;
     124  	k_semtimedop(bogus_semid, sem_b2, 2, ts);
     125  	printf("%s(%d, [{sem_num=%hu, sem_op=%hd, sem_flg=%s%s%#hx}"
     126  	       ", ... /* %p */], %u, {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
     127  	       SYSCALL_NAME, bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
     128  	       sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",
     129  	       sem_b2->sem_flg & IPC_NOWAIT ? "IPC_NOWAIT|" : "",
     130  	       (short) (sem_b2->sem_flg & ~(SEM_UNDO | IPC_NOWAIT)),
     131  	       sem_b2 + 1, 2,
     132  	       (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec),
     133  	       errstr);
     134  
     135  	sem_b->sem_op = 1;
     136  	if (k_semtimedop(id, sem_b, 1, NULL))
     137  		perror_msg_and_skip(SYSCALL_NAME ", 1");
     138  	printf("%s(%d, [{sem_num=0, sem_op=1, sem_flg=SEM_UNDO}], 1, NULL) = 0\n", SYSCALL_NAME, id);
     139  
     140  	sem_b->sem_op = -1;
     141  	if (k_semtimedop(id, sem_b, 1, ts))
     142  		perror_msg_and_skip(SYSCALL_NAME ", -1");
     143  	printf("%s(%d, [{sem_num=0, sem_op=-1, sem_flg=SEM_UNDO}], 1"
     144  	       ", {tv_sec=%lld, tv_nsec=%llu}) = 0\n",
     145  	       SYSCALL_NAME, id,
     146  	       (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec));
     147  
     148  	sem_b->sem_op = 1;
     149  	ts->tv_sec = 0xdeadbeefU;
     150  	ts->tv_nsec = 0xfacefeedU;
     151  	k_semtimedop(id, sem_b, 1, ts);
     152  	printf("%s(%d, [{sem_num=0, sem_op=1, sem_flg=SEM_UNDO}], 1"
     153  	       ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
     154  	       SYSCALL_NAME, id, (long long) ts->tv_sec,
     155  	       zero_extend_signed_to_ull(ts->tv_nsec), errstr);
     156  
     157  	sem_b->sem_op = -1;
     158  	ts->tv_sec = (typeof(ts->tv_sec)) 0xcafef00ddeadbeefLL;
     159  	ts->tv_nsec = (typeof(ts->tv_nsec)) 0xbadc0dedfacefeedLL;
     160  	k_semtimedop(id, sem_b, 1, ts);
     161  	printf("%s(%d, [{sem_num=0, sem_op=-1, sem_flg=SEM_UNDO}], 1"
     162  	       ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
     163  	       SYSCALL_NAME, id, (long long) ts->tv_sec,
     164  	       zero_extend_signed_to_ull(ts->tv_nsec), errstr);
     165  
     166  	puts("+++ exited with 0 +++");
     167  	return 0;
     168  }