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