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
10static void
11exit_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
23static pid_t
24spawn_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
70int
71main (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