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>
