Annotation of OpenXM/src/ox_toolkit/mysocket.c, Revision 1.7
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.7 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/mysocket.c,v 1.6 2000/12/01 16:31:11 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"
1.7 ! ohara 30: #include "ox_toolkit.h"
1.1 ohara 31:
1.5 ohara 32: typedef struct ox_sockopt {
33: int level;
34: int option_name;
35: void* option_value;
1.6 ohara 36: int option_len;
1.5 ohara 37: } ox_sockopt;
38:
39: static int getsocket(struct sockaddr_in *mp, char *host, int port)
1.1 ohara 40: {
41: struct hostent *ent = gethostbyname(host);
1.5 ohara 42:
1.1 ohara 43: memset(mp, '\0', sizeof(struct sockaddr_in));
44: mp->sin_family = AF_INET;
1.5 ohara 45: mp->sin_port = htons((short)port);
1.1 ohara 46: memcpy((char *)&mp->sin_addr, ent->h_addr, ent->h_length);
47:
48: return socket(AF_INET, SOCK_STREAM, 0);
49: }
50:
1.5 ohara 51: static int ox_connect(char *hostname, int port, ox_sockopt *opt)
1.1 ohara 52: {
1.5 ohara 53: struct sockaddr_in serv;
54: int s = getsocket(&serv, hostname, port);
55: if (connect(s, (struct sockaddr *)&serv, sizeof(serv)) != 0) {
1.7 ! ohara 56: fprintf(ox_stderr, "ox_connect: failed. socket = %d, errno = %d\n", s, errno);
1.5 ohara 57: return -1;
58: }
59: return s;
1.1 ohara 60: }
61:
1.5 ohara 62: static int ox_listen(char *hostname, int *port, int backlog, ox_sockopt *opt)
1.1 ohara 63: {
64: struct sockaddr_in me;
1.5 ohara 65: int s_waiting = getsocket(&me, hostname, *port);
1.1 ohara 66:
1.5 ohara 67: setsockopt(s_waiting, opt->level, opt->option_name,
68: opt->option_value, opt->option_len);
69: if (bind(s_waiting, (struct sockaddr *)&me, sizeof(me)) < 0
70: || listen(s_waiting, backlog) < 0) {
1.7 ! ohara 71: fprintf(ox_stderr, "ox_listen: failed.\n");
1.5 ohara 72: return -1;
73: }
74: return s_waiting;
75: }
1.1 ohara 76:
1.5 ohara 77: static int ox_getport(int s_waiting)
78: {
79: struct sockaddr_in me;
80: int len = sizeof(me);
81: if (getsockname(s_waiting, (struct sockaddr *)&me, &len) < 0) {
1.7 ! ohara 82: fprintf(ox_stderr, "ox_getport: failed.\n");
1.5 ohara 83: return -1;
1.1 ohara 84: }
1.5 ohara 85: return ntohs(me.sin_port);
86: }
1.1 ohara 87:
1.5 ohara 88: int mysocketAccept(int s_waiting)
89: {
90: /* return ox_accept(s_waiting); */
91: return accept(s_waiting, NULL, NULL);
92: }
1.1 ohara 93:
1.5 ohara 94: int mysocketListen(char *hostname, int *port)
95: {
96: int option = 1;
97: ox_sockopt opt = {SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)};
98: int s_waiting = ox_listen(hostname, port, 1, &opt);
1.1 ohara 99:
1.5 ohara 100: if (*port == 0) {
101: *port = ox_getport(s_waiting);
102: }
1.1 ohara 103: return s_waiting;
104: }
105:
1.5 ohara 106: int mysocketOpen(char* hostname, int port)
1.1 ohara 107: {
1.5 ohara 108: return ox_connect(hostname, port, NULL);
1.1 ohara 109: }
110:
111: #if 0
112: int mypipe(char *program, int fd1, int fd2)
113: {
114: int sockfd[2];
115: if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) {
1.7 ! ohara 116: fprintf(ox_stderr, "socketpair: fail! errno = %d\n", errno);
1.1 ohara 117: }
118: if (fork() == 0) {
1.2 ohara 119: /* child process */
1.1 ohara 120: close(sockfd[0]);
121: dup2(sockfd[1], fd1);
122: dup2(sockfd[1], fd2);
123: execl(program, program, NULL);
124: }
1.2 ohara 125: /* parent process */
1.1 ohara 126: close(sockfd[1]);
127: return sockfd[0];
128: }
129: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>