ia64/xen-unstable

view tools/xenstore/xenstore_client.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 f1e8d5f64105
line source
1 /*
2 * This file is subject to the terms and conditions of the GNU General
3 * Public License. See the file "COPYING" in the main directory of
4 * this archive for more details.
5 *
6 * Copyright (C) 2005 by Christian Limpach
7 *
8 */
10 #include <err.h>
11 #include <fcntl.h>
12 #include <getopt.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <xs.h>
17 #include <errno.h>
19 static void
20 usage(const char *progname)
21 {
22 #if defined(CLIENT_read)
23 errx(1, "Usage: %s [-h] [-p] key [...]", progname);
24 #elif defined(CLIENT_write)
25 errx(1, "Usage: %s [-h] key value [...]", progname);
26 #elif defined(CLIENT_rm) || defined(CLIENT_exists) || defined(CLIENT_list)
27 errx(1, "Usage: %s [-h] key [...]", progname);
28 #endif
29 }
31 int
32 main(int argc, char **argv)
33 {
34 struct xs_handle *xsh;
35 bool success;
36 int ret = 0;
37 #if defined(CLIENT_read) || defined(CLIENT_list)
38 int prefix = 0;
39 #endif
41 xsh = xs_domain_open();
42 if (xsh == NULL)
43 err(1, "xs_domain_open");
45 while (1) {
46 int c, index = 0;
47 static struct option long_options[] = {
48 {"help", 0, 0, 'h'},
49 #if defined(CLIENT_read) || defined(CLIENT_list)
50 {"prefix", 0, 0, 'p'},
51 #endif
52 {0, 0, 0, 0}
53 };
55 c = getopt_long(argc, argv, "h"
56 #if defined(CLIENT_read) || defined(CLIENT_list)
57 "p"
58 #endif
59 , long_options, &index);
60 if (c == -1)
61 break;
63 switch (c) {
64 case 'h':
65 usage(argv[0]);
66 /* NOTREACHED */
67 #if defined(CLIENT_read) || defined(CLIENT_list)
68 case 'p':
69 prefix = 1;
70 break;
71 #endif
72 }
73 }
75 if (optind == argc) {
76 usage(argv[0]);
77 /* NOTREACHED */
78 }
79 #if defined(CLIENT_write)
80 if ((argc - optind) % 2 == 1) {
81 usage(argv[0]);
82 /* NOTREACHED */
83 }
84 #endif
86 again:
87 success = xs_transaction_start(xsh);
88 if (!success)
89 errx(1, "couldn't start transaction");
91 while (optind < argc) {
92 #if defined(CLIENT_read)
93 char *val = xs_read(xsh, argv[optind], NULL);
94 if (val == NULL) {
95 warnx("couldn't read path %s", argv[optind]);
96 ret = 1;
97 goto out;
98 }
99 if (prefix)
100 printf("%s: ", argv[optind]);
101 printf("%s\n", val);
102 free(val);
103 optind++;
104 #elif defined(CLIENT_write)
105 success = xs_write(xsh, argv[optind], argv[optind + 1],
106 strlen(argv[optind + 1]));
107 if (!success) {
108 warnx("could not write path %s", argv[optind]);
109 ret = 1;
110 goto out;
111 }
112 optind += 2;
113 #elif defined(CLIENT_rm)
114 success = xs_rm(xsh, argv[optind]);
115 if (!success) {
116 warnx("could not remove path %s", argv[optind]);
117 ret = 1;
118 goto out;
119 }
120 optind++;
121 #elif defined(CLIENT_exists)
122 char *val = xs_read(xsh, argv[optind], NULL);
123 if (val == NULL) {
124 ret = 1;
125 goto out;
126 }
127 free(val);
128 optind++;
129 #elif defined(CLIENT_list)
130 unsigned int i, num;
131 char **list = xs_directory(xsh, argv[optind], &num);
132 if (list == NULL) {
133 warnx("could not list path %s", argv[optind]);
134 ret = 1;
135 goto out;
136 }
137 for (i = 0; i < num; i++) {
138 if (prefix)
139 printf("%s/", argv[optind]);
140 printf("%s\n", list[i]);
141 }
142 free(list);
143 optind++;
144 #endif
145 }
147 out:
148 success = xs_transaction_end(xsh, ret ? true : false);
149 if (!success) {
150 if (ret == 0 && errno == EAGAIN)
151 goto again;
152 errx(1, "couldn't end transaction");
153 }
154 return ret;
155 }