#include <errno.h>
#include <dlfcn.h>
#include <fcntl.h>
+#include <signal.h>
+#include "breakpoint.h"
+#include "functions.h"
+#include "packet.h"
+
+static unsigned char breakpoints[N_FUNCS] = { };
+static char break_any = 0;
+static char hold = 0;
static const char *get_lib_names(void)
{
return fd;
}
+
+int get_in_fd(void)
+{
+ static int fd = -1;
+
+ if(fd<0)
+ {
+ const char *var = getenv("GLWRAP_CTRL_FD");
+ if(var)
+ fd = strtol(var, NULL, 0);
+ else
+ fd = 0;
+ }
+
+ return fd;
+}
+
+static void receive_gldBreak(GlPacket *pkt)
+{
+ unsigned short func;
+ unsigned char flags_set;
+ unsigned char flags_clr;
+
+ packet_read_short(pkt, (short *)&func);
+ packet_read_char(pkt, (char *)&flags_set);
+ packet_read_char(pkt, (char *)&flags_clr);
+
+ if(func)
+ {
+ breakpoints[func] &= ~flags_clr;
+ breakpoints[func] |= flags_set;
+ }
+ else
+ break_any = flags_set;
+}
+
+static void receive_gldHold(GlPacket *pkt __attribute__((unused)))
+{
+ hold = 1;
+}
+
+static void receive(void)
+{
+ GlPacket *pkt;
+
+ while((pkt = packet_receive(get_in_fd())))
+ {
+ unsigned short func;
+
+ packet_read_short(pkt, (short *)&func);
+ switch(func)
+ {
+ case FUNC_GLDBREAK: receive_gldBreak(pkt); break;
+ case FUNC_GLDHOLD: receive_gldHold(pkt); break;
+ default:;
+ }
+ }
+}
+
+void tracepoint(unsigned short func, int flag)
+{
+ receive();
+
+ if((breakpoints[func]|break_any)&flag)
+ {
+ GlPacket *pkt;
+
+ pkt = packet_begin(FUNC_GLDBREAK);
+ packet_write_short(pkt, func);
+ packet_send(pkt, get_out_fd());
+
+ break_any = 0;
+
+ while(1)
+ {
+ hold = 0;
+ raise(SIGTRAP);
+ receive();
+ if(!hold)
+ break;
+ }
+ }
+}