Free a buffer on an error path
[pytipc.git] / tipc.py
blob425141a44bdb20a45a145c7d995c01edfc4cd1e7
2 """
3 TIPC python wrapper
4 Alberto Bertogli (albertito@gmail.com)
7 Addresses are expressed as (addr_type, v1, v2, v3 [, scope]);
8 where addr_type can be one of:
9 TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, and TIPC_ADDR_ID;
10 and scope can be one of:
11 TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, and TIPC_NODE_SCOPE.
14 The meaning of v1, v2 and v3 depend on the value of addr_type:
16 if addr_type is TIPC_ADDR_NAME:
17 v1 is the server type
18 v2 is the port identifier
19 v3 is ignored
20 if addr_type is TIPC_ADDR_NAMESEQ:
21 v1 is the server type
22 v2 is the lower port number
23 v3 is the upper port number
24 if addr_type is TIPC_ADDR_ID:
25 v1 is the node
26 v2 is the ref
27 v3 is ignored
29 Even when ignored, v3 must be present and be an integer.
30 """
32 import os
33 import socket as socketmodule
34 import tipc_ll
36 # Exported constants
37 from tipc_ll import AF_TIPC, SOL_TIPC, \
38 TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME, TIPC_ADDR_ID, \
39 TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE, TIPC_NODE_SCOPE, \
40 TIPC_IMPORTANCE, \
41 TIPC_SRC_DROPPABLE, TIPC_DEST_DROPPABLE, \
42 TIPC_CONN_TIMEOUT, \
43 TIPC_LOW_IMPORTANCE, TIPC_MEDIUM_IMPORTANCE, \
44 TIPC_HIGH_IMPORTANCE, TIPC_CRITICAL_IMPORTANCE, \
45 TIPC_SUB_PORTS, TIPC_SUB_SERVICE, TIPC_SUB_CANCEL, \
46 TIPC_WAIT_FOREVER, \
47 TIPC_PUBLISHED, TIPC_WITHDRAWN, TIPC_SUBSCR_TIMEOUT, \
48 TIPC_CFG_SRV, TIPC_TOP_SRV
51 class TIPCSocket:
52 def __init__(self, stype, fd = None):
53 if not fd:
54 self.fd = tipc_ll.socket(stype)
55 else:
56 self.fd = fd
58 self.closed = 0
59 self.psock = socketmodule.fromfd(self.fd, AF_TIPC, stype)
61 self.family = AF_TIPC
62 self.type = stype
63 self.proto = 0
65 def __del__(self):
66 self.close()
69 # Friendly functions for the ones implemented in tipc_ll
71 def connect(self, addr):
72 "Connects to the given server."
73 return tipc_ll.connect(self.fd, addr)
75 def bind(self, addr):
76 "Binds to the given address."
77 return tipc_ll.bind(self.fd, addr)
79 def accept(self):
80 "Accepts a new connection, returns (conn, addr)."
81 newfd, addr = tipc_ll.accept(self.fd)
82 return (TIPCSocket(self.type, fd = newfd), addr)
84 def sendto(self, buf, addr):
85 "Sends a message/buffer to the given address."
86 return tipc_ll.sendto(self.fd, buf, addr)
88 def recvfrom(self, maxlen = 64 * 1024):
89 "Receives a message/buffer, returns (buffer, address)."
90 return tipc_ll.recvfrom(self.fd, maxlen)
92 def close(self):
93 "Closes the socket."
94 if not self.closed:
95 self.closed = 1
96 return os.close(self.fd)
99 # Other useful functions, some of them based on socketmodule
101 def fileno(self):
102 "Returns the file descriptor number."
103 return self.fd
105 def send(self, buf):
106 "Sends a message/buffer."
107 self.psock.send(buf)
109 def recv(self, bufsize):
110 "Receives a message/buffer."
111 b, a = self.recvfrom(bufsize)
112 return b
114 def listen(self, backlog):
115 "Listen for connections made to the socket."
116 return self.psock.listen(backlog)
118 def setblocking(self, flag):
119 "Set blocking or non-blocking mode for the socket."
120 return self.psock.setblocking(flag)
122 def getsockopt(self, level, optname, buflen = None):
123 """Return the value of the given socket option (see the Unix
124 man page getsockopt(2))."""
125 if not buflen:
126 return self.psock.getsockopt(level, optname)
127 return self.psock.getsockopt(level, optname, buflen)
129 def setsockopt(self, level, optname, value):
130 """Set the value of the given socket option (see the Unix
131 manual page setsockopt(2))"""
132 return self.psock.setsockopt(level, optname, value)
134 def shutdown(self, how):
135 "Shut down one or both halves of the connection."
136 return self.psock.shutdown(how)
139 # Subscription handling
141 def send_subscr(self, addr, timeout = None, filter = TIPC_SUB_SERVICE):
143 Sends a subscription message to the server (the socket must
144 be connected to TIPC_ADDR_NAME, TIPC_TOP_SRV, TIPC_TOP_SRV, 0)
145 for this to work).
146 - addr: specifies the address to wait for (can be a name or a
147 nameseq).
148 - timeout: timeout in milliseconds (use None to wait
149 forever), defaults to None.
150 - filter: Either TIPC_SUB_SERVICE or TIPC_SUB_PORTS, see TIPC
151 documentation for details. Defaults to TIPC_SUB_SERVICE.
154 if not timeout:
155 timeout = TIPC_WAIT_FOREVER
157 atype, stype, lower, upper = addr[:4]
159 if atype == TIPC_ADDR_NAME:
160 upper = lower
162 subs = tipc_ll.build_subscr(stype, lower, upper,
163 timeout, filter)
164 self.send(subs)
166 def recv_subscr_event(self):
168 Receives a subscription event from the socket.
170 It returns None if there was an error receiving the
171 subscription, or the tuple:
172 ( event, found_lower, found_upper,
173 (srv_type, lower, upper, timeout, filter) )
175 - event: one of TIPC_SUBSCR_TIMEOUT, TIPC_PUBLISHED or
176 TIPC_WITHDRAWN.
177 - found_lower, found_upper: the lower and upper ports found.
178 - (srv_type, lower, upper, timeout, filter): information on
179 the subscription that generated the event (see send_subscr()
180 for details).
182 buf = self.recv(4092)
183 return tipc_ll.parse_event(buf)
186 def socket(stype):
188 Creates and returns a socket object of the given type.
190 The type can be one of SOCK_RDM, SOCK_SEQPACKET, SOCK_STREAM and
191 SOCK_DGRAM, see TIPC documentation for more information.
193 return TIPCSocket(stype)
196 def wait_for(addr, timeout = None, filter = None):
198 Waits for a server to appear on the given address.
200 If a timeout is specified and no server came up after that number of
201 milliseconds, returns None.
202 The optional filter parameter can be either TIPC_SUB_SERVICE or
203 TIPC_SUB_PORTS, see TIPC documentation for more details; it defaults
204 to TIPC_SUB_SERVICE.
206 If there are any errors, return None; otherwise return an event tuple
207 composed of:
208 ( event, found_lower, found_upper,
209 (srv_type, lower, upper, timeout, filter) )
211 - event: one of TIPC_SUBSCR_TIMEOUT, TIPC_PUBLISHED or
212 TIPC_WITHDRAWN.
213 - found_lower, found_upper: the lower and upper ports found.
214 - (srv_type, lower, upper, timeout, filter): information on
215 the subscription that generated the event (see send_subscr()
216 for details).
219 fd = socket(socketmodule.SOCK_SEQPACKET)
221 if not timeout:
222 timeout = TIPC_WAIT_FOREVER
223 if not filter:
224 filter = TIPC_SUB_SERVICE
226 topsrv_addr = (TIPC_ADDR_NAME, TIPC_TOP_SRV,
227 TIPC_TOP_SRV, TIPC_TOP_SRV)
228 fd.connect(topsrv_addr)
230 fd.send_subscr(addr, timeout, filter)
231 return fd.recv_subscr_event()