Annotation of OpenXM/src/ox_toolkit/mysocket.c, Revision 1.6
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.6 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/mysocket.c,v 1.5 2000/11/30 16:07:35 ohara Exp $ */
1.5 ohara 3: /*
1.3 ohara 4: Q: How to get a local port number?
5: A: You do setsockopt() to set options and do socket(), bind().
6: An OS set a local port for you.
7: In order to get the local port, you need to do getsockname().
8: (See [1] pp. 91, pp. 187 for detail)
9:
10: Reference
1.5 ohara 11: [1] W. Richard Stevens, "UNIX Network Programming", 2nd ed. Vol. 1 (Japanese version)
1.1 ohara 12: */
13:
14: #include <stdio.h>
15: #include <stdlib.h>
16: #include <unistd.h>
17: #include <errno.h>
18: #include <netdb.h>
1.4 ohara 19: #include <string.h>
1.1 ohara 20: #include <netinet/in.h>
21: #include <sys/types.h>
22: #include <sys/socket.h>
23: #include <fcntl.h>
24:
25: #if defined(__sun__)
26: #include <arpa/inet.h>
27: #endif
28:
29: #include "mysocket.h"
30:
1.5 ohara 31: typedef struct ox_sockopt {
32: int level;
33: int option_name;
34: void* option_value;
1.6 ! ohara 35: int option_len;
1.5 ohara 36: } ox_sockopt;
37:
38: static int getsocket(struct sockaddr_in *mp, char *host, int port)
1.1 ohara 39: {
40: struct hostent *ent = gethostbyname(host);
1.5 ohara 41:
1.1 ohara 42: memset(mp, '\0', sizeof(struct sockaddr_in));
43: mp->sin_family = AF_INET;
1.5 ohara 44: mp->sin_port = htons((short)port);
1.1 ohara 45: memcpy((char *)&mp->sin_addr, ent->h_addr, ent->h_length);
46:
47: return socket(AF_INET, SOCK_STREAM, 0);
48: }
49:
1.5 ohara 50: static int ox_connect(char *hostname, int port, ox_sockopt *opt)
1.1 ohara 51: {
1.5 ohara 52: struct sockaddr_in serv;
53: int s = getsocket(&serv, hostname, port);
54: if (connect(s, (struct sockaddr *)&serv, sizeof(serv)) != 0) {
55: fprintf(stderr, "ox_connect: failed. socket = %d, errno = %d\n", s, errno);
56: return -1;
57: }
58: return s;
1.1 ohara 59: }
60:
1.5 ohara 61: static int ox_listen(char *hostname, int *port, int backlog, ox_sockopt *opt)
1.1 ohara 62: {
63: struct sockaddr_in me;
1.5 ohara 64: int s_waiting = getsocket(&me, hostname, *port);
1.1 ohara 65:
1.5 ohara 66: setsockopt(s_waiting, opt->level, opt->option_name,
67: opt->option_value, opt->option_len);
68: if (bind(s_waiting, (struct sockaddr *)&me, sizeof(me)) < 0
69: || listen(s_waiting, backlog) < 0) {
70: fprintf(stderr, "ox_listen: failed.\n");
71: return -1;
72: }
73: return s_waiting;
74: }
1.1 ohara 75:
1.5 ohara 76: static int ox_getport(int s_waiting)
77: {
78: struct sockaddr_in me;
79: int len = sizeof(me);
80: if (getsockname(s_waiting, (struct sockaddr *)&me, &len) < 0) {
81: fprintf(stderr, "ox_getport: failed.\n");
82: return -1;
1.1 ohara 83: }
1.5 ohara 84: return ntohs(me.sin_port);
85: }
1.1 ohara 86:
1.5 ohara 87: int mysocketAccept(int s_waiting)
88: {
89: /* return ox_accept(s_waiting); */
90: return accept(s_waiting, NULL, NULL);
91: }
1.1 ohara 92:
1.5 ohara 93: int mysocketListen(char *hostname, int *port)
94: {
95: int option = 1;
96: ox_sockopt opt = {SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)};
97: int s_waiting = ox_listen(hostname, port, 1, &opt);
1.1 ohara 98:
1.5 ohara 99: if (*port == 0) {
100: *port = ox_getport(s_waiting);
101: }
1.1 ohara 102: return s_waiting;
103: }
104:
1.5 ohara 105: int mysocketOpen(char* hostname, int port)
1.1 ohara 106: {
1.5 ohara 107: return ox_connect(hostname, port, NULL);
1.1 ohara 108: }
109:
110: #if 0
111: int mypipe(char *program, int fd1, int fd2)
112: {
113: int sockfd[2];
114: if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) {
115: fprintf(stderr, "socketpair: fail! errno = %d\n", errno);
116: }
117: if (fork() == 0) {
1.2 ohara 118: /* child process */
1.1 ohara 119: close(sockfd[0]);
120: dup2(sockfd[1], fd1);
121: dup2(sockfd[1], fd2);
122: execl(program, program, NULL);
123: }
1.2 ohara 124: /* parent process */
1.1 ohara 125: close(sockfd[1]);
126: return sockfd[0];
127: }
128: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>