ia64/xen-unstable

view tools/vnet/vnetd/connection.c @ 6946:e703abaf6e3d

Add behaviour to the remove methods to remove the transaction's path itself. This allows us to write Remove(path) to remove the specified path rather than having to slice the path ourselves.
author emellor@ewan
date Sun Sep 18 14:42:13 2005 +0100 (2005-09-18)
parents 0a4b76b6b5a0
children 71b0f00f6344
line source
1 /*
2 * Copyright (C) 2003 - 2004 Mike Wray <mike.wray@hp.com>.
3 *
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1 of the
7 * License, or (at your option) any later version. This library is
8 * distributed in the hope that it will be useful, but WITHOUT ANY
9 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE.
11 * See the GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
25 #include "allocate.h"
26 #include "connection.h"
27 #include "file_stream.h"
28 #include "socket_stream.h"
30 #define DEBUG
31 #undef DEBUG
32 #define MODULE_NAME "conn"
33 #include "debug.h"
35 /** Initialize a file stream from a file desciptor.
36 *
37 * @param fd file descriptor
38 * @param mode file mode
39 * @param buffered make the stream buffered if 1, unbuffered if 0
40 * @param io return parameter for the stream
41 * @return 0 on success, error code otherwise
42 */
43 static int stream_init(int fd, const char *mode, int buffered, IOStream **io){
44 int err = 0;
45 *io = file_stream_fdopen(fd, mode);
46 if(!*io){
47 err = -errno;
48 perror("fdopen");
49 goto exit;
50 }
51 if(!buffered){
52 // Make unbuffered.
53 err = file_stream_setvbuf(*io, NULL, _IONBF, 0);
54 if(err){
55 err = -errno;
56 perror("setvbuf");
57 goto exit;
58 }
59 }
60 exit:
61 if(err && *io){
62 IOStream_close(*io);
63 *io = NULL;
64 }
65 return err;
66 }
68 ConnList * ConnList_add(Conn *conn, ConnList *l){
69 ConnList *v;
70 v = ALLOCATE(ConnList);
71 v->conn = conn;
72 v->next =l;
73 return v;
74 }
76 Conn *Conn_new(int (*fn)(Conn *), void *data){
77 Conn *conn;
78 conn = ALLOCATE(Conn);
79 conn->fn = fn;
80 conn->data = data;
81 return conn;
82 }
84 int Conn_handle(Conn *conn){
85 int err = 0;
86 dprintf(">\n");
87 if(conn->fn){
88 err = conn->fn(conn);
89 } else {
90 dprintf("> no handler\n");
91 err = -ENOSYS;
92 }
93 if(err < 0){
94 Conn_close(conn);
95 }
96 dprintf("< err=%d\n", err);
97 return err;
98 }
100 /** Initialize a connection.
101 *
102 * @param conn connection
103 * @param sock socket
104 * @param ipaddr ip address
105 * @return 0 on success, error code otherwise
106 */
107 int Conn_init(Conn *conn, int sock, int type, struct sockaddr_in addr){
108 int err = 0;
109 conn->addr = addr;
110 conn->type = type;
111 conn->sock = sock;
112 if(type == SOCK_STREAM){
113 err = stream_init(sock, "r", 0, &conn->in);
114 if(err) goto exit;
115 err = stream_init(sock, "w", 0, &conn->out);
116 if(err) goto exit;
117 } else {
118 conn->in = socket_stream_new(sock);
119 conn->out = socket_stream_new(sock);
120 socket_stream_set_addr(conn->out, &addr);
121 }
122 exit:
123 if(err) eprintf("< err=%d\n", err);
124 return err;
125 }
127 /** Open a connection.
128 *
129 * @param conn connection
130 * @param socktype socket type
131 * @param ipaddr ip address to connect to
132 * @param port port
133 * @return 0 on success, error code otherwise
134 */
135 int Conn_connect(Conn *conn, int socktype, struct in_addr ipaddr, uint16_t port){
136 int err = 0;
137 int sock;
138 struct sockaddr_in addr_in;
139 struct sockaddr *addr = (struct sockaddr *)&addr_in;
140 socklen_t addr_n = sizeof(addr_in);
141 dprintf("> addr=%s:%d\n", inet_ntoa(ipaddr), ntohs(port));
142 sock = socket(AF_INET, socktype, 0);
143 if(sock < 0){
144 err = -errno;
145 goto exit;
146 }
147 addr_in.sin_family = AF_INET;
148 addr_in.sin_addr = ipaddr;
149 addr_in.sin_port = port;
150 err = connect(sock, addr, addr_n);
151 if(err) goto exit;
152 err = Conn_init(conn, sock, socktype, addr_in);
153 exit:
154 if(err) eprintf("< err=%d\n", err);
155 return err;
156 }
158 /** Close a connection.
159 *
160 * @param conn connection
161 */
162 void Conn_close(Conn *conn){
163 if(!conn) return;
164 if(conn->in) IOStream_close(conn->in);
165 if(conn->out) IOStream_close(conn->out);
166 shutdown(conn->sock, 2);
167 }