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