Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Apr 1997 16:24:05 -0500
From:      Nanbor Wang <nw1@cs.wustl.edu>
To:        freebsd-hackers@freebsd.org
Subject:   Possible broken libc_r
Message-ID:  <199704232124.QAA21626@siesta.cs.wustl.edu>

next in thread | raw e-mail | index | archive | help
Hi All,

I found a possible bug in libc_r.  Below is a very simple test
program.  What I did was I opened a socket in the localhost between
client and server program.  When I compiled the program with
non-threaded library, everything worked just fine.  However, when I
compiled it using libc_r, the recv() system call seemed to be broken.
Without any specific manipulation, it acted as if I had turn on the
non-blocking flag.  Is this a bug or I did something terribly wrong?

TIA.

Nanbor

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	client.c
#	server.c
#	Makefile
#
echo x - client.c
sed 's/^X//' >client.c << 'END-of-client.c'
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <sys/errno.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netdb.h>
X#include <netinet/in.h>
X
X/* BSD socket client */
X                                 
X#define DEFAULT_SERVER_HOST "localhost"      
X#define DEFAULT_SERVER_PORT 10003
X#define STDIN               0
X#define STDOUT              1
X                             
Xint 
Xmain (int argc, char *argv[])                                   
X{ 
X  struct sockaddr_in saddr;                                          
X  struct hostent *hp;                                           
X  char *host = argc > 1 ? argv[1] : DEFAULT_SERVER_HOST;
X  u_short port_num = 
X    htons (argc > 2 ? atoi (argv[2]) : DEFAULT_SERVER_PORT);
X  char buf[BUFSIZ];	
X  int s_handle;                                        
X  int w_bytes;
X  int r_bytes;
X  int n;
X                                                                    
X  /* Create a local endpoint of communication */
X  if ((s_handle = socket (PF_INET, SOCK_STREAM, 0)) == -1)
X    perror ("socket"), exit (1);
X                                                                    
X  /* Determine IP address of the server */
X  if ((hp = gethostbyname (host)) == 0) 
X    perror ("gethostbyname"), exit (1);                             
X                                                                    
X  /* Set up the address information to contact the server */
X  memset ((void *) &saddr, 0, sizeof saddr);
X  saddr.sin_family = AF_INET;                                          
X  saddr.sin_port = port_num;
X  memcpy (&saddr.sin_addr, hp->h_addr, hp->h_length);
X
X  /* Establish connection with remote server */
X  if (connect (s_handle, (struct sockaddr *) &saddr, 
X		       sizeof saddr) == -1) 
X    perror ("connect"), exit (1);
X                                                                    
X  /* Send data to server (correctly handles 
X     "incomplete writes" due to flow control) */
X                                                                    
X  while ((r_bytes = read (STDIN, buf, sizeof buf)) > 0)
X    for (w_bytes = 0; w_bytes < r_bytes; w_bytes += n)
X      if ((n = send (s_handle, buf + w_bytes, 
X                      r_bytes - w_bytes, 0)) < 0)
X        perror ("write"), exit (1);
X                                                                    
X  if (recv (s_handle, buf, 1, 0) == 1)
X    write (STDOUT, buf, 1);
X    
X  /* Explicitly close the connection */
X  if (close (s_handle) == -1)
X    perror ("close"), exit (1);
X
X  return 0;
X}
END-of-client.c
echo x - server.c
sed 's/^X//' >server.c << 'END-of-server.c'
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <sys/errno.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/param.h>
X#include <netdb.h>
X#include <netinet/in.h>
X
X/* BSD socket server. */
X                                 
X#define DEFAULT_SERVER_HOST "localhost"      
X#define DEFAULT_SERVER_PORT 10003
X#define STDIN               0
X#define STDOUT              1
X
Xint main (int argc, char *argv[])
X{
X  u_short port_num = 
X    htons (argc > 1 ? atoi (argv[1]) : DEFAULT_SERVER_PORT);
X  struct sockaddr_in saddr;
X  int s_handle, n_handle;                                             
X  int addr_len ;
X
X  /* Create a local endpoint of communication */
X  if ((s_handle = socket (PF_INET, SOCK_STREAM, 0)) == -1)
X    perror ("socket"), exit (1);
X
X  /* Set up the address information to become a server */
X  memset ((void *) &saddr, 0, sizeof saddr);
X  saddr.sin_family = AF_INET;
X  saddr.sin_port = port_num;
X  saddr.sin_addr.s_addr = INADDR_ANY;
X
X  /* Associate address with endpoint */
X  if (bind (s_handle, (struct sockaddr *) &saddr, 
X            sizeof saddr) == -1) 
X    perror ("bind"), exit (1);
X
X  /* Make endpoint listen for service requests */
X  if (listen (s_handle, 5) == -1) 
X    perror ("listen"), exit (1);
X
X  /* Performs the iterative server activities */
X
X  for (;;) 
X    {
X      char buf[BUFSIZ];
X      int r_bytes;
X      struct sockaddr_in cli_addr;
X      int cli_addr_len = sizeof cli_addr;
X      struct hostent *hp;
X
X      /* Create a new endpoint of communication */
X      do 
X	n_handle = accept (s_handle, (struct sockaddr *) 
X			     &cli_addr, &cli_addr_len);
X      while (n_handle == -1 && errno == EINTR);
X	
X      if (n_handle == -1) 
X	{
X	  perror ("accept");
X	  continue;
X	}
X
X      addr_len = sizeof cli_addr.sin_addr.s_addr;
X      hp = gethostbyaddr ((char *) &cli_addr.sin_addr,
X                          addr_len, AF_INET);
X
X      if (hp != 0) 
X        printf ("client %s\n", hp->h_name), fflush (stdout);
X      else
X        perror ("gethostbyaddr");
X
X      /* Read data from client (terminate on error) */
X      do {
X	if ((r_bytes = recv (n_handle, buf, sizeof buf, 0)) > 0) {
X	  if (write (STDOUT, buf, r_bytes) != r_bytes)
X	    perror ("write"), exit (1);
X	}
X	else if (errno == EAGAIN)
X	  printf("\rEAGAIN, nbytes = %d", r_bytes) ;
X      } while (r_bytes > 0 || (r_bytes < 0 && errno == EAGAIN)) ;
X
X      puts("\n") ;
X      if (send (n_handle, "", 1, 0) != 1)
X	perror ("write"), exit (1);
X
X      /* Close the new endpoint 
X         (listening endpoint remains open) */
X      if (close (n_handle) == -1)   
X        perror ("close"), exit (1);
X      exit (0);
X    }
X  /* NOTREACHED */
X  return 0;
X}
END-of-server.c
echo x - Makefile
sed 's/^X//' >Makefile << 'END-of-Makefile'
X
XCFLAGS	=	-g
X
X# Program behave differently when compile with 
X# threaded library and non-threaded library
X# comment out next 2 lines for non-threaded version.
XLDFLAGS	=	-lc_r
XCFLAGS	+=	-D_THREAD_SAFE
X
X
Xall :		client server
X
Xserver :	server.o
X
Xclient :	client.o
X
Xserver.o :	server.c
X
Xclient.o :	client.cEND-of-Makefile
exit




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199704232124.QAA21626>