Bug#614378: libc6: Select()don't work properly on squeeze amd64
Package: libc6
Version: 2.11.2-10
Severity: important
/ Author : L.Sillari
// Date: 17/02/2011
// This example show a bug on debian 6 64 bit .
// using nonblocking socket .
// On this example the code must run forever if you use an unknown destination.
// On Debina 6 64bit that not appen .. after the same time it stop because of "Select()" (the Select returns 1 and not 0) .
// No problem using Debian 6 32bit or Debian 5 64 bit
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int sockfd; // Global variable
main(int argc, char *argv[])
{
//socket structure
struct sockaddr_in serv_addr;
struct hostent *server;
int opts; // Socket Option
int value=1;
int _port=35; // TCP port
/// Open socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
/// Error opening socket
printf("\n Error on socket() exit.\n");
exit(1);
}
/// NonBlocking socket setup
opts = fcntl(sockfd, F_GETFL, 0);
if (opts!=-1)
{
opts=fcntl(sockfd, F_SETFL, opts | O_NONBLOCK);
}
if (opts==-1)
{
/// Error
printf("\n Error on fcntl()\n");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(value)) < 0)
{
printf("\n Error on setsockopt()\n");
exit(1);
}
/// Put an unknown address to verify the bug
server = gethostbyname("192.168.79.110");
if (server == NULL)
{
/// Error
printf("\n Error on gethostbyname()\n");
exit(1);
}
memset((char *) &serv_addr, 0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *)&serv_addr.sin_addr.s_addr,(char *)server->h_addr, server->h_length);
serv_addr.sin_port = htons(_port);
/// NONBLOCKING Connection
//opts=connect(sockfd,(const sockaddr *)&serv_addr,sizeof(serv_addr));
opts=connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
if ((opts < 0 ) && (errno != EINPROGRESS))
{
printf("\n Error on connect()\n");
exit(1);
}
while (waitConnection(100) == 0) // We poll the connection ..
{
printf("WaitConnection \n");
}
printf("\n This is the bug: on Debian 6 squeeze(64bit) not on Debian 5 Lenny(64bit) \n");
}
int waitConnection(int _ms)
{
// wait the connection
extern int sockfd;
struct timeval tv;
int retval;
int valopt;
socklen_t len;
/// Connection handle
fd_set cnds;
FD_ZERO(&cnds);
/// Init Timeout
tv.tv_sec = 0;
tv.tv_usec = _ms * 1000;
FD_SET(sockfd,&cnds);
/// Wait on the select.
/// to verify the connection : writing channel
retval = select(sockfd+1, NULL, &cnds, NULL , &tv);
/// Error
if ( retval < 0 )
{
printf("\n Error on select ... \n");
exit(1);
}
/// Something appened
if ( retval > 0 )
{
if ( FD_ISSET(sockfd,&cnds) )
{
//Error check
len=sizeof(valopt);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &len) < 0) return 0;
if (valopt!=0) return 0;
printf("\n Wrong event : the destination doesn't exist but it seems connected !!!\n");
return 1;
}
}
return 0;
}
-- System Information:
Debian Release: 6.0
APT prefers stable
APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.32-5-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages libc6 depends on:
ii libc-bin 2.11.2-10 Embedded GNU C Library: Binaries
ii libgcc1 1:4.4.5-8 GCC support library
libc6 recommends no packages.
Versions of packages libc6 suggests:
ii debconf [debconf-2.0] 1.5.36.1 Debian configuration management sy
pn glibc-doc <none> (no description available)
ii locales 2.11.2-10 Embedded GNU C Library: National L
-- debconf information:
glibc/upgrade: true
glibc/disable-screensaver:
glibc/restart-failed:
glibc/restart-services:
Reply to: