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>