2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
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.
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.
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
30 #include <sys/syscall.h>
31 #include <sys/types.h>
36 /* returns 1 on success, 0 if there were any failures */
37 extern int lxc_rmdir_onedev(char *path
);
38 extern void lxc_setup_fs(void);
39 extern int get_u16(unsigned short *val
, const char *arg
, int base
);
40 extern int mkdir_p(const char *dir
, mode_t mode
);
41 extern void remove_trailing_slashes(char *p
);
42 extern char *get_rundir(void);
44 extern const char *lxc_global_config_value(const char *option_name
);
46 /* Define getline() if missing from the C library */
49 #include <../include/getline.h>
53 /* Define setns() if missing from the C library */
55 static inline int setns(int fd
, int nstype
)
58 return syscall(__NR_setns
, fd
, nstype
);
59 #elif defined(__NR_set_ns)
60 return syscall(__NR_set_ns
, fd
, nstype
);
68 /* Define unshare() if missing from the C library */
70 static inline int unshare(int flags
)
73 return syscall(__NR_unshare
, flags
);
83 /* Define signalfd() if missing from the C library */
84 #ifdef HAVE_SYS_SIGNALFD_H
85 # include <sys/signalfd.h>
87 /* assume kernel headers are too old */
89 struct signalfd_siginfo
110 # ifndef __NR_signalfd4
111 /* assume kernel headers are too old */
113 # define __NR_signalfd4 327
115 # define __NR_signalfd4 289
117 # define __NR_signalfd4 313
119 # define __NR_signalfd4 322
121 # define __NR_signalfd4 355
125 # ifndef __NR_signalfd
126 /* assume kernel headers are too old */
128 # define __NR_signalfd 321
130 # define __NR_signalfd 282
132 # define __NR_signalfd 305
134 # define __NR_signalfd 316
136 # define __NR_signalfd 349
140 static inline int signalfd(int fd
, const sigset_t
*mask
, int flags
)
144 retval
= syscall (__NR_signalfd4
, fd
, mask
, _NSIG
/ 8, flags
);
145 if (errno
== ENOSYS
&& flags
== 0)
146 retval
= syscall (__NR_signalfd
, fd
, mask
, _NSIG
/ 8);
151 /* open a file with O_CLOEXEC */
152 FILE *fopen_cloexec(const char *path
, const char *mode
);
155 /* Struct to carry child pid from lxc_popen() to lxc_pclose().
156 * Not an opaque struct to allow direct access to the underlying FILE *
157 * (i.e., struct lxc_popen_FILE *file; fgets(buf, sizeof(buf), file->f))
158 * without additional wrappers.
160 struct lxc_popen_FILE
{
165 /* popen(command, "re") replacement that restores default signal mask
166 * via sigprocmask(2) (unblocks all signals) after fork(2) but prior to calling exec(3).
167 * In short, popen(command, "re") does pipe() + fork() + exec()
168 * while lxc_popen(command) does pipe() + fork() + sigprocmask() + exec().
169 * Returns pointer to struct lxc_popen_FILE, that should be freed with lxc_pclose().
170 * On error returns NULL.
172 extern struct lxc_popen_FILE
*lxc_popen(const char *command
);
174 /* pclose() replacement to be used on struct lxc_popen_FILE *,
175 * returned by lxc_popen().
176 * Waits for associated process to terminate, returns its exit status and
177 * frees resources, pointed to by struct lxc_popen_FILE *.
179 extern int lxc_pclose(struct lxc_popen_FILE
*fp
);
182 * BUILD_BUG_ON - break compile if a condition is true.
183 * @condition: the condition which the compiler should know is false.
185 * If you have some code which relies on certain constants being equal, or
186 * other compile-time-evaluated condition, you should use BUILD_BUG_ON to
187 * detect if someone changes it.
189 * The implementation uses gcc's reluctance to create a negative array, but
190 * gcc (as of 4.4) only emits that error for obvious cases (eg. not arguments
191 * to inline functions). So as a fallback we use the optimizer; if it can't
192 * prove the condition is false, it will cause a link error on the undefined
193 * "__build_bug_on_failed". This error message can be harder to track down
194 * though, hence the two different methods.
197 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
199 extern int __build_bug_on_failed
;
200 #define BUILD_BUG_ON(condition) \
202 ((void)sizeof(char[1 - 2*!!(condition)])); \
203 if (condition) __build_bug_on_failed = 1; \
208 * wait on a child we forked
210 extern int wait_for_pid(pid_t pid
);
211 extern int lxc_wait_for_pid_status(pid_t pid
);
213 /* send and receive buffers completely */
214 extern ssize_t
lxc_write_nointr(int fd
, const void* buf
, size_t count
);
215 extern ssize_t
lxc_read_nointr(int fd
, void* buf
, size_t count
);
216 extern ssize_t
lxc_read_nointr_expect(int fd
, void* buf
, size_t count
, const void* expected_buf
);
218 #define SHA_DIGEST_LENGTH 20
219 extern int sha1sum_file(char *fnam
, unsigned char *md_value
);
222 /* read and write whole files */
223 extern int lxc_write_to_file(const char *filename
, const void* buf
, size_t count
, bool add_newline
);
224 extern int lxc_read_from_file(const char *filename
, void* buf
, size_t count
);
226 /* convert variadic argument lists to arrays (for execl type argument lists) */
227 extern char** lxc_va_arg_list_to_argv(va_list ap
, size_t skip
, int do_strdup
);
228 extern const char** lxc_va_arg_list_to_argv_const(va_list ap
, size_t skip
);
230 /* Some simple string functions; if they return pointers, they are allocated buffers. */
231 extern char *lxc_string_replace(const char *needle
, const char *replacement
, const char *haystack
);
232 extern bool lxc_string_in_array(const char *needle
, const char **haystack
);
233 extern char *lxc_string_join(const char *sep
, const char **parts
, bool use_as_prefix
);
234 /* Normalize and split path: Leading and trailing / are removed, multiple
235 * / are compactified, .. and . are resolved (.. on the top level is considered
239 * foo/../bar -> { bar, NULL }
241 * ./bar/baz/.. -> { bar, NULL }
242 * foo//bar -> { foo, bar, NULL }
244 extern char **lxc_normalize_path(const char *path
);
245 extern char *lxc_append_paths(const char *first
, const char *second
);
246 /* Note: the following two functions use strtok(), so they will never
247 * consider an empty element, even if two delimiters are next to
250 extern bool lxc_string_in_list(const char *needle
, const char *haystack
, char sep
);
251 extern char **lxc_string_split(const char *string
, char sep
);
252 extern char **lxc_string_split_and_trim(const char *string
, char sep
);
254 /* some simple array manipulation utilities */
255 typedef void (*lxc_free_fn
)(void *);
256 typedef void *(*lxc_dup_fn
)(void *);
257 extern int lxc_grow_array(void ***array
, size_t* capacity
, size_t new_size
, size_t capacity_increment
);
258 extern void lxc_free_array(void **array
, lxc_free_fn element_free_fn
);
259 extern size_t lxc_array_len(void **array
);
261 extern void **lxc_append_null_to_array(void **array
, size_t count
);
262 //initialize rand with urandom
263 extern int randseed(bool);
265 inline static bool am_unpriv(void) {
266 return geteuid() != 0;
270 * parse /proc/self/uid_map to find what @orig maps to
272 extern uid_t
get_ns_uid(uid_t orig
);
274 extern bool dir_exists(const char *path
);
276 #define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL)
277 uint64_t fnv_64a_buf(void *buf
, size_t len
, uint64_t hval
);