196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi/* 296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * kmod - interface to kernel module operations 396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * 496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * Copyright (C) 2011-2013 ProFUSION embedded systems 596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * Copyright (C) 2012 Lucas De Marchi <lucas.de.marchi@gmail.com> 696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. 796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * 896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * This library is free software; you can redistribute it and/or 996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * modify it under the terms of the GNU Lesser General Public 1096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * License as published by the Free Software Foundation; either 1196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * version 2.1 of the License, or (at your option) any later version. 1296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * 1396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * This library is distributed in the hope that it will be useful, 1496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * but WITHOUT ANY WARRANTY; without even the implied warranty of 1596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * Lesser General Public License for more details. 1796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * 1896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * You should have received a copy of the GNU Lesser General Public 19dea2dfee9b301da84dbb09cf510b8ebf2ef28fffLucas De Marchi * License along with this library; if not, see <http://www.gnu.org/licenses/>. 2096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi */ 2196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 2296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#include <assert.h> 23c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <ctype.h> 24c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <errno.h> 25c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <stdarg.h> 26c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <stddef.h> 2796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#include <stdio.h> 2896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#include <stdlib.h> 2996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#include <string.h> 30c2e4286bb98c6bec77575ac0c6f862e7ddf6394fLucas De Marchi#include <unistd.h> 3196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 32efb5bfaca938fa5991865c1e9a0c730dc919708cNatanael Copa#include <shared/missing.h> 3396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#include <shared/util.h> 3496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 3596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#define USEC_PER_SEC 1000000ULL 3696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#define NSEC_PER_USEC 1000ULL 3796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 38f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchistatic const struct kmod_ext { 39f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi const char *ext; 40f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi size_t len; 41f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi} kmod_exts[] = { 42f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi {KMOD_EXTENSION_UNCOMPRESSED, sizeof(KMOD_EXTENSION_UNCOMPRESSED) - 1}, 43f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi#ifdef ENABLE_ZLIB 44f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi {".ko.gz", sizeof(".ko.gz") - 1}, 45f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi#endif 46f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi#ifdef ENABLE_XZ 47f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi {".ko.xz", sizeof(".ko.xz") - 1}, 48f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi#endif 49f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi { } 50f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi}; 51f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 52a6ede6c7ad46b5e2b8eddddca5590c0b745b045aLucas De Marchiassert_cc(EAGAIN == EWOULDBLOCK); 53a6ede6c7ad46b5e2b8eddddca5590c0b745b045aLucas De Marchi 5496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi/* string handling functions and memory allocations */ 5596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi/* ************************************************************************ */ 5696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 5796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchivoid *memdup(const void *p, size_t n) 5896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 5996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi void *r = malloc(n); 6096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 6196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (r == NULL) 6296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return NULL; 6396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 6496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return memcpy(r, p, n); 6596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 6696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 679a437531af61a59f5f0a96545288735f45ce6469Lucas De Marchichar *strchr_replace(char *s, char c, char r) 6896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 6996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi char *p; 7096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 7196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi for (p = s; *p != '\0'; p++) { 7296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (*p == c) 7396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi *p = r; 7496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 7596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 7696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return s; 7796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 7896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 792b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi/* module-related functions */ 802b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi/* ************************************************************************ */ 812b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchiint alias_normalize(const char *alias, char buf[static PATH_MAX], size_t *len) 822b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi{ 832b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi size_t i; 842b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi 852b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi for (i = 0; i < PATH_MAX - 1; i++) { 862b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi const char c = alias[i]; 872b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi switch (c) { 882b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi case '-': 892b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi buf[i] = '_'; 902b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi break; 912b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi case ']': 922b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi return -EINVAL; 932b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi case '[': 942b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi while (alias[i] != ']' && alias[i] != '\0') { 952b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi buf[i] = alias[i]; 962b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi i++; 972b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi } 982b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi 992b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi if (alias[i] != ']') 1002b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi return -EINVAL; 1012b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi 1022b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi buf[i] = alias[i]; 1032b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi break; 1042b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi case '\0': 1052b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi goto finish; 1062b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi default: 1072b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi buf[i] = c; 1082b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi } 1092b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi } 1102b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi 1112b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchifinish: 1122b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi buf[i] = '\0'; 1132b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi if (len) 1142b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi *len = i; 1152b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi 1162b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi return 0; 1172b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi} 1182b0104fe3c47a9746b6296ed5646cd39e2ae010dLucas De Marchi 11952c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi/* 12052c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi * Replace dashes with underscores. 12152c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi * Dashes inside character range patterns (e.g. [0-9]) are left unchanged. 12252c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi * 12352c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi * For convenience, it returns error if @s is NULL 12452c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi */ 12552c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchiint underscores(char *s) 12652c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi{ 12752c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi unsigned int i; 12852c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi 12952c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi if (!s) 13052c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi return -EINVAL; 13152c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi 13252c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi for (i = 0; s[i]; i++) { 13352c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi switch (s[i]) { 13452c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi case '-': 13552c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi s[i] = '_'; 13652c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi break; 13752c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi case ']': 13852c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi return -EINVAL; 13952c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi case '[': 14052c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi i += strcspn(&s[i], "]"); 14152c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi if (!s[i]) 14252c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi return -EINVAL; 14352c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi break; 14452c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi } 14552c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi } 14652c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi 14752c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi return 0; 14852c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi} 14952c9c9905683c781e611a5bf3c61fcdc22ab5429Lucas De Marchi 150f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchichar *modname_normalize(const char *modname, char buf[static PATH_MAX], size_t *len) 151f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi{ 152f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi size_t s; 153f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 154f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi for (s = 0; s < PATH_MAX - 1; s++) { 155f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi const char c = modname[s]; 156f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi if (c == '-') 157f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi buf[s] = '_'; 158f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi else if (c == '\0' || c == '.') 159f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi break; 160f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi else 161f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi buf[s] = c; 162f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi } 163f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 164f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi buf[s] = '\0'; 165f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 166f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi if (len) 167f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi *len = s; 168f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 169f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi return buf; 170f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi} 171f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 172f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchichar *path_to_modname(const char *path, char buf[static PATH_MAX], size_t *len) 173f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi{ 174f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi char *modname; 175f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 176f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi modname = basename(path); 177f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi if (modname == NULL || modname[0] == '\0') 178f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi return NULL; 179f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 180f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi return modname_normalize(modname, buf, len); 181f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi} 182f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 183f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchibool path_ends_with_kmod_ext(const char *path, size_t len) 184f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi{ 185f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi const struct kmod_ext *eitr; 186f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 187f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi for (eitr = kmod_exts; eitr->ext != NULL; eitr++) { 188f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi if (len <= eitr->len) 189f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi continue; 190f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi if (streq(path + len - eitr->len, eitr->ext)) 191f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi return true; 192f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi } 193f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 194f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi return false; 195f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi} 196f4e8c16291c58b71dfc622c11f3e00c818dcaebbLucas De Marchi 19796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi/* read-like and fread-like functions */ 19896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi/* ************************************************************************ */ 19996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchissize_t read_str_safe(int fd, char *buf, size_t buflen) 20096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 20196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi size_t todo = buflen - 1; 20296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi size_t done = 0; 20396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 20496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi do { 20596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi ssize_t r = read(fd, buf + done, todo); 20696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 20796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (r == 0) 20896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi break; 20996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi else if (r > 0) { 21096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi todo -= r; 21196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi done += r; 21296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } else { 213a6ede6c7ad46b5e2b8eddddca5590c0b745b045aLucas De Marchi if (errno == EAGAIN || errno == EINTR) 21496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi continue; 21596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi else 21696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return -errno; 21796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 21896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } while (todo > 0); 21996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 22096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi buf[done] = '\0'; 22196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return done; 22296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 22396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 22496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchissize_t write_str_safe(int fd, const char *buf, size_t buflen) 22596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 22696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi size_t todo = buflen; 22796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi size_t done = 0; 22896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 22996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi do { 23096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi ssize_t r = write(fd, buf + done, todo); 23196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 23296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (r == 0) 23396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi break; 23496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi else if (r > 0) { 23596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi todo -= r; 23696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi done += r; 23796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } else { 238a6ede6c7ad46b5e2b8eddddca5590c0b745b045aLucas De Marchi if (errno == EAGAIN || errno == EINTR) 23996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi continue; 24096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi else 24196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return -errno; 24296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 24396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } while (todo > 0); 24496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 24596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return done; 24696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 24796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 24896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchiint read_str_long(int fd, long *value, int base) 24996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 25096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi char buf[32], *end; 25196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi long v; 25296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi int err; 25396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 25496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi *value = 0; 25596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi err = read_str_safe(fd, buf, sizeof(buf)); 25696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (err < 0) 25796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return err; 25896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi errno = 0; 25996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi v = strtol(buf, &end, base); 26096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (end == buf || !isspace(*end)) 26196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return -EINVAL; 26296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 26396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi *value = v; 26496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return 0; 26596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 26696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 26796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchiint read_str_ulong(int fd, unsigned long *value, int base) 26896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 26996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi char buf[32], *end; 27096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi long v; 27196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi int err; 27296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 27396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi *value = 0; 27496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi err = read_str_safe(fd, buf, sizeof(buf)); 27596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (err < 0) 27696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return err; 27796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi errno = 0; 27896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi v = strtoul(buf, &end, base); 27996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (end == buf || !isspace(*end)) 28096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return -EINVAL; 28196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi *value = v; 28296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return 0; 28396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 28496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 28596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi/* 28696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * Read one logical line from a configuration file. 28796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * 28896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * Line endings may be escaped with backslashes, to form one logical line from 28996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * several physical lines. No end of line character(s) are included in the 29096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * result. 29196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * 29296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * If linenum is not NULL, it is incremented by the number of physical lines 29396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * which have been read. 29496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi */ 295aafd38359adfd93b1f8c1e84b8bd7bc9e1b0b6cfLucas De Marchichar *freadline_wrapped(FILE *fp, unsigned int *linenum) 29696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 29796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi int size = 256; 29896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi int i = 0, n = 0; 29996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi _cleanup_free_ char *buf = malloc(size); 30096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 30196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (buf == NULL) 30296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return NULL; 30396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 30496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi for(;;) { 30596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi int ch = getc_unlocked(fp); 30696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 30796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi switch(ch) { 30896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi case EOF: 30996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (i == 0) 31096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return NULL; 31196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi /* else fall through */ 31296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 31396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi case '\n': 31496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi n++; 31596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 31696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi { 31788f6ffe449fc1c92725615348b63c4b59bb50921Caio Marcelo de Oliveira Filho char *ret = buf; 31896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi ret[i] = '\0'; 31996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi buf = NULL; 32096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (linenum) 32196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi *linenum += n; 32296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return ret; 32396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 32496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 32596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi case '\\': 32696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi ch = getc_unlocked(fp); 32796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 32896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (ch == '\n') { 32996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi n++; 33096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi continue; 33196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 33296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi /* else fall through */ 33396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 33496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi default: 33596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi buf[i++] = ch; 33696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 33796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (i == size) { 33896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi char *tmp; 33996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi size *= 2; 34096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi tmp = realloc(buf, size); 34196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (!tmp) 34296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return NULL; 34396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi buf = tmp; 34496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 34596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 34696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 34796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 34896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 34996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi/* path handling functions */ 35096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi/* ************************************************************************ */ 35196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 35296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchibool path_is_absolute(const char *p) 35396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 35496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi assert(p != NULL); 35596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 35696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return p[0] == '/'; 35796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 35896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 35996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchichar *path_make_absolute_cwd(const char *p) 36096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 36196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi _cleanup_free_ char *cwd = NULL; 36296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi size_t plen, cwdlen; 36396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi char *r; 36496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 36596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (path_is_absolute(p)) 36696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return strdup(p); 36796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 36896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi cwd = get_current_dir_name(); 36996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (!cwd) 37096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return NULL; 37196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 37296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi plen = strlen(p); 37396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi cwdlen = strlen(cwd); 37496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 37596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi /* cwd + '/' + p + '\0' */ 37696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi r = realloc(cwd, cwdlen + 1 + plen + 1); 37796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (r == NULL) 37896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return NULL; 37996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 38096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi cwd = NULL; 38196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi r[cwdlen] = '/'; 38296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi memcpy(&r[cwdlen + 1], p, plen + 1); 38396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 38496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return r; 38596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 38696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 38796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchistatic inline int is_dir(const char *path) 38896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 38996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi struct stat st; 39096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 39196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (stat(path, &st) >= 0) 39296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return S_ISDIR(st.st_mode); 39396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 39496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return -errno; 39596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 39696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 39796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchiint mkdir_p(const char *path, int len, mode_t mode) 39896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 39996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi char *start, *end; 40096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 40196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi start = strndupa(path, len); 40296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi end = start + len; 40396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 40496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi /* 40596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * scan backwards, replacing '/' with '\0' while the component doesn't 40696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * exist 40796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi */ 40896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi for (;;) { 40996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi int r = is_dir(start); 41096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (r > 0) { 41196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi end += strlen(end); 41296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 41396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (end == start + len) 41496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return 0; 41596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 41696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi /* end != start, since it would be caught on the first 41796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi * iteration */ 41896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi *end = '/'; 41996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi break; 42096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } else if (r == 0) 42196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return -ENOTDIR; 42296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 42396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (end == start) 42496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi break; 42596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 42696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi *end = '\0'; 42796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 42896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi /* Find the next component, backwards, discarding extra '/'*/ 42996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi while (end > start && *end != '/') 43096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi end--; 43196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 43296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi while (end > start && *(end - 1) == '/') 43396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi end--; 43496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 43596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 43696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi for (; end < start + len;) { 43796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (mkdir(start, mode) < 0 && errno != EEXIST) 43896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return -errno; 43996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 44096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi end += strlen(end); 44196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi *end = '/'; 44296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi } 44396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 44496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return 0; 44596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 44696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 44796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchiint mkdir_parents(const char *path, mode_t mode) 44896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 44996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi char *end = strrchr(path, '/'); 45096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 45196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi /* no parent directories */ 45296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi if (end == NULL) 45396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return 0; 45496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 45596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return mkdir_p(path, end - path, mode); 45696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 45796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 45896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchiunsigned long long ts_usec(const struct timespec *ts) 45996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 46096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return (unsigned long long) ts->tv_sec * USEC_PER_SEC + 46196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi (unsigned long long) ts->tv_nsec / NSEC_PER_USEC; 46296573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 46396573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi 46496573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchiunsigned long long stat_mstamp(const struct stat *st) 46596573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi{ 46696573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#ifdef HAVE_STRUCT_STAT_ST_MTIM 46796573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return ts_usec(&st->st_mtim); 46896573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#else 46996573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi return (unsigned long long) st->st_mtime; 47096573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi#endif 47196573a02208abebe4a884c0bbd0d6ecde9047f37Lucas De Marchi} 472