| | 428 | |
| | 429 | = 10/12 = |
| | 430 | == tee system call == |
| | 431 | * http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/tee.2.html |
| | 432 | > {{{#!cc |
| | 433 | > #define _GNU_SOURCE |
| | 434 | > #include <fcntl.h> |
| | 435 | > #include <stdio.h> |
| | 436 | > #include <stdlib.h> |
| | 437 | > #include <unistd.h> |
| | 438 | > #include <errno.h> |
| | 439 | > #include <limits.h> |
| | 440 | > |
| | 441 | > int |
| | 442 | > main(int argc, char *argv[]) |
| | 443 | > { |
| | 444 | > int fd; |
| | 445 | > int len, slen; |
| | 446 | > |
| | 447 | > if (argc != 2) { |
| | 448 | > fprintf(stderr, "Usage: %s <file>\n", argv[0]); |
| | 449 | > exit(EXIT_FAILURE); |
| | 450 | > } |
| | 451 | > |
| | 452 | > fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644); |
| | 453 | > if (fd == -1) { |
| | 454 | > perror("open"); |
| | 455 | > exit(EXIT_FAILURE); |
| | 456 | > } |
| | 457 | > |
| | 458 | > do { |
| | 459 | > /* |
| | 460 | > * tee stdin to stdout. |
| | 461 | > */ |
| | 462 | > len = tee(STDIN_FILENO, STDOUT_FILENO, |
| | 463 | > INT_MAX, SPLICE_F_NONBLOCK); |
| | 464 | > |
| | 465 | > if (len < 0) { |
| | 466 | > if (errno == EAGAIN) |
| | 467 | > continue; |
| | 468 | > perror("tee"); |
| | 469 | > exit(EXIT_FAILURE); |
| | 470 | > } else |
| | 471 | > if (len == 0) |
| | 472 | > break; |
| | 473 | > |
| | 474 | > /* |
| | 475 | > * Consume stdin by splicing it to a file. |
| | 476 | > */ |
| | 477 | > while (len > 0) { |
| | 478 | > slen = splice(STDIN_FILENO, NULL, fd, NULL, |
| | 479 | > len, SPLICE_F_MOVE); |
| | 480 | > if (slen < 0) { |
| | 481 | > perror("splice"); |
| | 482 | > break; |
| | 483 | > } |
| | 484 | > len -= slen; |
| | 485 | > } |
| | 486 | > } while (1); |
| | 487 | > |
| | 488 | > close(fd); |
| | 489 | > exit(EXIT_SUCCESS); |
| | 490 | > } |
| | 491 | > }}} |
| | 492 | * Ubuntu lucid(2.6.32-33-generic)やvanilla 2.6.35.14ではサンプルコードのまま正常に使える |
| | 493 | * mitty@ubuntu64:~/coursework/KernelHack/02$ cat tee.c | ./tee hoge | wc |
| | 494 | {{{ |
| | 495 | 58 130 1217 |
| | 496 | }}} |
| | 497 | * CentOS 5.7(2.6.18-238.19.1.el5.centos.plusPAE or 2.6.18-274.3.1.el5)ではspliceがエラーになる |
| | 498 | * viola01:02 s0711489$ cat tee.c | ./tee hoge | wc |
| | 499 | {{{ |
| | 500 | viola01:02 s0711489$ cat tee.c | ./tee hoge | wc |
| | 501 | splice: Invalid argument |
| | 502 | splice: Invalid argument |
| | 503 | splice: Invalid argument |
| | 504 | splice: Invalid argument |
| | 505 | splice: Invalid argument |
| | 506 | splice: Invalid argument |
| | 507 | splice: Invalid argument |
| | 508 | splice: Invalid argument |
| | 509 | splice: Invalid argument |
| | 510 | |
| | 511 | .... |
| | 512 | }}} |
| | 513 | * Ubuntu上でも、strace出来ない |
| | 514 | * mitty@ubuntu64:~/coursework/KernelHack/02$ strace -f -o sh.log sh -c 'cat tee.c | ./tee hoge | wc' |
| | 515 | * mitty@ubuntu64:~/coursework/KernelHack/02$ less sh.log |
| | 516 | {{{ |
| | 517 | (snip) |
| | 518 | |
| | 519 | 1611 <... tee resumed> ) = -1 EAGAIN (Resource temporarily unavailable) |
| | 520 | 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) |
| | 521 | 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) |
| | 522 | 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) |
| | 523 | 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) |
| | 524 | 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) |
| | 525 | 1611 tee(0, 0x1, 0x7fffffff, 0x2) = -1 EAGAIN (Resource temporarily unavailable) |
| | 526 | |
| | 527 | (snip) |
| | 528 | }}} |
| | 529 | |
| | 530 | * GDBによるステップ実行は、3000行ほど実行してみたがguest側で結果が出力されないので、断念 |