命令源码解析

来源:互联网 发布:阳光房顶棚防水 知乎 编辑:程序博客网 时间:2024/05/19 17:24

命令源码解析

//一般情况下,源码目录下会有一个Makeile,然后make之后,就能得到一些二进制文件//根据make的过程,可以判断出哪些文件被编译//在文件内,一般先定义一些变量,定义很多宏//在main函数内.//1.做初始化//2.设置设置成权限x,前提是the real user ID 是 root    uid = getuid();//returns the real user ID of the calling process.    if (setuid(uid)) {//sets the effective user ID of the calling process        perror("ping: setuid");        exit(-1);    }//3.解析参数//getopt//getopt_longwhile ((ch = getopt(argc, argv, COMMON_OPTSTR "bRT:")) != EOF){        switch(ch) {        case 'b':            broadcast_pings = 1;            break;        case 'Q':            settos = parsetos(optarg);            if (settos &&                (setsockopt(icmp_sock, IPPROTO_IP, IP_TOS,                    (char *)&settos, sizeof(int)) < 0)) {                perror("ping: error setting QOS sockopts");                exit(2);            }            break;        case 'R':            if (options & F_TIMESTAMP) {                fprintf(stderr, "Only one of -T or -R may be used\n");                exit(2);            }            options |= F_RROUTE;            break;        case 'T':            if (options & F_RROUTE) {                fprintf(stderr, "Only one of -T or -R may be used\n");                exit(2);            }            options |= F_TIMESTAMP;            if (strcmp(optarg, "tsonly") == 0)                ts_type = IPOPT_TS_TSONLY;            else if (strcmp(optarg, "tsandaddr") == 0)                ts_type = IPOPT_TS_TSANDADDR;            else if (strcmp(optarg, "tsprespec") == 0)                ts_type = IPOPT_TS_PRESPEC;            else {                fprintf(stderr, "Invalid timestamp type\n");                exit(2);            }            break;        case 'I':        {#if 0            char dummy;            int i1, i2, i3, i4;            if (sscanf(optarg, "%u.%u.%u.%u%c",                   &i1, &i2, &i3, &i4, &dummy) == 4) {                __u8 *ptr;                ptr = (__u8*)&source.sin_addr;                ptr[0] = i1;                ptr[1] = i2;                ptr[2] = i3;                ptr[3] = i4;                options |= F_STRICTSOURCE;            } else {                device = optarg;            }#else            if (inet_pton(AF_INET, optarg, &source.sin_addr) > 0)                options |= F_STRICTSOURCE;            else                device = optarg;#endif            break;        }        case 'M':            if (strcmp(optarg, "do") == 0)                pmtudisc = IP_PMTUDISC_DO;            else if (strcmp(optarg, "dont") == 0)                pmtudisc = IP_PMTUDISC_DONT;            else if (strcmp(optarg, "want") == 0)                pmtudisc = IP_PMTUDISC_WANT;            else {                fprintf(stderr, "ping: wrong value for -M: do, dont, want are valid ones.\n");                exit(2);            }            break;        case 'V':            printf("ping utility, iputils-ss%s\n", SNAPSHOT);            exit(0);        COMMON_OPTIONS            common_options(ch);            break;        default:            usage();        }    }    argc -= optind;//optind是解析到的参数的个数,argc是参数的总数,减去之后argc是错误的参数的个数    argv += optind;//当getopt返回后,此时argv已已经重新排序.argv+optind之后,指向了首个没有解析出来的参数//接下来对改变的各种参数进行判断并做各种动作getopt会做下面几件事1/对argv进行分析,每次返回一个argv[i]2/解析成功,optind加13/解析不成功,将argv[i]放入argv的后面4/接着分析-a 后面的参数,以optarg代入,且一个 -a 后面只能跟一个参数//main函数里面一般做的是初始化,设置权限,然后解析参数,设置状态位.然后接着,调用实际功能函数
原创粉丝点击