1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#define LOG_TAG "misc"
18555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project//
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Miscellaneous utility functions.
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project//
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/misc.h>
23555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#include <utils/Log.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/stat.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <string.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <errno.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <assert.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#if defined(HAVE_PTHREADS)
32555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn# include <pthread.h>
33555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#endif
34555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn
35555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#include <utils/Vector.h>
36555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace android;
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Get a file's type.
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectFileType getFileType(const char* fileName)
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    struct stat sb;
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (stat(fileName, &sb) < 0) {
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (errno == ENOENT || errno == ENOTDIR)
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeNonexistent;
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else {
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            fprintf(stderr, "getFileType got errno=%d on '%s'\n",
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                errno, fileName);
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeUnknown;
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (S_ISREG(sb.st_mode))
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeRegular;
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (S_ISDIR(sb.st_mode))
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeDirectory;
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (S_ISCHR(sb.st_mode))
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeCharDev;
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (S_ISBLK(sb.st_mode))
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeBlockDev;
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (S_ISFIFO(sb.st_mode))
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeFifo;
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#ifdef HAVE_SYMLINKS
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (S_ISLNK(sb.st_mode))
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeSymlink;
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (S_ISSOCK(sb.st_mode))
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeSocket;
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return kFileTypeUnknown;
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Get a file's modification date.
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projecttime_t getFileModDate(const char* fileName)
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    struct stat sb;
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (stat(fileName, &sb) < 0)
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return (time_t) -1;
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return sb.st_mtime;
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
91555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackbornstruct sysprop_change_callback_info {
92555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    sysprop_change_callback callback;
93555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    int priority;
94555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn};
95555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn
96555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#if defined(HAVE_PTHREADS)
97555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackbornstatic pthread_mutex_t gSyspropMutex = PTHREAD_MUTEX_INITIALIZER;
98555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackbornstatic Vector<sysprop_change_callback_info>* gSyspropList = NULL;
99555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#endif
100555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn
101555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackbornvoid add_sysprop_change_callback(sysprop_change_callback cb, int priority) {
102555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#if defined(HAVE_PTHREADS)
103555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    pthread_mutex_lock(&gSyspropMutex);
104555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    if (gSyspropList == NULL) {
105555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn        gSyspropList = new Vector<sysprop_change_callback_info>();
106555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    }
107555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    sysprop_change_callback_info info;
108555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    info.callback = cb;
109555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    info.priority = priority;
110555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    bool added = false;
111555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    for (size_t i=0; i<gSyspropList->size(); i++) {
112555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn        if (priority >= gSyspropList->itemAt(i).priority) {
113555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn            gSyspropList->insertAt(info, i);
114555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn            added = true;
115555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn            break;
116555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn        }
117555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    }
118555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    if (!added) {
119555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn        gSyspropList->add(info);
120555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    }
121555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    pthread_mutex_unlock(&gSyspropMutex);
122555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#endif
123555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn}
124555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn
125555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackbornvoid report_sysprop_change() {
126555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#if defined(HAVE_PTHREADS)
127555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    pthread_mutex_lock(&gSyspropMutex);
128555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    Vector<sysprop_change_callback_info> listeners;
129555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    if (gSyspropList != NULL) {
130555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn        listeners = *gSyspropList;
131555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    }
132555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    pthread_mutex_unlock(&gSyspropMutex);
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
134555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    //ALOGI("Reporting sysprop change to %d listeners", listeners.size());
135555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    for (size_t i=0; i<listeners.size(); i++) {
136555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn        listeners[i].callback();
137555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn    }
138555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn#endif
139555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn}
140555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn
141555f89d8df316cdc5a25dbedb8614c2ac7a5e0a9Dianne Hackborn}; // namespace android
142