summaryrefslogtreecommitdiff
path: root/libpinniped/pinniped.c
blob: 348638feb884ec47242f9758ee8333ed2500ebca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * Copyright (c) 2014 Justus Winter <4winter@informatik.uni-hamburg.de>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#define _GNU_SOURCE
#include <dlfcn.h>
#include <errno.h>
#include <execinfo.h>
#include <mach.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

static void
print_backtrace (const char *f, ...)
{
  va_list args;

  va_start (args, f);
  vfprintf (stderr, f, args);
  va_end (args);

  void *array[20];
  size_t size;
  size = backtrace (array, 20);
  backtrace_symbols_fd (&array[2], size - 2, 2);
}

#define wrap(NAME)							\
  kern_return_t								\
  NAME (ipc_space_t task, mach_port_t name)				\
  {									\
    static kern_return_t (*f)(ipc_space_t, mach_port_t) = NULL;		\
    if (! f)								\
      f = dlsym (RTLD_NEXT, #NAME);					\
									\
    kern_return_t r = f (task, name);					\
    if (r != KERN_SUCCESS)						\
      {									\
	char buf[80];							\
	print_backtrace ("%s: " #NAME " (%d, %d): %s\n",                \
                         program_invocation_name,                       \
			 task, name,                                    \
                         strerror_r (r, buf, sizeof buf));              \
      }									\
    return r;								\
  }

wrap (mach_port_deallocate)
wrap (mach_port_destroy)

#undef wrap