Subject: fdopen() on sockets?
From: [email-masked]

22 Jun 1998 22:14:42 -0700
Message-ID: <[email-masked]>

I recently installed a vanilla b19.1 and am re-porting a bunch of code
from b18.

I have some library code that takes sockets that turns sockets into
FILE *'s so that calling code doesn't need to worry if it is dealing
with a socket or a regular file. fdopen() is failing on sockets with
EBADF. Is there a workaround?

Test case appended. Oh, and as a bonus question, I normally rig
things so that detected program errors print a message and send a
SIGINT to the process. (See the function die() below.) When running
under gdb, this normally returns control to gdb with all the stack
ready for examination. The B19 behavior is for the program to exit.

--David Gadbois

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

#define PROGRAM "socket-fdopen"

void die(char *format, ...) {
va_list args;

fprintf(stderr, "%s: ", PROGRAM);
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
if (errno)
fprintf(stderr, ": %s", strerror(errno));
fprintf(stderr, ".n");
kill(getpid(), SIGINT);
}

#define MESSAGE "Eat flaming death, monkey boy!rn"

int main(int argc, char **argv) {
int port;
struct sockaddr_in addr;
int sfd;

if (argc == 1)
die("Must specify a port number to listen to.");
port = atoi(argv[1]);
if (port < 1024 || port > 65536)
die("Invalid port %d", port);

/* Make sure Winsock gets initialized. */
getprotobyname("tcp");

if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die("socket");

{
int reuseaddr = 1;

if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR,
(char *) &reuseaddr, sizeof(reuseaddr)) != 0)
die("setsockopt");
}

(void) memset((void *) &addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons((u_short) port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);

if (bind(sfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
die("bind");

if (listen(sfd, 5) < 0)
die("listen");

while (1) {
int new_sfd;
struct sockaddr_in peer_addr;
int peer_addr_len = sizeof(peer_addr);

if ((new_sfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_len)) < 0)
die("accept");
#if 1
{
FILE *fp;

if ((fp = fdopen(new_sfd, "w")) == NULL)
die("fdopen");
if (fwrite(MESSAGE, sizeof(char), strlen(MESSAGE), fp) != strlen(MESSAGE))
die("fwrite");
if (fclose(fp) != 0)
die("fclose");
}
#else
if (write(new_sfd, MESSAGE, strlen(MESSAGE)) != strlen(MESSAGE))
die("write");
if (close(new_sfd) != 0)
die("close");
#endif
}
}
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".