fflush() nightmares

mchawi at garnet.berkeley.edu mchawi at garnet.berkeley.edu
Thu Jun 22 23:33:58 AEST 1989


      it is in these dark moments of being really confounded by seemingly
 simple problems for long periods of time that i fling my problems forth:

      on sunos 3.5 (egads!), given a child process that has its  stdin  &
 stdout tied to an AF_INET socket, it seems that it is necessary to force
 a fflush() to send output through the socket connection.  i  don't  want
 to  change the child program in any way (it's huge), it just does simple
 printf's and gets().  this problem doesn't occur prior to the exec()!  i
 thought  that  the child inherits the exact same file descriptors.  here
 are [3] programs (server, client, & child) that demo the problem:

/*-(cut-here)---------------------------------------------------------*/


#include <stdio.h>
#include <fcntl.h>
#include <sgtty.h>

char b[380];


int main ()
{
	struct sgttyb t, u;
	int fd, status, pid, w;

	if (setup_inet (&fd))		/* set up a server socket */
		return (-1);


	if ((pid = fork ()) == 0)
	{
		close (0); dup (fd);	/* redirect stdio */
		close (1); dup (fd);

		close (fd);

		printf ("inside child's for() call, b4 the exec().\n");
		printf ("\nthese lines print out ok to the client.\n");

		execlp ("gekko", "gekko", (char *) 0);
		exit   (127);
	}

	close (fd);
	while ((w = wait (&status)) != pid && w != -1)
		;
}


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

static struct sockaddr_in server;
/*--------------------------------------*/
int setup_inet (pfd)
int *pfd;
{
	int sock, length;

	sock = socket (AF_INET, SOCK_STREAM, 0);	/* create socket */
	if (sock < 0)
		exit (-1);

	server.sin_family      = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port        = 0;

	if (bind (sock, &server, sizeof (server)))
		{ perror ("binding stream socket\n"); exit (-1); }

	/* find out assigned port number */
	length = sizeof (server);
	getsockname (sock, &server, &length);

	printf ("server: socket has port #%d\n", ntohs (server.sin_port));

	listen (sock, 5);
	*pfd = accept (sock, 0, 0);	/* start accepting connections */
	return (0);
}

/*-(cut-here)---------------------------------------------------------*/

	/* "gekko", the child program: */

#include <stdio.h>
#include <sgtty.h>

main ()
{
	char b[80];

	for (;;)
	{
		printf ("input: ");
		gets   (b);
		printf ("got: %s\n", b);

#if !PROBLEM_SOLVED
		fflush (stdout);	/* <<<--- WANNA EXCLUDE THIS */
#endif
	}
}

/*-(cut-here)---------------------------------------------------------*/


/* client program, simplified.  enter the name of the machine the
server program is running on, and the port number it returns. */


#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>



char host [22];
int port;

int fd;
struct sockaddr_in x;
struct timeval ts;



/*----------------------*/
main ()
{
	char b[333];
	struct hostent *hp;

	ts.tv_sec  = 5;
	ts.tv_usec = 0;

	printf ("host? "); gets (host);		/* get the name & number */
	printf ("port? "); gets (b); port = atoi (b);

	fd = socket (AF_INET, SOCK_STREAM, 0);

	bzero ((char *) &x, sizeof (struct sockaddr_in));
	x.sin_family = AF_INET;

	hp = gethostbyname (host);
	if (hp == NULL) exit (-1);

	bcopy (hp->h_addr, (char *) &x.sin_addr, hp->h_length);
	x.sin_port = (unsigned short) htons (port);

	/* connect the client */
	if (connect (fd, &x, sizeof (struct sockaddr_in)) < 0)
		{ perror ("not connected"); exit (-1); }

	main_loop ();
}


/*----------------------*/
main_loop ()
{
	int i, n;
	char B[256];

	for (;;)
	{
		printf ("0 - quit; 1 - read; 2 - write.\n");
		printf ("what? ");
		gets (B);
		switch (B[0])
		{
		case '1':
			if (read_socket (B, &n))
				return (-1);

			if (n)
				printf ("--> %s\n", B);

			break;
		case '2':
			printf ("string: ");
			gets (B);
			i = strlen (B);
			if (!i)
				break;

			B[i] = '\n'; B[i+1] = '\0';

			if (write_socket (B))
				return (-1);
			break;
		default:
			return (close (fd));
			break;
		}
	}
}


/*----------------------*/
int read_socket (b, n)
char *b;
int *n;
{
	int ready, nfd;

	ready = 1 << fd;
	nfd = select (20, &ready, (int *)0, (int *)0, &ts);
	if (ready && nfd > 0)
	{
		*n = read (fd, b, 2048);
		if (*n > 0)
			b[*n] = '\0';
	}

	return (0);
}


/*----------------------*/
int write_socket (b)
char *b;
{
	int ready;

	ready = 1 << fd;
	select (20, (int *)0, &ready, (int *)0, &ts);
	write (fd, b, strlen (b));
	return (0);
}



More information about the Comp.unix.wizards mailing list