+
+ return 0;
+}
+
+void GlDbg::launch()
+{
+ if(process.get_state()!=Process::INACTIVE)
+ throw InvalidState("Program is already running");
+
+ int fds[2];
+ socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
+ sock_fd = fds[0];
+
+ int flags = fcntl(sock_fd, F_GETFD);
+ fcntl(sock_fd, F_SETFD, flags|FD_CLOEXEC);
+
+ process.setenv("GLWRAP_FD", lexical_cast(fds[1]));
+ process.setenv("GLWRAP_CTRL_FD", lexical_cast(fds[1]));
+ process.launch();
+ close(fds[1]);
+}
+
+void GlDbg::set_breakpoint(unsigned short func, char flag)
+{
+ GlPacket *pkt = packet_begin(FUNC_GLDBREAK);
+ packet_write_short(pkt, func);
+ packet_write_char(pkt, flag);
+ packet_write_char(pkt, 0);
+ packet_send(pkt, sock_fd);
+}
+
+void GlDbg::clear_breakpoint(unsigned short func, char flag)
+{
+ GlPacket *pkt = packet_begin(FUNC_GLDBREAK);
+ packet_write_short(pkt, func);
+ packet_write_char(pkt, 0);
+ packet_write_char(pkt, flag);
+ packet_send(pkt, sock_fd);
+}
+
+void GlDbg::quit(bool force)
+{
+ if(!force && process.get_state()!=Process::INACTIVE)
+ throw InvalidState("Program is still running");
+ exit(0);