(root)/
glibc-2.38/
sysdeps/
pthread/
tst-umask1.c
       1  /* Copyright (C) 2003-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <fcntl.h>
      19  #include <pthread.h>
      20  #include <stdbool.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  #include <unistd.h>
      24  #include <sys/stat.h>
      25  
      26  
      27  static struct
      28  {
      29    int (*fp) (const char *, mode_t);
      30    const char *name;
      31    bool is_fd;
      32  } fcts[] =
      33  {
      34    { creat, "creat", true },
      35    { mkdir, "mkdir", false },
      36    { mkfifo, "mkfifo", false },
      37  };
      38  #define nfcts (sizeof (fcts) / sizeof (fcts[0]))
      39  
      40  
      41  static int
      42  work (const char *fname, int mask)
      43  {
      44    int result = 0;
      45    size_t i;
      46    for (i = 0; i < nfcts; ++i)
      47      {
      48        remove (fname);
      49        int fd = fcts[i].fp (fname, 0777);
      50        if (fd == -1)
      51  	{
      52  	  printf ("cannot %s %s: %m\n", fcts[i].name, fname);
      53  	  exit (1);
      54  	}
      55        if (fcts[i].is_fd)
      56  	close (fd);
      57        struct stat64 st;
      58        if (stat64 (fname, &st) == -1)
      59  	{
      60  	  printf ("cannot stat %s after %s: %m\n", fname, fcts[i].name);
      61  	  exit (1);
      62  	}
      63  
      64        if ((st.st_mode & mask) != 0)
      65  	{
      66  	  printf ("mask not successful after %s: %x still set\n",
      67  		  fcts[i].name, (unsigned int) (st.st_mode & mask));
      68  	  result = 1;
      69  	}
      70      }
      71  
      72    return result;
      73  }
      74  
      75  
      76  static pthread_barrier_t bar;
      77  
      78  
      79  static void *
      80  tf (void *arg)
      81  {
      82    pthread_barrier_wait (&bar);
      83  
      84    int result = work (arg, 022);
      85  
      86    pthread_barrier_wait (&bar);
      87  
      88    pthread_barrier_wait (&bar);
      89  
      90    return (work (arg, 0) | result) ? (void *) -1l : NULL;
      91  }
      92  
      93  
      94  static int
      95  do_test (const char *fname)
      96  {
      97    int result = 0;
      98  
      99    umask (0);
     100    result |= work (fname, 0);
     101  
     102    pthread_barrier_init (&bar, NULL, 2);
     103  
     104    pthread_t th;
     105    if (pthread_create (&th, NULL, tf, (void *) fname) != 0)
     106      {
     107        puts ("cannot create thread");
     108        exit (1);
     109      }
     110  
     111    umask (022);
     112    result |= work (fname, 022);
     113  
     114    pthread_barrier_wait (&bar);
     115  
     116    pthread_barrier_wait (&bar);
     117  
     118    umask (0);
     119  
     120    pthread_barrier_wait (&bar);
     121  
     122    void *res;
     123    if (pthread_join (th, &res) != 0)
     124      {
     125        puts ("join failed");
     126        exit (1);
     127      }
     128  
     129    remove (fname);
     130  
     131    return result || res != NULL;
     132  }
     133  
     134  #define TEST_FUNCTION do_test (argc < 2 ? "/tmp/tst-umask.tmp" : argv[1])
     135  #include "../test-skeleton.c"