The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/tools/tests/xnu_quick_test/misc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 
    2 #include "tests.h"
    3 
    4 /*
    5  * create_random_name - creates a file with a random / unique name in the given directory.
    6  * when do_open is true we create a file else we generaate a name that does not exist in the
    7  * given directory (we do not create anything when do_open is 0).
    8  * WARNING - caller provides enough space in path buffer for longest possible name.
    9  * WARNING - assumes caller has appended a trailing '/' on the path passed to us.
   10  * RAND_MAX is currently 2147483647 (ten characters plus one for a slash)
   11  */
   12 int create_random_name( char *the_pathp, int do_open ) {
   13         int             i, my_err;
   14         int             my_fd = -1;
   15         
   16     for ( i = 0; i < 1; i++ ) {
   17         int                     my_rand;
   18         char            *myp;
   19         char            my_name[32];
   20         
   21         my_rand = rand( );
   22         sprintf( &my_name[0], "%d", my_rand );
   23         if ( (strlen( &my_name[0] ) + strlen( the_pathp ) + 2) > PATH_MAX ) {
   24             printf( "%s - path to test file greater than PATH_MAX \n", __FUNCTION__ );
   25             return( -1 );
   26         }
   27 
   28         // append generated file name onto our path
   29         myp = strrchr( the_pathp, '/' );
   30         *(myp + 1) = 0x00;
   31         strcat( the_pathp, &my_name[0] );
   32                 if ( do_open ) {
   33                         /* create a file with this name */
   34                         my_fd = open( the_pathp, (O_RDWR | O_CREAT | O_EXCL),
   35                                                         (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
   36                         if ( my_fd == -1 ) {
   37                                 if ( errno != EEXIST ) {
   38                                         printf( "%s - open failed with errno %d - %s \n",
   39                                                         __FUNCTION__, errno, strerror( errno ) );
   40                                         return( -1 );
   41                                 }
   42                                 // name already exists, try another
   43                                 i--;
   44                                 continue;
   45                         }
   46                 }
   47                 else {
   48                         /* make sure the name is unique */
   49                         struct stat             my_sb;
   50                         my_err = stat( the_pathp, &my_sb );
   51                         if ( my_err != 0 ) {
   52                                 if ( errno == ENOENT ) {
   53                                         break;
   54                                 }
   55                                 else {
   56                                         printf( "%s - open failed with errno %d - %s \n",
   57                                                         __FUNCTION__, errno, strerror( errno ) );
   58                                         return( -1 );
   59                                 }
   60                         }
   61                         /* name already exists, try another */
   62                         i--;
   63                         continue;
   64                 }
   65     }
   66         
   67         if ( my_fd != -1 )
   68                 close( my_fd );
   69         
   70         return( 0 );
   71         
   72 } /* create_random_name */
   73 
   74 /*
   75  * create_file_with_name - create a file in the given target directory using the given name.
   76  * If an existing file or directory is present use the value of remove_existing to determine if the
   77  * object is to be deleted.
   78  * returns 0 if file could be created, 1 if file exists, 2 if directory exists, else -1 
   79  * NOTE - will fail if a directory is present with the given name and it is not empty.
   80  */
   81 int create_file_with_name( char *the_target_dirp, char *the_namep, int remove_existing ) {
   82         int                             create_test_file, my_err, my_result;
   83         int                             my_fd = -1;
   84         char *                  my_pathp = NULL;
   85         struct stat             my_sb;
   86         
   87         create_test_file = 0;
   88         my_pathp = (char *) malloc( PATH_MAX );
   89         if ( my_pathp == NULL ) {
   90                 printf( "malloc failed with error %d - \"%s\" \n", errno, strerror( errno) );
   91                 goto failure_exit;
   92         }
   93         strcpy( my_pathp, the_target_dirp );
   94         strcat( my_pathp, the_namep );
   95 
   96         /* make sure the name is unique */
   97         my_result = 0;
   98         my_err = stat( my_pathp, &my_sb );
   99         if ( my_err != 0 ) {
  100                 create_test_file = 1;
  101                 if ( errno != ENOENT ) {
  102                         goto failure_exit;
  103                 }
  104         }
  105         else {
  106                 /* name already exists */
  107                 if ( S_ISDIR( my_sb.st_mode ) ) {
  108                         my_result = 2; /* tell caller directory exists with target name */
  109                         if ( remove_existing ) {
  110                                 my_err = rmdir( my_pathp );
  111                                 if ( my_err == -1 ) {
  112                                         printf( "rmdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
  113                                         goto failure_exit;
  114                                 }
  115                                 create_test_file = 1;
  116                         }
  117                 }
  118                 else {
  119                         my_result = 1; /* tell caller file exists with target name */
  120                         if ( remove_existing ) {
  121                                 my_err = unlink( my_pathp );
  122                                 if ( my_err == -1 ) {
  123                                         printf( "unlink failed with error %d - \"%s\" \n", errno, strerror( errno) );
  124                                         goto failure_exit;
  125                                 }
  126                                 create_test_file = 1;
  127                         }
  128                 }
  129         }
  130         
  131         if ( create_test_file ) {
  132                 /* create a file with this name */
  133                 my_fd = open( my_pathp, (O_RDWR | O_CREAT | O_EXCL),
  134                                                 (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
  135                 if ( my_fd == -1 ) {
  136                         printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
  137                         goto failure_exit;
  138                 }
  139                 close( my_fd );
  140         } 
  141         goto routine_exit;
  142 
  143 failure_exit:   
  144         my_result = -1;
  145 routine_exit:
  146         if ( my_pathp != NULL ) {
  147                 if ( my_result == -1 && create_test_file ) {
  148                         remove( my_pathp );     
  149                 }
  150                 free( my_pathp );
  151          }
  152         
  153         return( my_result );
  154         
  155 } /* create_file_with_name */
  156 
  157 
  158 
  159 
  160 /*
  161  * This function is needed by both xnu_quick_test proper and the execve() helper
  162  * program. It forks a child process and then exec()s an image on that child.
  163  * Path, argv, and envp are fed directly to the execve() call.
  164  * Parameter killwait decides how long to wait before killing the child.
  165  */
  166 int do_execve_test(char * path, char * argv[], void * envp, int killwait)
  167 {
  168         int     my_err = 0, my_status;
  169         pid_t   my_pid, my_wait_pid;
  170 
  171 #if DEBUG
  172         printf("do_execve_test(path = %s)\n", path);
  173         printf("CWD= %s\n", getwd(NULL));
  174         fflush(stdout);
  175 #endif
  176         /* vfork then execve sleep system command (which we will kill from the parent process) */
  177         my_pid = vfork();
  178         if (my_pid == -1) {
  179                 printf( "vfork failed with errno %d - %s \n", errno, strerror( errno ) );
  180                 goto test_failed_exit;
  181         }
  182         if ( my_pid == 0 ) {
  183                 /* 
  184                  * child process - use execve to start one of the customized helper
  185                  * binaries, which just sleep for 120 seconds. Let our parent kill us.
  186                  */
  187 
  188                 my_err = execve(path, argv, envp);
  189                 if ( my_err != 0 ) { /* TODO: execve() on x86_64 inca returns weird error codes, see rdar://4655612 */
  190                         printf( "execve call failed with return value: %d, errno: %d - \"%s\"; path: %s \n",
  191                                 my_err, errno, strerror( errno), path );
  192                         fflush(stdout);
  193                         exit(-2);
  194                 }
  195 
  196                 /* should never get here */
  197                 printf("Execve failed and it was not caught by our test\n");
  198                 return(-1);
  199         }
  200         /* 
  201          * parent process - let's kill our sleeping child
  202          */     
  203         sleep(killwait);
  204         my_err = kill( my_pid, SIGKILL );
  205         if ( my_err == -1 ) {
  206                 printf( "kill call failed with error %d - \"%s\" \n", errno, strerror( errno) );
  207                 goto test_failed_exit;
  208         }
  209 
  210         /* wait for child to exit */
  211         my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
  212         if ( my_wait_pid == -1 ) {
  213                 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
  214                 goto test_failed_exit;
  215         }
  216 
  217         /* wait4 should return our child's pid when it exits */
  218         if ( my_wait_pid != my_pid ) {
  219                 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
  220                 goto test_failed_exit;
  221         }       
  222 
  223         if ( WIFSIGNALED( my_status ) && WTERMSIG( my_status ) != SIGKILL ) {
  224                 printf( "wait4 returned wrong signal status - 0x%02X \n", my_status );
  225                 goto test_failed_exit;
  226         }
  227 
  228         my_err = 0;
  229         goto test_passed_exit;
  230 
  231 test_failed_exit:
  232         my_err = 1;
  233 
  234 test_passed_exit:
  235         return( my_err );
  236 } /* do_execve_test */
  237 
  238 /*
  239  * Helper function for posix_spawn test
  240  *      arch: target architecture to spawn for
  241  */
  242 int do_spawn_test(int arch, int shouldfail)
  243 {
  244         int my_err, my_pid, my_status;
  245         size_t my_size;
  246         posix_spawnattr_t attr;
  247 
  248         char * args[] = {"helpers/arch", NULL};
  249 
  250         my_err = posix_spawnattr_init(&attr);
  251         if (my_err != 0) {
  252                 printf("posix_spawnattr_init failed\n");
  253                 goto done;
  254         }
  255 
  256         /* set spawn to only succeed for arch 'arch' */
  257         my_err = posix_spawnattr_setbinpref_np(&attr, 1, &arch, &my_size);
  258         if (my_err != 0 || my_size != 1) {
  259                 printf("posix_spawnattr_setbinpref_np failed\n");
  260                 goto done;
  261         }
  262 
  263         /* spawn off child process */
  264         my_err = posix_spawn(&my_pid, args[0], NULL, &attr, args, NULL);
  265         if (shouldfail) {
  266                 if( my_err == 0) {
  267                         printf("posix_spawn should have failed on arch %d\n", arch);
  268                         goto done;
  269                 }
  270                 my_err = 0;
  271         } else {
  272                 /* child should exit with return code == arch */
  273                 if (my_err != 0) {
  274                         printf("posix_spawn failed with errno %d - %s\n", errno, strerror(errno));
  275                         goto done;
  276                 }
  277 
  278                 my_err = wait4(my_pid, &my_status, 0, NULL);
  279                 if (my_err == -1) {
  280                         printf("wait4 failed with errno %d - %s\n", errno, strerror(errno));
  281                         goto done;
  282                 }
  283                 my_err = 0;
  284 
  285                 if (WEXITSTATUS(my_status) != (arch & 0xff)) {
  286                         printf("child exited with status %d (expected %d)\n", 
  287                                         (WEXITSTATUS(my_status)), 
  288                                         (arch & 0xff));
  289                         my_err = -1;
  290                         goto done;
  291                 }
  292         }
  293 
  294 done:
  295         return my_err;
  296 }
  297 
  298 /*
  299  * Uses sysctlbyname to determine the cpu type. Currently, XNU classifies G5 as a 
  300  * 32-bit CPU, so this shouldn't be used to determine whether or not a CPU
  301  * is 64-bit.
  302  */
  303 int get_architecture()
  304 {
  305         int rval = -1;
  306         size_t length = 0;
  307         int my_err, buf;
  308         char *errmsg = NULL;
  309 
  310         errmsg = "sysctlbyname() failed when getting hw.cputype";
  311         if (my_err = sysctlbyname("hw.cputype", NULL, &length, NULL, 0)) goto finished; /* get length of data */
  312         if (length != sizeof(buf))                                       goto finished;
  313         if (my_err = sysctlbyname("hw.cputype", &buf, &length, NULL, 0)) goto finished; /* copy data */
  314         switch (buf) {
  315         case CPU_TYPE_X86:
  316         case CPU_TYPE_X86_64:
  317                 rval = INTEL;
  318                 break;
  319         case CPU_TYPE_POWERPC:
  320         case CPU_TYPE_POWERPC64:
  321                 rval = POWERPC;
  322                 break;
  323         }
  324 
  325 finished:
  326         if (rval == -1 && errmsg)
  327                 printf("%s", errmsg);
  328 
  329         return rval;
  330 }
  331 
  332 
  333 /*
  334  * Gets the bit'ed-ness of the current host. Returns either 32 or 64.
  335  * This get the hardware capability, but does not tell us whether this
  336  * binary is executing in 64 bit or 32 bit mode. Check sizeof long
  337  * or pointer to determine that.
  338  */
  339 int get_bits()
  340 {
  341         int  my_err, buf;
  342         size_t len = 0;
  343         int rval = 32;  /*
  344                          * On 32-bit systems the sysctls 64bitops and x86_64 don't 
  345                          * even exists, so if we don't find them then we assume 
  346                          * a 32-bit system.
  347                          */
  348 
  349         /* Check for PPC 64 */
  350         if ((my_err = sysctlbyname("hw.optional.64bitops", NULL, &len, NULL, 0)))       goto x86_64check; /* Request size */
  351         if (len > sizeof(buf))                                                          goto x86_64check;
  352         if ((my_err = sysctlbyname("hw.optional.64bitops", &buf, &len, NULL, 0)))       goto x86_64check; /* Copy value out from kernel */
  353         if (buf == 1) rval = 64;
  354         goto finished;
  355 
  356 x86_64check:
  357         /* Check for x86_64 */
  358         if ((my_err = sysctlbyname("hw.optional.x86_64", NULL, &len, NULL, 0))) goto finished; /* Request size */
  359         if (len > sizeof(buf))                                                  goto finished;
  360         if ((my_err = sysctlbyname("hw.optional.x86_64", &buf, &len, NULL, 0))) goto finished; /* Copy value out from kernel */
  361         if (buf == 1) rval = 64;
  362 
  363 finished:
  364         return rval;
  365 }
  366 

Cache object: 20a5428490ee747f23a1cdfd6fae6ab1


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.