1 /* Simple sockets interface derived from the sockets UICI
2 implementation in Appendix B of Practical UNIX Programming,
3 K. A. Robbins and S. Robbins, Prentice Hall, 1996. */
5 #if defined(__MWERKS__) && defined(macintosh)
12 #include <sys/types.h>
18 #elif defined(MACINTOSH)
23 # include <sys/socket.h>
24 # include <netinet/in.h>
25 # include <netinet/tcp.h>
29 #if defined(__hpux) || defined(MACINTOSH)
30 extern int h_errno
; /* HP-UX 9.05 and GUSI forget to declare this in netdb.h */
35 static int Sock_error(Sock_error_t perr
, int e
, int he
)
45 extern void __sinit(void);
46 extern int __initialize (void *ignoredParameter
);
47 int __initialize(void *ignoredParameter
) {
57 WORD wVers
= MAKEWORD(1, 1);
58 if (WSAStartup(wVers
, &wsaData
) != 0)
60 #elif defined(MACINTOSH)
61 GUSISetup(GUSIwithInternetSockets
);
62 #elif defined(SIGPIPE)
64 if (sigaction(SIGPIPE
, (struct sigaction
*)NULL
, &act
) < 0)
66 if (act
.sa_handler
== SIG_DFL
) {
67 act
.sa_handler
= SIG_IGN
;
68 if (sigaction(SIGPIPE
, &act
, (struct sigaction
*)NULL
) < 0)
75 int Sock_open(Sock_port_t port
, Sock_error_t perr
)
78 struct sockaddr_in server
;
80 if ((sock
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0)
81 return Sock_error(perr
, errno
, 0);
83 server
.sin_family
= AF_INET
;
84 server
.sin_addr
.s_addr
= INADDR_ANY
;
85 server
.sin_port
= htons((short)port
);
87 if ((bind(sock
, (struct sockaddr
*)&server
, sizeof(server
)) < 0) ||
88 (listen(sock
, MAXBACKLOG
) < 0))
89 return Sock_error(perr
, errno
, 0);
93 int Sock_listen(int fd
, char *cname
, int buflen
, Sock_error_t perr
)
95 struct sockaddr_in net_client
;
96 int len
= sizeof(struct sockaddr
);
98 struct hostent
*hostptr
;
101 retval
= accept(fd
, (struct sockaddr
*)(&net_client
), &len
);
102 while (retval
== -1 && errno
== EINTR
);
104 return Sock_error(perr
, errno
, 0);
106 if (cname
!= NULL
&& buflen
> 0) {
109 struct in_addr
*iaddr
= &(net_client
.sin_addr
);
110 hostptr
= gethostbyaddr((char *)iaddr
, sizeof(struct in_addr
), AF_INET
);
111 name
= (hostptr
== NULL
) ? "unknown" : hostptr
->h_name
;
113 if (buflen
< nlen
+ 1)
115 strncpy(cname
, name
, nlen
);
121 int Sock_connect(Sock_port_t port
, char *sname
, Sock_error_t perr
)
123 struct sockaddr_in server
;
128 if (! (hp
= gethostbyname(sname
))
129 || (sock
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0)
130 return Sock_error(perr
, errno
, h_errno
);
132 memcpy((char *)&server
.sin_addr
, hp
->h_addr_list
[0], hp
->h_length
);
133 server
.sin_port
= htons((short)port
);
134 server
.sin_family
= AF_INET
;
137 retval
= connect(sock
, (struct sockaddr
*) &server
, sizeof(server
));
138 while (retval
== -1 && errno
== EINTR
);
140 Sock_error(perr
, errno
, 0);
151 int Sock_close(int fd
, Sock_error_t perr
)
154 if (closesocket(fd
) != 0)
155 return Sock_error(perr
, WSAENOTSOCK
, 0);
158 return Sock_error(perr
, errno
, 0);
164 ssize_t
Sock_read(int fd
, void *buf
, size_t size
, Sock_error_t perr
)
168 retval
= recv(fd
, buf
, size
, 0);
169 while (retval
== -1 && errno
== EINTR
);
171 return Sock_error(perr
, errno
, 0);
176 ssize_t
Sock_write(int fd
, void *buf
, size_t size
, Sock_error_t perr
)
180 retval
= send(fd
, buf
, size
, 0);
181 while (retval
== -1 && errno
== EINTR
);
183 return Sock_error(perr
, errno
, 0);