5 #include <sys/socket.h>
8 #define UNIX_PATH_MAX 108
10 //#define SOCKETDIR "/var/run/ust/socks"
11 #define SOCKETDIR "/tmp/socks"
12 #define SOCKETDIRLEN sizeof(SOCKETDIR)
13 #define USTSIGNAL SIGIO
15 #define DBG(fmt, args...) fprintf(stderr, fmt "\n", ## args)
16 #define WARN(fmt, args...) fprintf(stderr, "usertrace: WARNING: " fmt "\n", ## args)
17 #define ERR(fmt, args...) fprintf(stderr, "usertrace: ERROR: " fmt "\n", ## args)
18 #define PERROR(call) perror("usertrace: ERROR: " call)
20 #define MAX_MSG_SIZE (100)
22 #define MSG_REGISTER_NOTIF 2
24 struct tracecmd
{ /* no padding */
29 //struct listener_arg {
34 /* size: the size of all the fields except size itself */
37 /* Only the necessary part of the payload is transferred. It
38 * may even be none of it.
44 char mysocketfile
[UNIX_PATH_MAX
] = "";
47 void do_command(struct tracecmd
*cmd
)
51 void receive_commands()
61 /* FIXME: fd_notif should probably be protected by a spinlock */
67 msg
.size
= sizeof(msg
.type
);
69 /* FIXME: don't block here */
70 result
= write(fd_notif
, &msg
, msg
.size
+sizeof(msg
.size
));
77 int listener_main(void *p
)
81 /* Allowing only 1 connection for now. */
82 result
= listen(pfd
, 1);
92 struct sockaddr_un addr
;
93 socklen_t addrlen
= sizeof(addr
);
95 result
= fd
= accept(pfd
, (struct sockaddr
*)&addr
, &addrlen
);
102 struct trctl_msg msg
;
103 unsigned char dontclose
=0;
105 result
= read(fd
, &msg
.size
, sizeof(msg
.size
));
111 if(size
> MAX_MSG_SIZE
) {
112 ERR("trctl message too big");
116 result
= read(fd
, &msg
.type
, sizeof(msg
.type
));
123 case MSG_REGISTER_NOTIF
:
124 /* TODO: put it in notif mode */
132 void create_listener(void)
135 static char listener_stack
[16384];
137 result
= clone(listener_main
, listener_stack
+sizeof(listener_stack
)-1, CLONE_FS
| CLONE_FILES
| CLONE_VM
, NULL
);
143 /* The signal handler itself. */
145 void sighandler(int sig
)
151 /* Called by the app signal handler to chain it to us. */
153 void chain_signal(void)
155 sighandler(USTSIGNAL
);
158 static int init_socket(void)
165 struct sockaddr_un addr
;
167 result
= fd
= socket(PF_UNIX
, SOCK_SEQPACKET
, 0);
173 addr
.sun_family
= AF_UNIX
;
175 result
= snprintf(addr
.sun_path
, UNIX_PATH_MAX
, "%s/%d", SOCKETDIR
, mypid
);
176 if(result
>= UNIX_PATH_MAX
) {
177 ERR("string overflow allocating socket name");
180 //DBG("opening socket at %s", addr.sun_path);
182 result
= bind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
188 strcpy(mysocketfile
, addr
.sun_path
);
199 static void destroy_socket(void)
203 if(mysocketfile
[0] == '\0')
206 result
= unlink(mysocketfile
);
212 static int init_signal_handler(void)
214 /* Attempt to handler SIGIO. If the main program wants to
215 * handle it, fine, it'll override us. They it'll have to
216 * use the chaining function.
220 struct sigaction act
;
222 result
= sigemptyset(&act
.sa_mask
);
224 PERROR("sigemptyset");
228 act
.sa_handler
= sighandler
;
229 act
.sa_flags
= SA_RESTART
;
231 /* Only defer ourselves. Also, try to restart interrupted
232 * syscalls to disturb the traced program as little as possible.
234 result
= sigaction(SIGIO
, &act
, NULL
);
243 static void __attribute__((constructor
)) init()
249 /* Must create socket before signal handler to prevent races
252 result
= init_socket();
254 ERR("init_socket error");
257 result
= init_signal_handler();
259 ERR("init_signal_handler error");
265 /* should decrementally destroy stuff if error */
269 /* This is only called if we terminate normally, not with an unhandled signal,
270 * so we cannot rely on it. */
272 static void __attribute__((destructor
)) fini()
This page took 0.058821 seconds and 4 git commands to generate.