| 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側で結果が出力されないので、断念 |