1 #include <errno.h> 2 #include <mach/mach.h> 3 #include <signal.h> 4 #include <stdio.h> 5 #include <stdint.h> 6 #include <stdlib.h> 7 #include <spawn.h> 8 #include <unistd.h> 9 10 static void 11 exit_with_errno (int err, const char *prefix) 12 { 13 if (err) 14 { 15 fprintf (stderr, 16 "%s%s", 17 prefix ? prefix : "", 18 strerror(err)); 19 exit (err); 20 } 21 } 22 23 static pid_t 24 spawn_process (const char **argv, 25 const char **envp, 26 cpu_type_t cpu_type, 27 int &err) 28 { 29 pid_t pid = 0; 30 31 const posix_spawn_file_actions_t *file_actions = NULL; 32 posix_spawnattr_t attr; 33 err = posix_spawnattr_init (&attr); 34 if (err) 35 return pid; 36 37 short flags = POSIX_SPAWN_SETEXEC | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; 38 err = posix_spawnattr_setflags (&attr, flags); 39 if (err == 0) 40 { 41 // Use the default signal masks 42 sigset_t no_signals; 43 sigset_t all_signals; 44 sigemptyset (&no_signals); 45 sigfillset (&all_signals); 46 posix_spawnattr_setsigmask(&attr, &no_signals); 47 posix_spawnattr_setsigdefault(&attr, &all_signals); 48 49 if (cpu_type != 0) 50 { 51 size_t ocount = 0; 52 err = posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount); 53 } 54 55 if (err == 0) 56 { 57 err = posix_spawn (&pid, 58 argv[0], 59 file_actions, 60 &attr, 61 (char * const *)argv, 62 (char * const *)envp); 63 } 64 65 posix_spawnattr_destroy(&attr); 66 } 67 return pid; 68 } 69 70 int 71 main (int argc, char const **argv) 72 { 73 printf ("pid %i: Pointer size is %zu.\n", getpid(), sizeof(void *)); 74 int err = 0; // Set breakpoint 1 here 75 #if defined (__x86_64__) 76 if (sizeof(void *) == 8) 77 { 78 spawn_process (argv, NULL, CPU_TYPE_I386, err); 79 if (err) 80 exit_with_errno (err, "posix_spawn i386 error"); 81 } 82 else 83 { 84 spawn_process (argv, NULL, CPU_TYPE_X86_64, err); 85 if (err) 86 exit_with_errno (err, "posix_spawn x86_64 error"); 87 } 88 #else 89 spawn_process (argv, NULL, 0, err); 90 if (err) 91 exit_with_errno (err, "posix_spawn x86_64 error"); 92 #endif 93 return 0; 94 } 95