写一个检测网线是否被拔出的守护进程(嵌入式设备上)

来源:互联网 发布:网络软文广告 编辑:程序博客网 时间:2024/04/29 22:24

/*

        博主注明:

               编译环境: Ubuntu 10.4    编译器:arm-linux-gcc

               硬件环境:i.mx28  嵌入式linux版本 2.6.15

               介绍:

                             参考ethtool工具源代码,发现在对网卡的ioctl操作中,可以读出网卡的状态

*/


#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <signal.h>#include <sys/file.h>#include <netinet/in.h>#include <linux/if.h>#include <string.h>#include <sys/types.h>#include <arpa/inet.h>#include <sys/ioctl.h> //由于嵌入式linux貌似没有对ethtool_value这个结*构体的定义,但在非嵌入式的版本里是有的,所以直接抄过来= =...struct ethtool_value {    int cmd;    int data;}; //以下两个宏和ioctl有关,从网卡里获取网线的状态的关键就在这里#define ETHTOOL_GLINK        0x0000000a#define SIOCETHTOOL            0x8946#define UNCONNECT                0#define CONNECT                    1int main(int argc, char **argv){    int i, fd, fd2, fdtablesize, sock, last, ret;    pid_t pid;    struct sigaction sa;    struct ifreq ifr;    struct ethtool_value edata;    edata.cmd = ETHTOOL_GLINK;    edata.data = 0;   //以下是产生一个守*护进程的方法,具体注解就不再赘述,之前的博文里有详解    umask(0);    sa.sa_handler = SIG_IGN;    sigemptyset(&sa.sa_mask);    sa.sa_flags = 0;    //shutdown some signal    if(sigaction(SIGTTOU, &sa, NULL) < 0)    {        printf("can't ignore SIGTTOU\n");        return -1;    }       if(sigaction(SIGTTIN, &sa, NULL) < 0)    {        printf("can't ignore SIGTTIN\n");        return -1;    }       if(sigaction(SIGTSTP, &sa, NULL) < 0)    {        printf("can't ignore SIGTSTP\n");        return -1;    }       if(sigaction(SIGHUP, &sa, NULL) < 0)    {        printf("can't ignore SIGHUP\n");        return -1;    }       //terminate the father thread first    if(fork() != 0)    {        exit(1);    }    if(setsid() < 0)    {        exit(1);    }    //terminate the father thread second    if(fork() != 0)    {        exit(1);    }    //change work dir to root    if(chdir("/") == -1)    {        exit(1);    }    //shutdown some fds    for(fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++)    {        close(fd);    }    if(sigaction(SIGCHLD, &sa, NULL))    {        printf("can't ignore SIGCHLD\n");        return -1;    }    //access a socket    sock = socket(AF_INET, SOCK_DGRAM, 0);    if(sock == -1)    {        return -1;    }//这里是将要查询的端口名拷贝到指定位置    strcpy(ifr.ifr_name, "eth0");    ifr.ifr_data = (char *)&edata;//获取状态    ioctl(sock, SIOCETHTOOL, &ifr);       last = edata.data;//不断的读取网卡的状态    while(1)    { //偶尔也让它休息一下^_^        sleep(1);        ioctl(sock, SIOCETHTOOL, &ifr);//如果状态没有改变,就跳过,直接执行下一次查询        if(edata.data == last)        {            continue;        }        else        {            if(last == UNCONNECT)   //如果网线被插上了            {                //打开一个子进程,在里面调用一个脚本                if(fork() == 0)                {                //  pid = getpid();                    ret = execl("/data/work/ma_to_mt.sh", "master", NULL);                    if(ret < 0)                    {                        exit(1);                    }         //          return 0;  //这里没有必要使用return  因为execl执行了就不会返回了                     }                last = CONNECT;  //把状态改为已连接            }            else if(last == CONNECT)   //如果断开了网线            {                if(fork() == 0)         //开一个子进程,运行另一个脚本                {         //           pid = getpid();                    ret = execl("/data/work/mt_to_ma.sh", "managed", NULL);                    if(ret < 0)                    {                        exit(1);                    }                }                last = UNCONNECT;    //状态改为已断开            }                   }           waitpid(-1, NULL ,0);     //这个回收子进程的动作貌似也是没必要的= =....    }    return 0;}



原创粉丝点击