]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/parse.c
api_create and api_start: work toward making them thread-safe
[mirror_lxc.git] / src / lxc / parse.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23 #define _GNU_SOURCE
24 #include <stdio.h>
25 #undef _GNU_SOURCE
26 #include <string.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <dirent.h>
30
31 #include "parse.h"
32 #include "config.h"
33 #include "utils.h"
34 #include "lxclock.h"
35 #include <lxc/log.h>
36
37 /* Workaround for the broken signature of alphasort() in bionic.
38 This was fixed upstream in 40e467ec668b59be25491bd44bf348a884d6a68d so the
39 workaround can probably be dropped with the next version of the Android NDK.
40 */
41 #ifdef IS_BIONIC
42 int bionic_alphasort(const struct dirent** a, const struct dirent** b) {
43 return strcoll((*a)->d_name, (*b)->d_name);
44 }
45 #endif
46
47
48 lxc_log_define(lxc_parse, lxc);
49
50 static int dir_filter(const struct dirent *dirent)
51 {
52 if (!strcmp(dirent->d_name, ".") ||
53 !strcmp(dirent->d_name, ".."))
54 return 0;
55 return 1;
56 }
57
58 int lxc_dir_for_each(const char *name, const char *directory,
59 lxc_dir_cb callback, void *data)
60 {
61 struct dirent **namelist;
62 int n, ret = 0;
63
64 #ifdef IS_BIONIC
65 n = scandir(directory, &namelist, dir_filter, bionic_alphasort);
66 #else
67 n = scandir(directory, &namelist, dir_filter, alphasort);
68 #endif
69 if (n < 0) {
70 SYSERROR("failed to scan %s directory", directory);
71 return -1;
72 }
73
74 while (n--) {
75 if (!ret &&
76 callback(name, directory, namelist[n]->d_name, data)) {
77 ERROR("callback failed");
78 ret = -1;
79 }
80 free(namelist[n]);
81 }
82 free(namelist);
83
84 return ret;
85 }
86
87 int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data)
88 {
89 FILE *f;
90 int err = 0;
91 char *line = NULL;
92 size_t len = 0;
93
94 process_lock();
95 f = fopen(file, "r");
96 process_unlock();
97 if (!f) {
98 SYSERROR("failed to open %s", file);
99 return -1;
100 }
101
102 while (getline(&line, &len, f) != -1) {
103 err = callback(line, data);
104 if (err)
105 break;
106 }
107
108 if (line)
109 free(line);
110 process_lock();
111 fclose(f);
112 process_unlock();
113 return err;
114 }
115
116 int lxc_char_left_gc(char *buffer, size_t len)
117 {
118 int i;
119 for (i = 0; i < len; i++) {
120 if (buffer[i] == ' ' ||
121 buffer[i] == '\t')
122 continue;
123 return i;
124 }
125 return 0;
126 }
127
128 int lxc_char_right_gc(char *buffer, size_t len)
129 {
130 int i;
131 for (i = len - 1; i >= 0; i--) {
132 if (buffer[i] == ' ' ||
133 buffer[i] == '\t' ||
134 buffer[i] == '\n' ||
135 buffer[i] == '\0')
136 continue;
137 return i + 1;
138 }
139 return 0;
140 }
141
142 int lxc_is_line_empty(char *line)
143 {
144 int i;
145 size_t len = strlen(line);
146
147 for (i = 0; i < len; i++)
148 if (line[i] != ' ' && line[i] != '\t' &&
149 line[i] != '\n' && line[i] != '\r' &&
150 line[i] != '\f' && line[i] != '\0')
151 return 0;
152 return 1;
153 }