debuggers.hg

view extras/mini-os/lib/xs.c @ 20669:63ff27b3b07a

mini-os: Fix memory leaks in xs_read() and xs_write()

xenbus_read() and xenbus_write() will allocate memory for error
message if any error occurs, this memory should be freed.

Signed-off-by: Yu Zhiguo <yuzg@cn.fujitsu.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Dec 11 09:01:15 2009 +0000 (2009-12-11)
parents a905c582a406
children
line source
1 /*
2 * libxs-compatible layer
3 *
4 * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 2007-2008
5 *
6 * Mere wrapper around xenbus_*
7 */
9 #ifdef HAVE_LIBC
10 #include <os.h>
11 #include <lib.h>
12 #include <xs.h>
13 #include <xenbus.h>
14 #include <stdlib.h>
15 #include <unistd.h>
17 static inline int _xs_fileno(struct xs_handle *h) {
18 return (intptr_t) h;
19 }
21 struct xs_handle *xs_daemon_open()
22 {
23 int fd = alloc_fd(FTYPE_XENBUS);
24 files[fd].xenbus.events = NULL;
25 printk("xs_daemon_open -> %d, %p\n", fd, &files[fd].xenbus.events);
26 return (void*)(intptr_t) fd;
27 }
29 void xs_daemon_close(struct xs_handle *h)
30 {
31 int fd = _xs_fileno(h);
32 struct xenbus_event *event;
33 for (event = files[fd].xenbus.events; event; event = event->next)
34 free(event);
35 files[fd].type = FTYPE_NONE;
36 }
38 int xs_fileno(struct xs_handle *h)
39 {
40 return _xs_fileno(h);
41 }
43 void *xs_read(struct xs_handle *h, xs_transaction_t t,
44 const char *path, unsigned int *len)
45 {
46 char *value;
47 char *msg;
49 msg = xenbus_read(t, path, &value);
50 if (msg) {
51 printk("xs_read(%s): %s\n", path, msg);
52 free(msg);
53 return NULL;
54 }
56 if (len)
57 *len = strlen(value);
58 return value;
59 }
61 bool xs_write(struct xs_handle *h, xs_transaction_t t,
62 const char *path, const void *data, unsigned int len)
63 {
64 char value[len + 1];
65 char *msg;
67 memcpy(value, data, len);
68 value[len] = 0;
70 msg = xenbus_write(t, path, value);
71 if (msg) {
72 printk("xs_write(%s): %s\n", path, msg);
73 free(msg);
74 return false;
75 }
76 return true;
77 }
79 static bool xs_bool(char *reply)
80 {
81 if (!reply)
82 return true;
83 free(reply);
84 return false;
85 }
87 bool xs_rm(struct xs_handle *h, xs_transaction_t t, const char *path)
88 {
89 return xs_bool(xenbus_rm(t, path));
90 }
92 static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
93 enum xsd_sockmsg_type type,
94 struct write_req *iovec,
95 unsigned int num_vecs,
96 unsigned int *len)
97 {
98 struct xsd_sockmsg *msg;
99 void *ret;
101 msg = xenbus_msg_reply(type, t, iovec, num_vecs);
102 ret = malloc(msg->len);
103 memcpy(ret, (char*) msg + sizeof(*msg), msg->len);
104 if (len)
105 *len = msg->len - 1;
106 free(msg);
107 return ret;
108 }
110 static void *xs_single(struct xs_handle *h, xs_transaction_t t,
111 enum xsd_sockmsg_type type,
112 const char *string,
113 unsigned int *len)
114 {
115 struct write_req iovec;
117 iovec.data = (void *)string;
118 iovec.len = strlen(string) + 1;
120 return xs_talkv(h, t, type, &iovec, 1, len);
121 }
123 char *xs_get_domain_path(struct xs_handle *h, unsigned int domid)
124 {
125 char domid_str[MAX_STRLEN(domid)];
127 sprintf(domid_str, "%u", domid);
129 return xs_single(h, XBT_NULL, XS_GET_DOMAIN_PATH, domid_str, NULL);
130 }
132 char **xs_directory(struct xs_handle *h, xs_transaction_t t,
133 const char *path, unsigned int *num)
134 {
135 char *msg;
136 char **entries, **res;
137 char *entry;
138 int i, n;
139 int size;
141 msg = xenbus_ls(t, path, &res);
142 if (msg) {
143 printk("xs_directory(%s): %s\n", path, msg);
144 return NULL;
145 }
147 size = 0;
148 for (n = 0; res[n]; n++)
149 size += strlen(res[n]) + 1;
151 entries = malloc(n * sizeof(char *) + size);
152 entry = (char *) (&entries[n]);
154 for (i = 0; i < n; i++) {
155 int l = strlen(res[i]) + 1;
156 memcpy(entry, res[i], l);
157 free(res[i]);
158 entries[i] = entry;
159 entry += l;
160 }
162 *num = n;
163 return entries;
164 }
166 bool xs_watch(struct xs_handle *h, const char *path, const char *token)
167 {
168 int fd = _xs_fileno(h);
169 printk("xs_watch(%s, %s)\n", path, token);
170 return xs_bool(xenbus_watch_path_token(XBT_NULL, path, token, &files[fd].xenbus.events));
171 }
173 char **xs_read_watch(struct xs_handle *h, unsigned int *num)
174 {
175 int fd = _xs_fileno(h);
176 struct xenbus_event *event;
177 event = files[fd].xenbus.events;
178 files[fd].xenbus.events = event->next;
179 printk("xs_read_watch() -> %s %s\n", event->path, event->token);
180 *num = 2;
181 return (char **) &event->path;
182 }
184 bool xs_unwatch(struct xs_handle *h, const char *path, const char *token)
185 {
186 printk("xs_unwatch(%s, %s)\n", path, token);
187 return xs_bool(xenbus_unwatch_path_token(XBT_NULL, path, token));
188 }
189 #endif