| | 447 | {{{ |
| | 448 | #!C |
| | 449 | #include <unistd.h> |
| | 450 | #include <stdio.h> |
| | 451 | #include <fcntl.h> |
| | 452 | #include <linux/fb.h> // include frame buffer header files |
| | 453 | #include <sys/ioctl.h> |
| | 454 | |
| | 455 | int main(void) |
| | 456 | { |
| | 457 | int fbfd = 0 ; // frame buffer file description |
| | 458 | |
| | 459 | /* Get device independent unchangeable information about a frame buffer |
| | 460 | * device and a specific video mode by FBIOGET_FSCREENINFO ioctl. */ |
| | 461 | struct fb_fix_screeninfo finfo; |
| | 462 | |
| | 463 | fbfd = open( "/dev/fb0" , O_RDWR ); |
| | 464 | if ( !fbfd ) |
| | 465 | { |
| | 466 | printf( "Error: cannot open framebuffer device.\n" ); |
| | 467 | exit(1); |
| | 468 | } |
| | 469 | printf("The framebuffer device was opened successfully.\n"); |
| | 470 | |
| | 471 | /* Get fixed screen information */ |
| | 472 | if ( ioctl ( fbfd , FBIOGET_FSCREENINFO , &finfo ) ) |
| | 473 | { |
| | 474 | printf("Error reading fixed screen information.\n"); |
| | 475 | exit(2); |
| | 476 | } else { |
| | 477 | printf("Succesfully Read the Fixed Screen Information\n"); |
| | 478 | } |
| | 479 | |
| | 480 | printf("fb_fix_screeninfo.smem_len = %d\n", finfo.smem_len); |
| | 481 | printf("fb_fix_screeninfo.mmio_len = %d\n", finfo.mmio_len); |
| | 482 | } |
| | 483 | }}} |
| | 484 | |
| | 485 | * 在 Ubuntu Intrepid 上執行結果 |
| | 486 | {{{ |
| | 487 | root@intrepid:~# uname -a |
| | 488 | Linux intrepid 2.6.27-7-server #1 SMP Tue Nov 4 20:16:57 UTC 2008 x86_64 GNU/Linux |
| | 489 | root@intrepid:~# ./fbinfo |
| | 490 | The framebuffer device was opened successfully. |
| | 491 | Succesfully Read the Fixed Screen Information |
| | 492 | fb_fix_screeninfo.smem_len = 16777216 |
| | 493 | fb_fix_screeninfo.mmio_len = 0 |
| | 494 | }}} |
| | 495 | * 以下是在 Debian Sarge 上執行結果,值得一提的是 jfbterm 在 2.6.8 核心上可以正常執行。(不過還有字型問題需要調整) |
| | 496 | {{{ |
| | 497 | root@wsu-admin:~# uname -a |
| | 498 | Linux wsu-admin 2.6.8-2-386 #1 Tue Aug 16 12:46:35 UTC 2005 i686 GNU/Linux |
| | 499 | root@wsu-admin:~# ./fbinfo |
| | 500 | The framebuffer device was opened successfully. |
| | 501 | Succesfully Read the Fixed Screen Information |
| | 502 | fb_fix_screeninfo.smem_len = 65536 |
| | 503 | fb_fix_screeninfo.mmio_len = 0 |
| | 504 | }}} |
| | 505 | {{{ |
| | 506 | root@wsu-admin:~# jfbterm |
| | 507 | jfbterm - Kanji on framebuffer console Version 0.4.7 |
| | 508 | Copyright (C) 2003 Fumitoshi UKAI |
| | 509 | Copyright (C) 1999-2000 Noritoshi Masuichi |
| | 510 | This program is based on KON2 |
| | 511 | Copyright (C) 1992-1996 Takashi MANABE |
| | 512 | |
| | 513 | (**) : Configuration file `/etc/jfbterm.conf' |
| | 514 | .... 略 .... |
| | 515 | exec : /bin/bash ioctl FBIOGET_CON2FBMAP: Invalid argument |
| | 516 | color 0 : 0, 0 |
| | 517 | color 1 : 2a, 2a |
| | 518 | color 2 : 2a, 2a |
| | 519 | color 3 : 2a, 2a |
| | 520 | color 4 : 2a, 2a |
| | 521 | color 5 : 2a, 2a |
| | 522 | color 6 : 2a, 2a |
| | 523 | color 7 : 2a, 2a |
| | 524 | color 8 : 15, 15 |
| | 525 | color 9 : 3f, 3f |
| | 526 | color 10 : 3f, 3f |
| | 527 | color 11 : 3f, 3f |
| | 528 | color 12 : 3f, 3f |
| | 529 | color 13 : 3f, 3f |
| | 530 | color 14 : 3f, 3f |
| | 531 | color 15 : 3f, 3f |
| | 532 | }}} |
| | 533 | * 以下是在 Debian Etch 上執行結果,有趣的是 jfbterm 0.4.7-7 在 2.6.18-4 上執行,縱使有 cannot mmap(mmio) : Invalid argument 的錯誤訊息,但仍舊可以正常進入 jfbterm 的環境。 |
| | 534 | {{{ |
| | 535 | root@etch:~# uname -a |
| | 536 | Linux etch 2.6.18-4-686 #1 SMP Wed May 9 23:03:12 UTC 2007 i686 GNU/Linux |
| | 537 | root@etch:~# ./fbinfo |
| | 538 | The framebuffer device was opened successfully. |
| | 539 | Succesfully Read the Fixed Screen Information |
| | 540 | fb_fix_screeninfo.smem_len = 1920000 |
| | 541 | fb_fix_screeninfo.mmio_len = 0 |
| | 542 | }}} |
| | 543 | {{{ |
| | 544 | root@etch:~# jfbterm |
| | 545 | jfbterm - Kanji on framebuffer console Version 0.4.7 |
| | 546 | Copyright (C) 2003 Fumitoshi UKAI |
| | 547 | Copyright (C) 1999-2000 Noritoshi Masuichi |
| | 548 | This program is based on KON2 |
| | 549 | Copyright (C) 1992-1996 Takashi MANABE |
| | 550 | |
| | 551 | (**) : Configuration file `/etc/jfbterm.conf' |
| | 552 | ... 略 ... |
| | 553 | exec : /bin/bash color 0 : 0, 0 |
| | 554 | color 1 : 15, 15 |
| | 555 | color 2 : 540, 540 |
| | 556 | color 3 : 555, 555 |
| | 557 | color 4 : a800, a800 |
| | 558 | color 5 : a815, a815 |
| | 559 | color 6 : ad40, ad40 |
| | 560 | color 7 : ad55, ad55 |
| | 561 | color 8 : 52aa, 52aa |
| | 562 | color 9 : 52bf, 52bf |
| | 563 | color 10 : 57ea, 57ea |
| | 564 | color 11 : 57ff, 57ff |
| | 565 | color 12 : faaa, faaa |
| | 566 | color 13 : fabf, fabf |
| | 567 | color 14 : ffea, ffea |
| | 568 | color 15 : ffff, ffff |
| | 569 | cannot mmap(mmio) : Invalid argument |
| | 570 | }}} |
| | 571 | * 為了測試 jfbterm 的中文相容性,我們寫了一隻簡單的 script |
| | 572 | {{{ |
| | 573 | #!sh |
| | 574 | #!/bin/bash |
| | 575 | echo " TEST 中文測試 " |
| | 576 | echo "Press Any Key to continue!" |
| | 577 | read |
| | 578 | }}} |
| | 579 | * 在 Ubutnu intriped 的 tty1 上執行 jfbterm -f /etc/jfbterm.conf -e /root/test.sh 可以正常看到" TEST 中文測試 "字樣,但卻無法正常跳出,因此我們再來 DEBUG 一下。 |
| | 580 | {{{ |
| | 581 | file jfbterm |
| | 582 | set args -f /etc/jfbterm.conf -e /root/test.sh |
| | 583 | show args |
| | 584 | break fbcommon.c:500 |
| | 585 | break fbcommon.c:557 |
| | 586 | break fbcommon.c:566 |
| | 587 | break term.c:103 |
| | 588 | break term.c:284 |
| | 589 | r |
| | 590 | c |
| | 591 | c |
| | 592 | c |
| | 593 | bt |
| | 594 | c |
| | 595 | bt |
| | 596 | p utp->ut_time |
| | 597 | p utp->ut_tv |
| | 598 | }}} |
| | 599 | {{{ |
| | 600 | Breakpoint 4, tterm_final (p=0x6147c0) at term.c:103 |
| | 601 | (gdb) bt |
| | 602 | #0 tterm_final (p=0x6147c0) at term.c:103 |
| | 603 | #1 0x0000000000408adf in sigchld (sig=<value optimized out>) at term.c:82 |
| | 604 | #2 <signal handler called> |
| | 605 | #3 0x00007f5dfc00f433 in select () from /lib/libc.so.6 |
| | 606 | #4 0x0000000000408873 in tterm_start (p=0x6147c0, tn=<value optimized out>, en=<value optimized out>) at term.c:192 |
| | 607 | #5 0x0000000000402cf2 in main (argc=<value optimized out>, argv=0x7fff049477f8) at main.c:438 |
| | 608 | (gdb) c |
| | 609 | Continuing. |
| | 610 | |
| | 611 | Breakpoint 5, tterm_reset_utmp (p=<value optimized out>) at term.c:284 |
| | 612 | (gdb) bt |
| | 613 | #0 tterm_reset_utmp (p=<value optimized out>) at term.c:284 |
| | 614 | #1 0x0000000000408a50 in tterm_final (p=0xe) at term.c:103 |
| | 615 | #2 0x0000000000408adf in sigchld (sig=<value optimized out>) at term.c:82 |
| | 616 | #3 <signal handler called> |
| | 617 | #4 0x00007fa268131433 in select () from /lib/libc.so.6 |
| | 618 | #5 0x0000000000408873 in tterm_start (p=0x6147c0, tn=<value optimized out>, en=<value optimized out>) at term.c:192 |
| | 619 | #6 0x0000000000402cf2 in main (argc=<value optimized out>, argv=0x7fff70a69328) at main.c:438 |
| | 620 | (gdb) p utp->ut_time |
| | 621 | There is no member named ut_time. |
| | 622 | }}} |
| | 623 | * [註] utp->ut_time = utp->ut_tv.tv_sec |
| | 624 | {{{ |
| | 625 | #!C |
| | 626 | |
| | 627 | < /usr/include/bits/utmp.h > |
| | 628 | |
| | 629 | 59 /* The structure describing an entry in the user accounting database. */ |
| | 630 | 60 struct utmp |
| | 631 | 61 { |
| | 632 | 62 short int ut_type; /* Type of login. */ |
| | 633 | 63 pid_t ut_pid; /* Process ID of login process. */ |
| | 634 | 64 char ut_line[UT_LINESIZE]; /* Devicename. */ |
| | 635 | 65 char ut_id[4]; /* Inittab ID. */ |
| | 636 | 66 char ut_user[UT_NAMESIZE]; /* Username. */ |
| | 637 | 67 char ut_host[UT_HOSTSIZE]; /* Hostname for remote login. */ |
| | 638 | 68 struct exit_status ut_exit; /* Exit status of a process marked |
| | 639 | 69 as DEAD_PROCESS. */ |
| | 640 | 70 /* The ut_session and ut_tv fields must be the same size when compiled |
| | 641 | 71 32- and 64-bit. This allows data files and shared memory to be |
| | 642 | 72 shared between 32- and 64-bit applications. */ |
| | 643 | 73 #if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32 |
| | 644 | 74 int32_t ut_session; /* Session ID, used for windowing. */ |
| | 645 | 75 struct |
| | 646 | 76 { |
| | 647 | 77 int32_t tv_sec; /* Seconds. */ |
| | 648 | 78 int32_t tv_usec; /* Microseconds. */ |
| | 649 | 79 } ut_tv; /* Time entry was made. */ |
| | 650 | 80 #else |
| | 651 | 81 long int ut_session; /* Session ID, used for windowing. */ |
| | 652 | 82 struct timeval ut_tv; /* Time entry was made. */ |
| | 653 | 83 #endif |
| | 654 | 84 |
| | 655 | 85 int32_t ut_addr_v6[4]; /* Internet address of remote host. */ |
| | 656 | 86 char __unused[20]; /* Reserved for future use. */ |
| | 657 | 87 }; |
| | 658 | |
| | 659 | 94 # define ut_time ut_tv.tv_sec |
| | 660 | }}} |
| | 661 | * GDB 線上除錯練習 |
| | 662 | {{{ |
| | 663 | [tty1] |
| | 664 | |
| | 665 | root@etch:~# apt-get build-dep jfbterm |
| | 666 | root@etch:~# apt-get source jfbterm |
| | 667 | root@etch:~# apt-get install jfbterm |
| | 668 | root@etch:~# cd jfbterm-0.4.7 |
| | 669 | root@etch:~/jfbterm-0.4.7# ./configure --enable-debug |
| | 670 | root@etch:~/jfbterm-0.4.7# make |
| | 671 | root@etch:~/jfbterm-0.4.7# ./jfbterm -f /etc/jfbterm.conf -e /root/test.sh |
| | 672 | |
| | 673 | [tty2] |
| | 674 | |
| | 675 | root@etch:~# gdb /root/jfbterm-0.4.7/jfbterm `pidof jfbterm` |
| | 676 | GNU gdb 6.4.90-debian |
| | 677 | Copyright (C) 2006 Free Software Foundation, Inc. |
| | 678 | GDB is free software, covered by the GNU General Public License, and you are |
| | 679 | welcome to change it and/or distribute copies of it under certain conditions. |
| | 680 | Type "show copying" to see the conditions. |
| | 681 | There is absolutely no warranty for GDB. Type "show warranty" for details. |
| | 682 | This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". |
| | 683 | |
| | 684 | Attaching to program: /root/jfbterm-0.4.7/jfbterm, process 7480 |
| | 685 | Reading symbols from /lib/tls/i686/cmov/libutil.so.1...done. |
| | 686 | Loaded symbols for /lib/tls/i686/cmov/libutil.so.1 |
| | 687 | Reading symbols from /lib/tls/i686/cmov/libm.so.6...done. |
| | 688 | Loaded symbols for /lib/tls/i686/cmov/libm.so.6 |
| | 689 | Reading symbols from /lib/tls/i686/cmov/libc.so.6...done. |
| | 690 | Loaded symbols for /lib/tls/i686/cmov/libc.so.6 |
| | 691 | Reading symbols from /lib/ld-linux.so.2...done. |
| | 692 | Loaded symbols for /lib/ld-linux.so.2 |
| | 693 | Reading symbols from /lib/tls/i686/cmov/libnss_compat.so.2...done. |
| | 694 | Loaded symbols for /lib/tls/i686/cmov/libnss_compat.so.2 |
| | 695 | Reading symbols from /lib/tls/i686/cmov/libnsl.so.1...done. |
| | 696 | Loaded symbols for /lib/tls/i686/cmov/libnsl.so.1 |
| | 697 | Reading symbols from /lib/tls/i686/cmov/libnss_nis.so.2...done. |
| | 698 | Loaded symbols for /lib/tls/i686/cmov/libnss_nis.so.2 |
| | 699 | Reading symbols from /lib/tls/i686/cmov/libnss_files.so.2...done. |
| | 700 | Loaded symbols for /lib/tls/i686/cmov/libnss_files.so.2 |
| | 701 | Failed to read a valid object file image from memory. |
| | 702 | 0xb7fea410 in ?? () |
| | 703 | (gdb) break term.c:284 |
| | 704 | Breakpoint 1 at 0x804f552: file term.c, line 284. |
| | 705 | (gdb) c |
| | 706 | Continuing. |
| | 707 | |
| | 708 | Breakpoint 1, tterm_final (p=0x8058be0) at term.c:284 |
| | 709 | 284 time(&(utp->ut_time)); |
| | 710 | (gdb) c |
| | 711 | Continuing. |
| | 712 | |
| | 713 | Breakpoint 1, tterm_final (p=0x8058be0) at term.c:284 |
| | 714 | 284 time(&(utp->ut_time)); |
| | 715 | (gdb) c |
| | 716 | Continuing. |
| | 717 | |
| | 718 | Program exited normally. |
| | 719 | }}} |
| | 720 | * GDB 遠端除錯練習 |
| | 721 | {{{ |
| | 722 | [tty1] |
| | 723 | gdbserver 127.0.0.1:1234 /root/jfbterm-0.4.7/jfbterm |
| | 724 | [pts1] |
| | 725 | (gdb) target remote 127.0.0.1:1234 |
| | 726 | }}} |
| | 727 | * 在 DEBUG 的時候偶爾會看到 <value optimized out>,但是該怎麼去掉呢?? |
| | 728 | * [參考] http://www.cs.utk.edu/~vose/c-stuff/onlinedocs/gdb_7.html |
| | 729 | {{{ |
| | 730 | The values of arguments that were not saved in their stack frames are shown as `<value optimized out>'. |
| | 731 | |
| | 732 | If you need to display the values of such optimized-out arguments, either deduce that from other variables whose values depend on the one you are interested in, or recompile without optimizations. |
| | 733 | }}} |
| | 734 | * [作法] 在 configure 的時候加上 CFLAGS |
| | 735 | * 註: 因為如果有設定 CFLAGS 的話,在 configure 裡是會直接採用我們提供的 CFLAGS。因此縱使加上 --enable-debug 也沒有用,configure 不會幫你加 -g 進去。 |
| | 736 | {{{ |
| | 737 | root@intrepid:~/jfbterm-0.4.7-dev# CFLAGS="-g -O0" ./configure |
| | 738 | }}} |
| | 739 | * 繼續追為何結束時會收到 SIGSEGV 的主因 |
| | 740 | {{{ |
| | 741 | < 直接在 tty1 或在 screen 中執行 > |
| | 742 | root@intrepid:~/jfbterm-0.4.7-dev# ./jfbterm -f /etc/jfbterm.conf -e /root/test.sh |
| | 743 | }}} |
| | 744 | {{{ |
| | 745 | root@intrepid:~/jfbterm-0.4.7-dev# gdb ./jfbterm `pidof jfbterm` |
| | 746 | break term.c:103 |
| | 747 | break term.c:284 |
| | 748 | c |
| | 749 | #### 直接在 tty1 不透過 screen 執行 的結果 ##### |
| | 750 | Breakpoint 1, tterm_final (p=0x617a00) at term.c:103 |
| | 751 | 103 tterm_reset_utmp(p); |
| | 752 | (gdb) s |
| | 753 | tterm_reset_utmp (p=0x617a00) at term.c:271 |
| | 754 | 271 { |
| | 755 | (gdb) s |
| | 756 | 275 tn = rindex(p->name, '/') + 4; |
| | 757 | (gdb) p p->name |
| | 758 | $1 = "/dev/pts/0", '\0' <repeats 53 times> |
| | 759 | #### 直接在 tty1 有透過 screen 執行 的結果 ##### |
| | 760 | |
| | 761 | Breakpoint 1, tterm_final (p=0x617a00) at term.c:103 |
| | 762 | 103 tterm_reset_utmp(p); |
| | 763 | (gdb) s |
| | 764 | tterm_reset_utmp (p=0x617a00) at term.c:271 |
| | 765 | 271 { |
| | 766 | (gdb) s |
| | 767 | 275 tn = rindex(p->name, '/') + 4; |
| | 768 | (gdb) p p->name |
| | 769 | $1 = "/dev/pts/1", '\0' <repeats 53 times> |
| | 770 | }}} |
| | 771 | * manpage of getutid(3) |
| | 772 | {{{ |
| | 773 | SYNOPSIS |
| | 774 | |
| | 775 | struct utmp *getutid(struct utmp *ut); |
| | 776 | |
| | 777 | DESCRIPTION |
| | 778 | |
| | 779 | getutid() searches forward from the current file position in the utmp |
| | 780 | file based upon ut. If ut->ut_type is one of RUN_LVL, BOOT_TIME, |
| | 781 | NEW_TIME, or OLD_TIME, getutid() will find the first entry whose |
| | 782 | ut_type field matches ut->ut_type. If ut->ut_type is one of INIT_PRO- |
| | 783 | CESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS, getutid() will find |
| | 784 | the first entry whose ut_id field matches ut->ut_id. |
| | 785 | |
| | 786 | RETURN VALUE |
| | 787 | getutent(), getutid(), getutline() and pututline() return a pointer to |
| | 788 | a struct utmp on success, and NULL on failure. This struct utmp is |
| | 789 | allocated in static storage, and may be overwritten by subsequent |
| | 790 | calls. |
| | 791 | |
| | 792 | FILES |
| | 793 | /var/run/utmp database of currently logged-in users |
| | 794 | /var/log/wtmp database of past user logins |
| | 795 | |
| | 796 | NOTES |
| | 797 | Glibc Notes |
| | 798 | The above functions are not thread-safe. Glibc adds reentrant versions |
| | 799 | |
| | 800 | #define _GNU_SOURCE /* or _SVID_SOURCE or _BSD_SOURCE */ |
| | 801 | #include <utmp.h> |
| | 802 | |
| | 803 | int getutent_r(struct utmp *ubuf, struct utmp **ubufp); |
| | 804 | |
| | 805 | int getutid_r(struct utmp *ut, |
| | 806 | struct utmp *ubuf, struct utmp **ubufp); |
| | 807 | |
| | 808 | int getutline_r(struct utmp *ut, |
| | 809 | struct utmp *ubuf, struct utmp **ubufp); |
| | 810 | |
| | 811 | These functions are GNU extensions, analogs of the functions of the |
| | 812 | same name without the _r suffix. The ubuf parameter gives these func- |
| | 813 | tions a place to store their result. On success they return 0, and a |
| | 814 | pointer to the result is written in *ubufp. On error these functions |
| | 815 | return -1. |
| | 816 | |
| | 817 | }}} |
| | 818 | {{{ |
| | 819 | root@intrepid:~# w |
| | 820 | 02:01:29 up 5 min, 5 users, load average: 0.75, 0.91, 0.41 |
| | 821 | USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT |
| | 822 | root@intrepid:~# w |
| | 823 | 02:02:14 up 6 min, 5 users, load average: 0.35, 0.78, 0.39 |
| | 824 | USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT |
| | 825 | root pts/0 :tty1:S.0 01:58 1:46m 0.24s 0.21s ./jfbterm -f /etc/jfbterm.conf -e /root/test.sh ### screen 0 |
| | 826 | root pts/1 :tty1:S.1 01:58 3:55m 0.01s 0.01s /bin/bash ### screen 1 |
| | 827 | root pts/3 172.21.253.1 01:59 1:19m 0.12s 0.10s gdb ./jfbterm 3833 ### from ssh for gdb |
| | 828 | root pts/2 - 01:59 1:46m 0.00s 0.21s ./jfbterm -f /etc/jfbterm.conf -e /root/test.sh ### fb created by jfbterm |
| | 829 | root pts/4 172.21.253.1 02:01 0.00s 0.02s 0.00s w ### from ssh for this command `w' |
| | 830 | }}} |