(root)/
glibc-2.38/
sysvipc/
test-sysvshm.c
       1  /* Basic tests for SYSV shared memory functions.
       2     Copyright (C) 2016-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <stdio.h>
      20  #include <stdlib.h>
      21  #include <errno.h>
      22  #include <string.h>
      23  #include <unistd.h>
      24  #include <sys/types.h>
      25  #include <sys/ipc.h>
      26  #include <sys/shm.h>
      27  
      28  #include <test-sysvipc.h>
      29  
      30  #include <support/support.h>
      31  #include <support/check.h>
      32  #include <support/temp_file.h>
      33  
      34  /* These are for the temporary file we generate.  */
      35  static char *name;
      36  static int shmid;
      37  
      38  static void
      39  remove_shm (void)
      40  {
      41    /* Enforce message queue removal in case of early test failure.
      42       Ignore error since the shm may already have being removed.  */
      43    shmctl (shmid, IPC_RMID, 0);
      44  }
      45  
      46  static void
      47  do_prepare (int argc, char *argv[])
      48  {
      49    int fd = create_temp_file ("tst-sysvshm.", &name);
      50    if (fd == -1)
      51      FAIL_EXIT1 ("cannot create temporary file (errno=%d)", errno);
      52  }
      53  
      54  #define PREPARE do_prepare
      55  
      56  /* It is not an extensive test, but rather a functional one aimed to check
      57     correct parameter passing on kernel.  */
      58  
      59  #define CHECK_EQ(v, k) \
      60    if ((v) != (k)) \
      61      FAIL_EXIT1("%d != %d", v, k)
      62  
      63  #define SHM_MODE 0666
      64  
      65  static int
      66  do_test (void)
      67  {
      68    atexit (remove_shm);
      69  
      70    key_t key = ftok (name, 'G');
      71    if (key == -1)
      72      FAIL_EXIT1 ("ftok failed");
      73  
      74    long int pgsz = sysconf (_SC_PAGESIZE);
      75    if (pgsz == -1)
      76      FAIL_EXIT1 ("sysconf (_SC_PAGESIZE) failed (errno = %d)", errno);
      77  
      78    shmid = shmget(key, pgsz, IPC_CREAT | IPC_EXCL | SHM_MODE);
      79    if (shmid == -1)
      80      {
      81        if (errno == ENOSYS)
      82  	FAIL_UNSUPPORTED ("shmget not supported");
      83        FAIL_EXIT1 ("shmget failed (errno=%d)", errno);
      84      }
      85  
      86    TEST_COMPARE (shmctl (shmid, first_shm_invalid_cmd (), NULL), -1);
      87    TEST_COMPARE (errno, EINVAL);
      88  
      89    /* Get shared memory kernel information and do some sanity checks.  */
      90    struct shmid_ds shminfo;
      91    if (shmctl (shmid, IPC_STAT, &shminfo) == -1)
      92      FAIL_EXIT1 ("shmctl with IPC_STAT failed (errno=%d)", errno);
      93  
      94    if (shminfo.shm_perm.__key != key)
      95      FAIL_EXIT1 ("shmid_ds::shm_perm::key (%d) != %d",
      96  		(int) shminfo.shm_perm.__key, (int) key);
      97    if (shminfo.shm_perm.mode != SHM_MODE)
      98      FAIL_EXIT1 ("shmid_ds::shm_perm::mode (%o) != %o",
      99  		shminfo.shm_perm.mode, SHM_MODE);
     100    if (shminfo.shm_segsz != pgsz)
     101      FAIL_EXIT1 ("shmid_ds::shm_segsz (%lu) != %lu",
     102  		(long unsigned) shminfo.shm_segsz, pgsz);
     103  
     104    /* Attach on shared memory and realize some operations.  */
     105    int *shmem = shmat (shmid, NULL, 0);
     106    if (shmem == (void*) -1)
     107      FAIL_EXIT1 ("shmem failed (errno=%d)", errno);
     108  
     109    shmem[0]   = 0x55555555;
     110    shmem[32]  = 0x44444444;
     111    shmem[64]  = 0x33333333;
     112    shmem[128] = 0x22222222;
     113  
     114    if (shmdt (shmem) == -1)
     115      FAIL_EXIT1 ("shmem failed (errno=%d)", errno);
     116  
     117    shmem = shmat (shmid, NULL, SHM_RDONLY);
     118    if (shmem == (void*) -1)
     119      FAIL_EXIT1 ("shmem failed (errno=%d)", errno);
     120  
     121    CHECK_EQ (shmem[0],   0x55555555);
     122    CHECK_EQ (shmem[32],  0x44444444);
     123    CHECK_EQ (shmem[64],  0x33333333);
     124    CHECK_EQ (shmem[128], 0x22222222);
     125  
     126    if (shmdt (shmem) == -1)
     127      FAIL_EXIT1 ("shmem failed (errno=%d)", errno);
     128  
     129    /* Finally free up the semnaphore resource.  */
     130    if (shmctl (shmid, IPC_RMID, 0) == -1)
     131      FAIL_EXIT1 ("semctl failed (errno=%d)", errno);
     132  
     133    return 0;
     134  }
     135  
     136  #include <support/test-driver.c>