aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-03-29 12:44:23 -0400
committerSteven Rostedt <rostedt@goodmis.org>2010-03-29 16:26:24 -0400
commitcf2892d3cfb5bc75cf376db81f6eb8d04af68401 (patch)
tree503d42decd87f666fc097126cdaf8bbc2e4db004
parentd6f2926f12dcfe5f880a490e368800cd5fcfa03e (diff)
trace-cmd: Make listen connection run as a separate process
Fork off children when a process is connected, and run continuously. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-listen.c89
1 files changed, 60 insertions, 29 deletions
diff --git a/trace-listen.c b/trace-listen.c
index 419cbd1..9d375af 100644
--- a/trace-listen.c
+++ b/trace-listen.c
@@ -27,6 +27,7 @@
27#include <getopt.h> 27#include <getopt.h>
28#include <sys/types.h> 28#include <sys/types.h>
29#include <sys/socket.h> 29#include <sys/socket.h>
30#include <sys/wait.h>
30#include <netdb.h> 31#include <netdb.h>
31#include <unistd.h> 32#include <unistd.h>
32#include <fcntl.h> 33#include <fcntl.h>
@@ -367,6 +368,63 @@ static void process_client(const char *node, const char *port, int fd)
367 } 368 }
368} 369}
369 370
371static void do_connection(int cfd, struct sockaddr_storage *peer_addr,
372 socklen_t peer_addr_len)
373{
374 char host[NI_MAXHOST], service[NI_MAXSERV];
375 char buf[BUFSIZ];
376 ssize_t nread;
377 pid_t pid;
378 int s;
379 int status;
380 int ret;
381
382 /* Clean up any children that has started before */
383 do {
384 ret = waitpid(0, &status, WNOHANG);
385 } while (ret > 0);
386
387 pid = fork();
388 if (pid < 0) {
389 warning("failed to create child");
390 return;
391 }
392
393 if (pid > 0) {
394 close(cfd);
395 return;
396 }
397
398 s = getnameinfo((struct sockaddr *)peer_addr, peer_addr_len,
399 host, NI_MAXHOST,
400 service, NI_MAXSERV, NI_NUMERICSERV);
401
402 if (s == 0)
403 printf("Connected with %s:%s\n",
404 host, service);
405 else {
406 printf("Error with getnameinfo: %s\n",
407 gai_strerror(s));
408 close(cfd);
409 return;
410 }
411
412 process_client(host, service, cfd);
413
414 do {
415 if (nread > 0)
416 nread = read(cfd, buf, BUFSIZ);
417 if (cfd < 0)
418 die("client");
419 if (nread > 0)
420 write(1, buf, nread);
421 } while (nread);
422
423 close(cfd);
424
425 exit(0);
426}
427
370static void do_listen(char *port) 428static void do_listen(char *port)
371{ 429{
372 struct addrinfo hints; 430 struct addrinfo hints;
@@ -374,9 +432,6 @@ static void do_listen(char *port)
374 int sfd, s, cfd; 432 int sfd, s, cfd;
375 struct sockaddr_storage peer_addr; 433 struct sockaddr_storage peer_addr;
376 socklen_t peer_addr_len; 434 socklen_t peer_addr_len;
377 ssize_t nread;
378 char buf[BUFSIZ];
379 char host[NI_MAXHOST], service[NI_MAXSERV];
380 435
381 memset(&hints, 0, sizeof(hints)); 436 memset(&hints, 0, sizeof(hints));
382 hints.ai_family = AF_UNSPEC; 437 hints.ai_family = AF_UNSPEC;
@@ -413,34 +468,10 @@ static void do_listen(char *port)
413 cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len); 468 cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len);
414 if (cfd < 0) 469 if (cfd < 0)
415 die("connecting"); 470 die("connecting");
416 s = getnameinfo((struct sockaddr *)&peer_addr, peer_addr_len,
417 host, NI_MAXHOST,
418 service, NI_MAXSERV, NI_NUMERICSERV);
419
420 if (s == 0)
421 printf("Connected with %s:%s\n",
422 host, service);
423 else {
424 printf("Error with getnameinfo: %s\n",
425 gai_strerror(s));
426 close(cfd);
427 close(sfd);
428 return;
429 }
430
431 process_client(host, service, cfd);
432 471
433 do { 472 do_connection(cfd, &peer_addr, peer_addr_len);
434 if (nread > 0)
435 nread = read(cfd, buf, BUFSIZ);
436 if (cfd < 0)
437 die("client");
438 if (nread > 0)
439 write(1, buf, nread);
440 } while (nread);
441 473
442 close(cfd); 474 } while (1);
443 } while (0);
444} 475}
445 476
446static void start_daemon(void) 477static void start_daemon(void)