程序在FD_SET宏中挂起(select())

时间:2014-08-13 05:45:00

标签: c linux select

我的程序存在问题,我不知道这个问题的根源是什么。我的程序是从几个RFID阅读器(最多8个阅读器)读取数据,因此我使用select()来确定是否有要读取的数据。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>

#define KNRM  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"

int main(int argc, char *argv[]) {
    // Variables and constants
    int fd[8];
    int max_fd;
    char *devices[8];
    char name[256] = "Unknown";
    fd_set readset;

    printf("\n");

// 1. Setup check
    // 1.1 Check if user is root
    if ((getuid()) != 0) {
        printf(KRED "Warning: " KNRM "You are not root! This may not work.\n");
    }

    // 1.2 Check that all of the argument vectors has data (within the argument count)
    for(int i = 1; i < argc; i++){
        if (argv[i] == NULL) {
            printf(KRED "Error: " KNRM "Something is wrong with the path to the device event\n");
            exit(0);
        }
    }

    // 1.3 Copy the vectors to device array
    for(int i = 1; i < argc; i++){
        devices[i] = argv[i];
    }


// 2. Open Devices
    for(int i = 1; i < argc; i++){
        if ((fd[i] = open(devices[i], O_RDONLY)) == -1){
            printf(KRED "Warning: " KNRM "%s is not a valid device.\n", devices[i]);
        }
    }


// 3. Print Device Names
    printf("\n----------------------------------------------------------------------------\n");
    for(int i = 1; i < argc; i++){
        // Check if device open was successful
        if(fd[i] != -1){
            ioctl(fd[i], EVIOCGNAME(sizeof(name)), name);
            printf(" Reading From : %s (%s)\n", devices[i], name);
        }
    }
    printf("----------------------------------------------------------------------------\n");
    printf("\n");

    // 3.1 Initialize set
    FD_ZERO(&readset);
    max_fd = 0;
    for(int j = 0; j < argc; j++){
        printf(KGRN "now here" KNRM "\n");
        FD_SET(fd[j], &readset);        // <-- Stalls here!!
        printf("not here\n");
        max_fd = (max_fd > fd[j]) ? max_fd : fd[j];
        printf("%i\n", max_fd);
    }

// 4. Now, check for readability
    int result = select(max_fd+1, &readset, NULL, NULL, NULL);
    if (result == -1) {
       printf(KRED "Warning: " KNRM "Some error occurred while checking for readability\n\n");
    } else {
        for (int i = 0; i < argc; i++) {
            if (FD_ISSET(fd[i], &readset)) {
                printf("%u is readable\n", fd[i]);
          }
       }
    }

    return 0;
}

它在这一行中挂起(当评论第4点时,如果没有评论第4点,程序将退出同一行):

FD_SET(fd[j], &readset);        // <-- Stalls here!!

我不知道出了什么问题,所以任何建议都表示赞赏! (下面是一个屏幕截图,说明正在运行的程序)

Example compiling and running the program

1 个答案:

答案 0 :(得分:1)

您对程序中数组的索引不一致,当您访问未初始化的索引0时,为您提供undefined behavior

您也不检查未打开的文件描述符,并盲目地尝试在fd中设置和使用全部。