2 * socket.c -- socket library functions
4 * For license terms, see the file COPYING in this directory.
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
16 #if defined(STDC_HEADERS)
19 #if defined(HAVE_UNISTD_H)
22 #if defined(HAVE_STDARG_H)
30 #ifdef INADDR_BROADCAST
31 #define INADDR_NONE INADDR_BROADCAST
33 #define INADDR_NONE -1
38 * There are, in effect, two different implementations here. One
39 * uses read(2) and write(2) directly with no buffering, the other
40 * uses stdio with line buffering (for better throughput). Both
41 * are known to work under Linux. You get the former by configuring
42 * with --disable-stdio, the latter by configuring with --enable-stdio
48 * Size of buffer for internal buffering read function
49 * don't increase beyond the maximum atomic read/write size for
50 * your sockets, or you'll take a potentially huge performance hit
52 #define INTERNAL_BUFSIZE 2048
53 #endif /* USE_STDIO */
55 FILE *SockOpen(char *host, int clientPort)
59 struct sockaddr_in ad;
63 #endif /* USE_STDIO */
65 memset(&ad, 0, sizeof(ad));
66 ad.sin_family = AF_INET;
68 inaddr = inet_addr(host);
69 if (inaddr != INADDR_NONE)
70 memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
73 hp = gethostbyname(host);
76 memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
78 ad.sin_port = htons(clientPort);
80 sock = socket(AF_INET, SOCK_STREAM, 0);
83 if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
90 return fdopen(sock, "r+");
92 fp = fdopen(sock, "r+");
94 setvbuf(fp, NULL, _IOLBF, INTERNAL_BUFSIZE);
97 #endif /* USE_STDIO */
101 #if defined(HAVE_STDARG_H)
102 int SockPrintf(FILE *sockfp, char* format, ...)
105 int SockPrintf(sockfp,format,va_alist)
114 #if defined(HAVE_STDARG_H)
115 va_start(ap, format) ;
119 vsprintf(buf, format, ap);
121 return SockWrite(buf, 1, strlen(buf), sockfp);
127 int SockWrite(char *buf, int size, int len, FILE *sockfp)
134 n = write(fileno(sockfp), buf, len);
144 char *SockGets(char *buf, int len, FILE *sockfp)
151 if (read(fileno(sockfp), cp, 1) != 1)
152 return((char *)NULL);
164 int SockWrite(char *buf, int size, int len, FILE *sockfp)
166 int n = fwrite(buf, size, len, sockfp);
168 fseek(sockfp, 0L, SEEK_CUR); /* required by POSIX */
173 char *SockGets(char *buf, int len, FILE *sockfp)
175 return(fgets(buf, len, sockfp));
182 * Use the chargen service to test input beuffering directly.
183 * You may have to uncomment the `chargen' service description in your
184 * inetd.conf (and then SIGHUP inetd) for this to work.
188 FILE *fp = SockOpen("localhost", 19);
191 while (SockGets(buf, sizeof(buf)-1, fp))
192 SockWrite(buf, 1, strlen(buf), stdout);
196 /* socket.c ends here */