]>
git.ipfire.org Git - thirdparty/kmod.git/blob - shared/util.c
0113967cbb1628afc85b72e070ca412f820c07ea
2 * kmod - interface to kernel module operations
4 * Copyright (C) 2011-2013 ProFUSION embedded systems
5 * Copyright (C) 2012 Lucas De Marchi <lucas.de.marchi@gmail.com>
6 * Copyright (C) 2013-2014 Intel Corporation. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <shared/util.h>
35 #define USEC_PER_SEC 1000000ULL
36 #define NSEC_PER_USEC 1000ULL
38 /* string handling functions and memory allocations */
39 /* ************************************************************************ */
41 void *memdup(const void *p
, size_t n
)
48 return memcpy(r
, p
, n
);
51 char *strchr_replace(char *s
, int c
, char r
)
55 for (p
= s
; *p
!= '\0'; p
++) {
63 /* read-like and fread-like functions */
64 /* ************************************************************************ */
65 ssize_t
read_str_safe(int fd
, char *buf
, size_t buflen
)
67 size_t todo
= buflen
- 1;
71 ssize_t r
= read(fd
, buf
+ done
, todo
);
79 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
91 ssize_t
write_str_safe(int fd
, const char *buf
, size_t buflen
)
97 ssize_t r
= write(fd
, buf
+ done
, todo
);
105 if (errno
== EAGAIN
|| errno
== EWOULDBLOCK
||
116 int read_str_long(int fd
, long *value
, int base
)
123 err
= read_str_safe(fd
, buf
, sizeof(buf
));
127 v
= strtol(buf
, &end
, base
);
128 if (end
== buf
|| !isspace(*end
))
135 int read_str_ulong(int fd
, unsigned long *value
, int base
)
142 err
= read_str_safe(fd
, buf
, sizeof(buf
));
146 v
= strtoul(buf
, &end
, base
);
147 if (end
== buf
|| !isspace(*end
))
154 * Read one logical line from a configuration file.
156 * Line endings may be escaped with backslashes, to form one logical line from
157 * several physical lines. No end of line character(s) are included in the
160 * If linenum is not NULL, it is incremented by the number of physical lines
161 * which have been read.
163 char *getline_wrapped(FILE *fp
, unsigned int *linenum
)
167 _cleanup_free_
char *buf
= malloc(size
);
173 int ch
= getc_unlocked(fp
);
179 /* else fall through */
187 ret
= realloc(buf
, size
+ 1);
200 ch
= getc_unlocked(fp
);
206 /* else fall through */
214 tmp
= realloc(buf
, size
);
223 /* path handling functions */
224 /* ************************************************************************ */
226 bool path_is_absolute(const char *p
)
233 char *path_make_absolute_cwd(const char *p
)
235 _cleanup_free_
char *cwd
= NULL
;
239 if (path_is_absolute(p
))
242 cwd
= get_current_dir_name();
247 cwdlen
= strlen(cwd
);
249 /* cwd + '/' + p + '\0' */
250 r
= realloc(cwd
, cwdlen
+ 1 + plen
+ 1);
256 memcpy(&r
[cwdlen
+ 1], p
, plen
+ 1);
261 static inline int is_dir(const char *path
)
265 if (stat(path
, &st
) >= 0)
266 return S_ISDIR(st
.st_mode
);
271 int mkdir_p(const char *path
, int len
, mode_t mode
)
275 start
= strndupa(path
, len
);
279 * scan backwards, replacing '/' with '\0' while the component doesn't
283 int r
= is_dir(start
);
287 if (end
== start
+ len
)
290 /* end != start, since it would be caught on the first
302 /* Find the next component, backwards, discarding extra '/'*/
303 while (end
> start
&& *end
!= '/')
306 while (end
> start
&& *(end
- 1) == '/')
310 for (; end
< start
+ len
;) {
311 if (mkdir(start
, mode
) < 0 && errno
!= EEXIST
)
321 int mkdir_parents(const char *path
, mode_t mode
)
323 char *end
= strrchr(path
, '/');
325 /* no parent directories */
329 return mkdir_p(path
, end
- path
, mode
);
332 unsigned long long ts_usec(const struct timespec
*ts
)
334 return (unsigned long long) ts
->tv_sec
* USEC_PER_SEC
+
335 (unsigned long long) ts
->tv_nsec
/ NSEC_PER_USEC
;
338 unsigned long long stat_mstamp(const struct stat
*st
)
340 #ifdef HAVE_STRUCT_STAT_ST_MTIM
341 return ts_usec(&st
->st_mtim
);
343 return (unsigned long long) st
->st_mtime
;