From: gadbois AT cyc DOT com (David Gadbois) Subject: fdopen() on sockets? 17 Jun 1998 02:37:03 -0700 Message-ID: <199806162259.RAA11487.cygnus.gnu-win32@lagavulin.cyc.com> To: gnu-win32 AT cygnus DOT com 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 #include #include #include #include #include #include #include #include #include #include #include #include #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!\r\n" 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 "gnu-win32-request AT cygnus DOT com" with one line of text: "help".