LINUX.ORG.RU

покритикуйте следующий код(не мой)


0

0

int connect_nb(int sockfd, struct sockaddr *serv_addr, socklen_t addrlen){                                                     
    int             flags, res, error;                                                                                         
    socklen_t       len;                                                                                                       
    struct pollfd   p;                                                                                                         
                                                                                                                               
    if((flags = fcntl(sockfd, F_GETFL, 0)) < 0)                                                                                
        {   syslog(LOG_ERR, "fcntl GETFL failed: %s", strerror(errno));        return -1;    }                                 
    if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0)                                                                         
        {   syslog(LOG_ERR, "fcntl SETFL failed: %s", strerror(errno));        return -1;    }                                 
                                                                                                                               
    error = 0;                                                                                                                 
    if((res = connect(sockfd, serv_addr, addrlen)) < 0)  if(errno!=EINPROGRESS)return -1;                                      
                                                                                                                               
    if(res == 0) { /* connect completed immediately (usually localhost) */                                                     
        if(fcntl(sockfd, F_SETFL, flags) < 0)                                                                                  
            {   syslog(LOG_ERR, "fcntl reSETFL failed: %s", strerror(errno));  return -1;     }                                
        return 0;                                                                                                              
    }                                                                                                                          
                                                                                                                               
    memset(&p, 0, sizeof(p));                                                                                                  
    p.fd = sockfd;                                                                                                             
    p.events = POLLOUT;                                                                                                        
    if((res = poll(&p, 1, SERVER_TO * 1000)) != 1) {                                                                           
        if(res == 0) {  errno = ETIMEDOUT;  }   /* timeout */                                                                  
        return -1;                                                                                                             
    }                                                                                                                          
                                                                                                                               
    /* socket is writeable == operation completed */                                                                           
    len = sizeof(error);                                                                                                       
    if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)                                                             
        {   syslog(LOG_ERR, "getsockopt failed: %s", strerror(errno));         return -1;    }                                 
                                                                                                                               
    if(fcntl(sockfd, F_SETFL, flags) < 0)     /* restore file status flags */                                                  
        {   syslog(LOG_ERR, "fcntl reSETFL failed: %s", strerror(errno));      return -1;    }                                 
                                                                                                                               
    if(error){  errno = error;  return -1;  }   /* getsockopt() shows an error */                                              
                                                                                                                               
    /* really connected */                                                                                                     
    return 0;                                                                                                                  
} 
★★★★★
Ответ на: комментарий от klalafuda

Ок, а ещё такой нюанс насколько корректно при помощи poll ловить завершение неблокирующего connect???? причём именно таким образом??

cvv ★★★★★
() автор топика
Ответ на: комментарий от cvv

> насколько корректно при помощи poll ловить завершение неблокирующего connect????

Я обычно делаю select() но AFAIK poll() не хуже :-/

> причём именно таким образом??

Вот тут не знаю... наизусть не помню, а читать ломает ;-)

Onanim
()

попробуйте посмотреть похожий код в программах smf-clamd, smf-spamd... там вроде чуть более корректно это реализовано.

anonymous
()
Ответ на: комментарий от Onanim

> Прокомментируешь?

белые люди имеют привычку закрывать сокет после получения ошибки, что явным образом в ней не делается. впрочем, может быть автор кода предпологает делать это по выходу из функции -> если это так, то все в принципе ok. главное об этом не забывать и ему и его пользователям..

ps: чем ему не угодил select() не понимаю. лично мне он как-то привычнее.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от klalafuda

> > Прокомментируешь?

> белые люди имеют привычку закрывать сокет после получения ошибки, что
> явным образом в ней не делается. впрочем, может быть автор кода
> предпологает делать это по выходу из функции -> если это так, то все в
> принципе ok. главное об этом не забывать и ему и его пользователям..

В функцию передается уже готовый (открытый) файл-дескриптор (сокет).
Логично, что функция его не закрывает и оставляет на усмотрение
вызывающего (кто открыл тот и закроет).
Так обычно поступают программисты всех оттенков.

> ps: чем ему не угодил select() не понимаю. лично мне он как-то
> привычнее.

Да, я тоже в таких случаях использую select. Но IMHO это
просто дело привычки.

Onanim
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.