ia64/xen-unstable

view tools/xenstore/xs_lib.c @ 7238:971e7c7411b3

Raise an exception if an error appears on the pipes to our children, and make
sure that the child's pipes are closed even under that exception. Move the
handling of POLLHUP to the end of the loop, so that we guarantee to read any
remaining data from the child if POLLHUP and POLLIN appear at the same time.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@ewan
date Thu Oct 06 10:13:11 2005 +0100 (2005-10-06)
parents ef9591d03fdd
children 93e27f7ca8a8 61b3b357d827
line source
1 /*
2 Common routines between Xen store user library and daemon.
3 Copyright (C) 2005 Rusty Russell IBM Corporation
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
20 #include "xs_lib.h"
21 #include <unistd.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <errno.h>
27 /* Common routines for the Xen store daemon and client library. */
29 static const char *xs_daemon_rootdir(void)
30 {
31 char *s = getenv("XENSTORED_ROOTDIR");
32 return (s ? s : "/var/lib/xenstored");
33 }
35 static const char *xs_daemon_rundir(void)
36 {
37 char *s = getenv("XENSTORED_RUNDIR");
38 return (s ? s : "/var/run/xenstored");
39 }
41 static const char *xs_daemon_path(void)
42 {
43 static char buf[PATH_MAX];
44 char *s = getenv("XENSTORED_PATH");
45 if (s)
46 return s;
47 if (snprintf(buf, PATH_MAX, "%s/socket",
48 xs_daemon_rundir()) >= PATH_MAX)
49 return NULL;
50 return buf;
51 }
53 const char *xs_daemon_tdb(void)
54 {
55 static char buf[PATH_MAX];
56 sprintf(buf, "%s/tdb", xs_daemon_rootdir());
57 return buf;
58 }
60 const char *xs_daemon_socket(void)
61 {
62 return xs_daemon_path();
63 }
65 const char *xs_daemon_socket_ro(void)
66 {
67 static char buf[PATH_MAX];
68 const char *s = xs_daemon_path();
69 if (s == NULL)
70 return NULL;
71 if (snprintf(buf, PATH_MAX, "%s_ro", s) >= PATH_MAX)
72 return NULL;
73 return buf;
74 }
76 const char *xs_domain_dev(void)
77 {
78 char *s = getenv("XENSTORED_PATH");
79 return (s ? s : "/proc/xen/xenbus");
80 }
82 /* Simple routines for writing to sockets, etc. */
83 bool xs_write_all(int fd, const void *data, unsigned int len)
84 {
85 while (len) {
86 int done;
88 done = write(fd, data, len);
89 if (done < 0 && errno == EINTR)
90 continue;
91 if (done <= 0)
92 return false;
93 data += done;
94 len -= done;
95 }
97 return true;
98 }
100 /* Convert strings to permissions. False if a problem. */
101 bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num,
102 const char *strings)
103 {
104 const char *p;
105 char *end;
106 unsigned int i;
108 for (p = strings, i = 0; i < num; i++) {
109 /* "r", "w", or "b" for both. */
110 switch (*p) {
111 case 'r':
112 perms[i].perms = XS_PERM_READ;
113 break;
114 case 'w':
115 perms[i].perms = XS_PERM_WRITE;
116 break;
117 case 'b':
118 perms[i].perms = XS_PERM_READ|XS_PERM_WRITE;
119 break;
120 case 'n':
121 perms[i].perms = XS_PERM_NONE;
122 break;
123 default:
124 errno = EINVAL;
125 return false;
126 }
127 p++;
128 perms[i].id = strtol(p, &end, 0);
129 if (*end || !*p) {
130 errno = EINVAL;
131 return false;
132 }
133 p = end + 1;
134 }
135 return true;
136 }
138 /* Convert permissions to a string (up to len MAX_STRLEN(domid_t)+1). */
139 bool xs_perm_to_string(const struct xs_permissions *perm, char *buffer)
140 {
141 switch (perm->perms) {
142 case XS_PERM_WRITE:
143 *buffer = 'w';
144 break;
145 case XS_PERM_READ:
146 *buffer = 'r';
147 break;
148 case XS_PERM_READ|XS_PERM_WRITE:
149 *buffer = 'b';
150 break;
151 case XS_PERM_NONE:
152 *buffer = 'n';
153 break;
154 default:
155 errno = EINVAL;
156 return false;
157 }
158 sprintf(buffer+1, "%i", (int)perm->id);
159 return true;
160 }
162 /* Given a string and a length, count how many strings (nul terms). */
163 unsigned int xs_count_strings(const char *strings, unsigned int len)
164 {
165 unsigned int num;
166 const char *p;
168 for (p = strings, num = 0; p < strings + len; p++)
169 if (*p == '\0')
170 num++;
172 return num;
173 }