]>
git.ipfire.org Git - thirdparty/dracut.git/blob - install/util.c
2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/types.h>
25 #include <sys/syscall.h>
29 static inline pid_t
gettid(void) {
30 return (pid_t
) syscall(SYS_gettid
);
33 size_t page_size(void) {
34 static __thread
size_t pgsz
= 0;
37 if (_likely_(pgsz
> 0))
40 assert_se((r
= sysconf(_SC_PAGESIZE
)) > 0);
47 bool endswith(const char *s
, const char *postfix
) {
62 return memcmp(s
+ sl
- pl
, postfix
, pl
) == 0;
64 int close_nointr(int fd
) {
79 void close_nointr_nofail(int fd
) {
80 int saved_errno
= errno
;
82 /* like close_nointr() but cannot fail, and guarantees errno
85 assert_se(close_nointr(fd
) == 0);
90 int open_terminal(const char *name
, int mode
) {
95 * If a TTY is in the process of being closed opening it might
96 * cause EIO. This is horribly awful, but unlikely to be
97 * changed in the kernel. Hence we work around this problem by
98 * retrying a couple of times.
100 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
104 if ((fd
= open(name
, mode
)) >= 0)
113 usleep(50 * USEC_PER_MSEC
);
120 if ((r
= isatty(fd
)) < 0) {
121 close_nointr_nofail(fd
);
126 close_nointr_nofail(fd
);
133 bool streq_ptr(const char *a
, const char *b
) {
135 /* Like streq(), but tries to make sense of NULL pointers */
145 bool is_main_thread(void) {
146 static __thread
int cached
= 0;
148 if (_unlikely_(cached
== 0))
149 cached
= getpid() == gettid() ? 1 : -1;
154 int safe_atou(const char *s
, unsigned *ret_u
) {
162 l
= strtoul(s
, &x
, 0);
164 if (!x
|| *x
|| errno
)
165 return errno
? -errno
: -EINVAL
;
167 if ((unsigned long) (unsigned) l
!= l
)
170 *ret_u
= (unsigned) l
;
174 static const char *const log_level_table
[] = {
175 [LOG_EMERG
] = "emerg",
176 [LOG_ALERT
] = "alert",
179 [LOG_WARNING
] = "warning",
180 [LOG_NOTICE
] = "notice",
182 [LOG_DEBUG
] = "debug"
185 DEFINE_STRING_TABLE_LOOKUP(log_level
, int);
187 char *strnappend(const char *s
, const char *suffix
, size_t b
) {
195 return strndup(suffix
, b
);
204 if (b
> ((size_t) -1) - a
)
207 r
= new(char, a
+b
+1);
212 memcpy(r
+a
, suffix
, b
);
218 char *strappend(const char *s
, const char *suffix
) {
219 return strnappend(s
, suffix
, suffix
? strlen(suffix
) : 0);
222 char *strjoin(const char *x
, ...) {
236 t
= va_arg(ap
, const char *);
241 if (n
> ((size_t) -1) - l
) {
267 t
= va_arg(ap
, const char *);
281 char *cunescape_length_with_prefix(const char *s
, size_t length
, const char *prefix
) {
288 /* Undoes C style string escaping, and optionally prefixes it. */
290 pl
= prefix
? strlen(prefix
) : 0;
292 r
= new(char, pl
+length
+1);
297 memcpy(r
, prefix
, pl
);
299 for (f
= s
, t
= r
+ pl
; f
< s
+ length
; f
++) {
342 /* This is an extension of the XDG syntax files */
347 /* hexadecimal encoding */
353 if (a
< 0 || b
< 0) {
354 /* Invalid escape code, let's take it literal then */
358 *(t
++) = (char) ((a
<< 4) | b
);
380 if (a
< 0 || b
< 0 || c
< 0) {
381 /* Invalid escape code, let's take it literal then */
385 *(t
++) = (char) ((a
<< 6) | (b
<< 3) | c
);
393 /* premature end of string.*/
398 /* Invalid escape code, let's take it literal then */
410 char *cunescape_length(const char *s
, size_t length
) {
411 return cunescape_length_with_prefix(s
, length
, NULL
);
415 /* Split a string into words, but consider strings enclosed in '' and
416 * "" as words even if they include spaces. */
417 char *split_quoted(const char *c
, size_t *l
, char **state
) {
418 const char *current
, *e
;
419 bool escaped
= false;
425 current
= *state
? *state
: c
;
427 current
+= strspn(current
, WHITESPACE
);
432 else if (*current
== '\'') {
435 for (e
= current
; *e
; e
++) {
445 *state
= (char*) (*e
== 0 ? e
: e
+1);
447 } else if (*current
== '\"') {
450 for (e
= current
; *e
; e
++) {
460 *state
= (char*) (*e
== 0 ? e
: e
+1);
463 for (e
= current
; *e
; e
++) {
468 else if (strchr(WHITESPACE
, *e
))
475 return (char*) current
;
478 /* Split a string into words. */
479 char *split(const char *c
, size_t *l
, const char *separator
, char **state
) {
482 current
= *state
? *state
: (char*) c
;
484 if (!*current
|| *c
== 0)
487 current
+= strspn(current
, separator
);
488 *l
= strcspn(current
, separator
);
491 return (char*) current
;
494 int unhexchar(char c
) {
496 if (c
>= '0' && c
<= '9')
499 if (c
>= 'a' && c
<= 'f')
502 if (c
>= 'A' && c
<= 'F')
508 int unoctchar(char c
) {
510 if (c
>= '0' && c
<= '7')