2011年11月27日 星期日

Allow Unix sockets to be treated like normal files.


某天忽然想要用echo/cat的方式直接對unix socket做存取,結果得到error,只好有請google大神,覓得此良方Allow Unix sockets to be treated like normal files,try了一下沒問題。



#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>

#define handle_error(msg) \
        do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
    int srv_fd, cli_fd;
    socklen_t cli_len;
    struct sockaddr_un srv_addr, cli_addr;
    char buf[128] = "Brook: ";
    ssize_t len;

    unlink("server_socket");
    if ((srv_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        handle_error("socket");
    }

    srv_addr.sun_family = AF_UNIX;
    strcpy(srv_addr.sun_path, "/tmp/unix_sock");
    if (bind(srv_fd, (struct sockaddr *)&srv_addr, sizeof(srv_addr)) < 0) {
        handle_error("bind");
    }

    if (listen(srv_fd, 1) < 0) {
         handle_error("listen");
    }

    while (1) {
        cli_fd = accept(srv_fd, (struct sockaddr *)&cli_addr, &cli_len);
        len = read(cli_fd, buf + 6, sizeof(buf) - 6);
        buf[6 + len] = 0;
        write(cli_fd, buf, strlen(buf));
        close(cli_fd);
    }
    return 0;
}

    參考資料:
  • http://lwn.net/Articles/415651/ , net/unix: Allow Unix sockets to be treated like normal files.


github:
https://github.com/brook-kuo/Linux_Module/tree/master/socket/unix_as_normal_file


2011年11月19日 星期六

socket programming in bash


關於Bash的Socket部份您可以在man page中看到這段描述:
/dev/tcp/host/port
        If host is a valid hostname or Internet address, and port is an integer
        port number or service name, bash attempts to open a TCP connection to
        the corresponding socket.

/dev/udp/host/port
        If host is a valid hostname or Internet address, and port is an integer
        port number or service name, bash attempts to open a UDP connection to 
        the corresponding socket.

用一個簡單的例子就會懂了



2011年11月13日 星期日

HTML5 canvas的初體驗


HTML5的新的element,canvas,可以在Browser上繪製圖表/圖片。使用時必須訂出繪製的範圍(width/height),接著就可以開始用JavaScript進行繪圖了。目前多數支援canvas的browser看來也都只有支援2D,未來應該會有3D的。
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Canvas/Simple shapes (rectangles)</title>
    </head>
<body>
    <canvas id="myCanvas" width="300" height="150">
    Fallback content, in case the browser does not support Canvas.
    </canvas>
    <script type="application/x-javascript">
        // Get a reference to the element.
        var elem = document.getElementById('myCanvas');

        // 判斷是否能取得context
        if (elem && elem.getContext) {
            // 你只能對每一個canvas做initialize一次(getContext).
            // context = canvas . getContext(contextId [, ... ])
            var context = elem.getContext('2d');
            if (context) {
                // context.fillRect(x, y, w, h)
                // 畫方形
                context.fillRect(0, 0, 150, 100);

                // context.clearRect(x, y, w, h)
                // 清方形
                context.clearRect(100,50, 50, 50);

                // context.strokeRect(x, y, w, h)
                // 畫框
                context.strokeRect(150,100, 50, 50);
            }
        }
    </script>
</body>
</html>



fillRect(x, y, w, h)使用fillStyle來決定顏色。
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Canvas/FillRect attribute</title>
    </head>
<body>
    <canvas id="myCanvas" width="300" height="150">
    Fallback content, in case the browser does not support Canvas.
    </canvas>
    <script type="application/x-javascript">
        // Get a reference to the element.
        var elem = document.getElementById('myCanvas');

        // 判斷是否能取得context
        if (elem && elem.getContext) {
            // 你只能對每一個canvas做initialize一次(getContext).
            // context = canvas . getContext(contextId [, ... ])
            var context = elem.getContext('2d');
            if (context) {
                context.fillStyle = 'pink';
                context.fillRect(0, 0, 50, 50);

                context.fillStyle = '#f00'; // red
                context.fillRect(50, 50, 50, 50);
                context.fillStyle = '#0f0'; // green
                context.fillRect(100, 100, 50, 50);
                context.fillStyle = '#00f'; // blue
                context.fillRect(150, 150, 50, 50);

                // RGBA(red, green, blue, alpha)
                // Alpha1是透明度
                context.fillStyle = 'RGBA(100, 100, 255, 0.2)';
                context.fillRect(50, 50, 150, 150);
            }
        }
    </script>
</body>
</html>



而strokeRect(x, y, w, h)則會使用strokeStyle(顏色), lineWidth(粗細), lineJoin(連接觸樣式),等屬性來決定,其實就是line style。
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Canvas/Line styles</title>
    </head>
<body>
    <canvas id="myCanvas" width="300" height="150">
    Fallback content, in case the browser does not support Canvas.
    </canvas>
    <script type="application/x-javascript">
        // Get a reference to the element.
        var elem = document.getElementById('myCanvas');

        // 判斷是否能取得context
        if (elem && elem.getContext) {
            // 你只能對每一個canvas做initialize一次(getContext).
            // context = canvas . getContext(contextId [, ... ])
            var context = elem.getContext('2d');
            if (context) {
                // The beginPath() starts a new path
                context.beginPath();
                // reset the path to (0, 0)
                context.moveTo(0,0);
                context.strokeStyle = '#f00';

                // lineWidth是線的大小
                context.lineWidth = 1;
                context.strokeRect(0, 0, 20, 20);
                context.lineWidth = 10;
                context.strokeRect(30, 30, 20, 20);

                // LineJoin是連接處(轉角)的樣式
                context.lineJoin = 'bevel';
                context.strokeRect(60, 60, 20, 20);

                context.lineJoin = 'round';
                context.strokeRect(90, 90, 20, 20);

                context.lineJoin = 'miter';
                context.strokeRect(120, 120, 20, 20);
            }
        }
    </script>
</body>
</html>



參考資料:
  1. http://dev.opera.com/articles/view/html-5-canvas-the-basics/
  2. http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html
  3. https://developer.mozilla.org/en/Canvas_tutorial/Using_images
  4. http://wiki.moztw.org/%E7%94%A8_Canvas_%E7%95%AB%E5%9C%96
  5. http://www.w3school.com.cn/htmldom/dom_obj_canvas.asp


source code:
https://github.com/brook-kuo/JavaScript/tree/master/html5/canvas



2011年11月6日 星期日

關於bridge中hard_header_len/needed_headroom的問題


我的interface在收送上本來沒有問題,但是當它和其他interface作bridge之後就發生crash了,後來才發現是head不夠大,於是參考這篇文章"关于bridge中hard_header_len值的问题",做了些修改,原因是因為我的device在預留head room時,是hard_header_len+needed_headroom。而且有些local generate的packet會使用LL_RESERVED_SPACE()這macro來保留head room,而LL_RESERVED_SPACE()也會使用到needed_headroom,所以最保險的作法就是同時設定bridge的hard_header_len和needed_headroom。
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -369,6 +369,10 @@ void br_features_recompute(struct net_bridge *br)
 {
        struct net_bridge_port *p;
        unsigned long features, mask;
+#if 1 // Brook.
+    unsigned short max_hard_header_len = ETH_HLEN;
+    unsigned short max_needed_headroom = 0;
+#endif

        features = mask = br->feature_mask;
        if (list_empty(&br->port_list))
@@ -379,8 +383,22 @@ void br_features_recompute(struct net_bridge *br)
        list_for_each_entry(p, &br->port_list, list) {
                features = netdev_increment_features(features,
                                                     p->dev->features, mask);
+#if 1 // Brook.
+        if (p->dev->hard_header_len > max_hard_header_len) {
+            max_hard_header_len = p->dev->hard_header_len;
+        }
+
+        if (p->dev->needed_headroom > max_needed_headroom) {
+            max_needed_headroom = p->dev->needed_headroom;
+        }
+#endif
        }

+#if 1 // Brook.
+    br->dev->hard_header_len = max_hard_header_len;
+    br->dev->needed_headroom = max_needed_headroom;
+#endif
+
 done:
        br->dev->features = netdev_fix_features(features, NULL);
 }

    參考資料:
  1. 关于bridge中hard_header_len值的问题
  2. struct net_device结构中添加了needed_headroom/needed_tailroom成员



利用gen_init_cpio建立initrd的script


利用gen_init_cpio建立initrd的script
#!/bin/bash
#kernel的目錄
KERN_DIR=/usr/src/linux-kvm
#gen_initramfs_list.sh產生的暫存檔
INITRAMFS_LIST=/tmp/gen_initramfs_list
#initramfs的來源目錄, 為傳入該script的第一個參數
INITRAMFS_DIR=$1
#initrd的目的檔名, 為傳入該script的第二個參數
INITRD=$2
#給INITRAMFS_DIR default值
: ${INITRAMFS_DIR:="/home/brook/projects/rootfs"}
#給INITRD default值, 
: ${INITRD:="/home/brook/initrd"}

if [ ! -d $INITRAMFS_DIR ]; then
    echo "usage: $0 <initramfs_dir> <output_file>"
    exit 1
fi

sh $KERN_DIR/scripts/gen_initramfs_list.sh -d $INITRAMFS_DIR > $INITRAMFS_LIST
$KERN_DIR/usr/gen_init_cpio $INITRAMFS_LIST > $INITRD