【09.03.24】在Ubuntu中和Android中添加開機自啓動的守護進程

昨天和今天實驗了向Android中添加一個守護進程,鼓搗了2天,小有點收穫,自己編寫的進程添加進這兩個操作系統的開機啓動中了。但離完全成功似乎還有些距離。另外今天還看了下解壓、修改Android的ramdisk.img的方法。

先把我的守護進程(daemon09.c)發到這裏

/************************程序開始**************************/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
    int i=0,fd;
    pid_t pid;
    struct rlimit rl;
    char str[]="Writing Test is going...\n";

    umask(0);
    if(getrlimit(RLIMIT_NOFILE,&rl)<0)
        printf("getrlimit函數調用出現錯誤!\n");
    if((pid=fork())<0)
    {
        printf("fork出現錯誤!\n");
        exit(1);
    }
    else if(pid>0)//父進程退出
    {
        printf("父進程退出,它的ID爲%d,它的子進程ID爲%d\n",getpid(),pid);
        exit(0);
    }
    //子進程
    sleep(2);
    printf("子進程ID爲%d\n",getpid());

    setsid();
    if((pid=fork())<0)
    {
        printf("fork出現錯誤!\n");
        return -1;
    }
    else if(pid>0)//第一個子進程退出
    {
        printf("第一個子進程退出,它的ID爲%d,它的子進程ID爲%d\n",getpid(),pid); /*這個printf的內容可以被輸出,貌似是因爲它所在的進程雖然失去了終端,但它是一個會話組的首進程,因此看到有printf後,自己又申請了一個終端?*/
        exit(0);
    }

    //第二個子進程
    printf("不會輸出這一行。\n");/*這個printf的內容將不會在屏幕上輸出,原因可能是因爲它所在的進程此時已經不是一個會話組的首進程,無法重新申請獲得終端?*/
    chdir("/");
    if(rl.rlim_max==RLIM_INFINITY)
        rl.rlim_max=1024;
    printf("%d",(int)rl.rlim_max);
    for(i=0;i<rl.rlim_max;i++)
        close(i);
    open("/dev/null",O_RDWR);
    dup(0);
    dup(0);
   
    //每隔5s向文件內寫入一次數據
    while(1)
    {
        fd=open("/data/deamon.txt",O_WRONLY|O_CREAT|O_APPEND,0766);/*這裏的/data指的是android系統上的/data目錄*/
        write(fd,str,sizeof(str));
        sleep(5);
    }
    close(fd);
    exit(0);
}
/************************程序結束**************************/

因爲andorid也是基於LINUX內核的,因此我想一開始先試驗一下是否可以把這個進程在Ubuntu中開機自啓動。
通過在/etc/rc.local文件中加入了一行“/usr/myfiles/test/daemon09”,成功讓daemon09在Ubuntu開機時啓動了。(注意,這裏在LINUX下啓動的話,上面的C程序中紅字部分可能需要改變一下,因爲Ubuntu下沒有/data這樣一個路徑)

在Ubuntu Linux下成功之後,就轉而看看在android下是否能行。android啓動後的根目錄下的init.rc似乎是管這個的(源碼目錄/system/core/rootdir/init.rc,make後就是它),於是我試着對源文件做修改再make運行,但一開始總是不得要領,不知道init.rc中的語法是什麼。後來在google論壇上找了下,原來init.rc的內容在“android源碼路徑/system/core/init/readme.txt“內有說明。於是根據那個搞了幾個小時(沒辦法,本人是菜鳥),基本上弄出來了,android模擬器啓動後,自己寫的進程也成功加入了。方法如下:

在init.rc的那一堆以service開頭的語句中插入一段新的service語句。格式如下:

#my_deamon_test是服務名稱,後面跟的是你編寫的要開機啓動的程序及路徑,這裏的路徑是android系統中的路徑
service my_deamon_test /data/deamon_test
     oneshot(不加這一句似乎不行,少了它可能你的程序啓動不起來)

oneshot選項的含義(在android源碼路徑/system/core/init/readme.txt內有說明):
Do not restart the service when it exits.


===============================
另外,這兩天在網上看了一些android下的調試技巧,貼到這裏備忘

1、解壓、修改Android的ramdisk.img的方法
將ramdisk.img複製一份到任何其他目錄下,將其名稱改爲ramdisk.img.gz,並使用命令
gunzip ramdisk.img.gz
然後新建一個文件夾,叫ramdisk吧,進入,輸入命令
cpio -i -F ../ramdisk.img
這下,你就能看見並。

根據自己的需要對裏面的內容修改之後,可以使用下列命令重新打包成鏡像
cpio -i -t -F ../ramdisk.img > list
cpio -o -H newc -O lk.img < list  
當前目錄下生成的lk.img就是我們的新鏡像了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章