| #include <errno.h> |
| #include <mach/mach.h> |
| #include <signal.h> |
| #include <stdio.h> |
| #include <stdint.h> |
| #include <stdlib.h> |
| #include <spawn.h> |
| #include <unistd.h> |
| |
| static void |
| exit_with_errno (int err, const char *prefix) |
| { |
| if (err) |
| { |
| fprintf (stderr, |
| "%s%s", |
| prefix ? prefix : "", |
| strerror(err)); |
| exit (err); |
| } |
| } |
| |
| static pid_t |
| spawn_process (const char **argv, |
| const char **envp, |
| cpu_type_t cpu_type, |
| int &err) |
| { |
| pid_t pid = 0; |
| |
| const posix_spawn_file_actions_t *file_actions = NULL; |
| posix_spawnattr_t attr; |
| err = posix_spawnattr_init (&attr); |
| if (err) |
| return pid; |
| |
| short flags = POSIX_SPAWN_SETEXEC | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; |
| err = posix_spawnattr_setflags (&attr, flags); |
| if (err == 0) |
| { |
| // Use the default signal masks |
| sigset_t no_signals; |
| sigset_t all_signals; |
| sigemptyset (&no_signals); |
| sigfillset (&all_signals); |
| posix_spawnattr_setsigmask(&attr, &no_signals); |
| posix_spawnattr_setsigdefault(&attr, &all_signals); |
| |
| if (cpu_type != 0) |
| { |
| size_t ocount = 0; |
| err = posix_spawnattr_setbinpref_np (&attr, 1, &cpu_type, &ocount); |
| } |
| |
| if (err == 0) |
| { |
| err = posix_spawn (&pid, |
| argv[0], |
| file_actions, |
| &attr, |
| (char * const *)argv, |
| (char * const *)envp); |
| } |
| |
| posix_spawnattr_destroy(&attr); |
| } |
| return pid; |
| } |
| |
| int |
| main (int argc, char const **argv) |
| { |
| printf ("pid %i: Pointer size is %zu.\n", getpid(), sizeof(void *)); |
| int err = 0; // Set breakpoint 1 here |
| #if defined (__x86_64__) |
| if (sizeof(void *) == 8) |
| { |
| spawn_process (argv, NULL, CPU_TYPE_I386, err); |
| if (err) |
| exit_with_errno (err, "posix_spawn i386 error"); |
| } |
| else |
| { |
| spawn_process (argv, NULL, CPU_TYPE_X86_64, err); |
| if (err) |
| exit_with_errno (err, "posix_spawn x86_64 error"); |
| } |
| #else |
| spawn_process (argv, NULL, 0, err); |
| if (err) |
| exit_with_errno (err, "posix_spawn x86_64 error"); |
| #endif |
| return 0; |
| } |