blob: 9bdaf18a116a4e81253c76dd268c3e42aa564998 [file] [log] [blame]
Adam Lesinski16c4d152014-01-24 13:27:13 -08001/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "misc"
18
19//
20// Miscellaneous utility functions.
21//
22#include <androidfw/misc.h>
23
Yurii Zubrytskyi2ab44472022-11-30 00:56:22 -080024#include "android-base/logging.h"
Adam Lesinski16c4d152014-01-24 13:27:13 -080025
Yurii Zubrytskyi98e12d02022-12-01 09:34:02 -080026#ifdef __linux__
Yurii Zubrytskyi2ab44472022-11-30 00:56:22 -080027#include <sys/statvfs.h>
28#include <sys/vfs.h>
Yurii Zubrytskyi98e12d02022-12-01 09:34:02 -080029#endif // __linux__
Yurii Zubrytskyi2ab44472022-11-30 00:56:22 -080030
Yurii Zubrytskyi2ab44472022-11-30 00:56:22 -080031#include <errno.h>
32#include <sys/stat.h>
Adam Lesinski16c4d152014-01-24 13:27:13 -080033
Yurii Zubrytskyifff1d482024-08-30 16:54:55 -070034#include <cstdio>
35#include <cstring>
36#include <tuple>
37
Adam Lesinski16c4d152014-01-24 13:27:13 -080038namespace android {
39
40/*
41 * Get a file's type.
42 */
43FileType getFileType(const char* fileName)
44{
45 struct stat sb;
46
47 if (stat(fileName, &sb) < 0) {
48 if (errno == ENOENT || errno == ENOTDIR)
49 return kFileTypeNonexistent;
50 else {
Yurii Zubrytskyi2ab44472022-11-30 00:56:22 -080051 PLOG(ERROR) << "getFileType(): stat(" << fileName << ") failed";
Adam Lesinski16c4d152014-01-24 13:27:13 -080052 return kFileTypeUnknown;
53 }
54 } else {
55 if (S_ISREG(sb.st_mode))
56 return kFileTypeRegular;
57 else if (S_ISDIR(sb.st_mode))
58 return kFileTypeDirectory;
59 else if (S_ISCHR(sb.st_mode))
60 return kFileTypeCharDev;
61 else if (S_ISBLK(sb.st_mode))
62 return kFileTypeBlockDev;
63 else if (S_ISFIFO(sb.st_mode))
64 return kFileTypeFifo;
Elliott Hughes1bf24812015-01-12 14:33:04 -080065#if defined(S_ISLNK)
Adam Lesinski16c4d152014-01-24 13:27:13 -080066 else if (S_ISLNK(sb.st_mode))
67 return kFileTypeSymlink;
Elliott Hughes1bf24812015-01-12 14:33:04 -080068#endif
69#if defined(S_ISSOCK)
Adam Lesinski16c4d152014-01-24 13:27:13 -080070 else if (S_ISSOCK(sb.st_mode))
71 return kFileTypeSocket;
72#endif
73 else
74 return kFileTypeUnknown;
75 }
76}
77
Yurii Zubrytskyifff1d482024-08-30 16:54:55 -070078static ModDate getModDate(const struct stat& st) {
79#ifdef _WIN32
80 return st.st_mtime;
81#else
82 return st.st_mtim;
83#endif
Yurii Zubrytskyie7c1f002024-01-30 13:50:57 -080084}
Adam Lesinski16c4d152014-01-24 13:27:13 -080085
Yurii Zubrytskyifff1d482024-08-30 16:54:55 -070086ModDate getFileModDate(const char* fileName) {
87 struct stat sb;
88 if (stat(fileName, &sb) < 0) {
89 return kInvalidModDate;
90 }
91 return getModDate(sb);
92}
93
94ModDate getFileModDate(int fd) {
95 struct stat sb;
96 if (fstat(fd, &sb) < 0) {
97 return kInvalidModDate;
98 }
99 if (sb.st_nlink <= 0) {
100 errno = ENOENT;
101 return kInvalidModDate;
102 }
103 return getModDate(sb);
Adam Lesinski16c4d152014-01-24 13:27:13 -0800104}
105
Yurii Zubrytskyi98e12d02022-12-01 09:34:02 -0800106#ifndef __linux__
107// No need to implement these on the host, the functions only matter on a device.
Yurii Zubrytskyi2ab44472022-11-30 00:56:22 -0800108bool isReadonlyFilesystem(const char*) {
109 return false;
110}
111bool isReadonlyFilesystem(int) {
112 return false;
113}
Yurii Zubrytskyi98e12d02022-12-01 09:34:02 -0800114#else // __linux__
Yurii Zubrytskyi2ab44472022-11-30 00:56:22 -0800115bool isReadonlyFilesystem(const char* path) {
116 struct statfs sfs;
117 if (::statfs(path, &sfs)) {
118 PLOG(ERROR) << "isReadonlyFilesystem(): statfs(" << path << ") failed";
119 return false;
120 }
121 return (sfs.f_flags & ST_RDONLY) != 0;
122}
123
124bool isReadonlyFilesystem(int fd) {
125 struct statfs sfs;
126 if (::fstatfs(fd, &sfs)) {
127 PLOG(ERROR) << "isReadonlyFilesystem(): fstatfs(" << fd << ") failed";
128 return false;
129 }
130 return (sfs.f_flags & ST_RDONLY) != 0;
131}
Yurii Zubrytskyi98e12d02022-12-01 09:34:02 -0800132#endif // __linux__
Yurii Zubrytskyi2ab44472022-11-30 00:56:22 -0800133
Yurii Zubrytskyifff1d482024-08-30 16:54:55 -0700134} // namespace android
135
136bool operator==(const timespec& l, const timespec& r) {
137 return std::tie(l.tv_sec, l.tv_nsec) == std::tie(r.tv_sec, l.tv_nsec);
138}