Возвращаемое значение fcntl () с флагом F_GETFD? - PullRequest
0 голосов
/ 30 октября 2018

Я использую fcntl () для файлового дескриптора со следующим вызовом:

Retval = select(
    MaxSocketId + 1,
    &ReadSocketSet,
    (fd_set *)NULL,
    (fd_set *)NULL,
    (struct timeval *)NULL
);

if (Retval <= 0) {
    for (lIndexFD = 3; lIndexFD < (MaxSocketId + 1); lIndexFD++) {
        if ((lFlag = fcntl(lIndexFD, F_GETFD)) < 0) {
            if (errno == 9) {
                FD_CLR(lIndexFD, &ActiveSocketSet);
            }
        }
        else
            printf(" \n In fcntl Else cond %d ", lFlag);
    }
    continue;
}

Но мой процесс идет в бесконечном цикле в состоянии else для fcntl (). Похоже, что fcntl () возвращает 0.

Я хотел бы знать, в каком состоянии он возвращает 0 и что делать, чтобы справиться с этой ситуацией.

1 Ответ

0 голосов
/ 30 октября 2018

UPDATE:

if (Retval <= 0) может измениться на if (Retval < 0).

Когда Retval равен нулю, select работает нормально.

Если Retval равно -1, а errno равно EBADF, используйте fcntl, проверьте, что fd действителен.

Вы смотрели fcntl, он всегда возвращает 0, потому что:

  1. Не установлены флаги FD_CLOEXEC для fd

  2. select не сбой и fcntl тоже не сбой, потому что все fd действительны.


fcntl имеют много видов cmd. При использовании F_GETFD это означает получение флагов дескриптора файла.

Проверьте руководство fcntl, в этом типе есть только один флаг (FD_CLOEXEC). Так что если не установить этот флаг для fd, то F_GETFD вернет значение 0.

Флаги дескриптора файла

Следующие команды управляют флагами, связанными с дескриптором файла. В настоящее время определен только один такой флаг: FD_CLOEXEC, флаг закрытия при исполнении. Если бит FD_CLOEXEC равен 0, файл дескриптор останется открытым через execve (2), в противном случае он будет закрыт.

  F_GETFD (void)
         Read the file descriptor flags; arg is ignored.

  F_SETFD (int)
         Set the file descriptor flags to the value specified by arg.

Когда он не вернет 0?

  1. Когда open один файл, флаг FD_CLOEXEC по умолчанию отключен. Вы можете включить его следующим образом.

    fd = open(filepath, O_RDONLY | O_CLOEXEC)
    
  2. Позвоните fcntl(fd, F_SETFD, FD_CLOEXEC), чтобы включить флаг FD_CLOEXEC.

...