Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/power/acpi/os_specific/service_layers/osunixdir.c
26292 views
1
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2
/******************************************************************************
3
*
4
* Module Name: osunixdir - Unix directory access interfaces
5
*
6
* Copyright (C) 2000 - 2025, Intel Corp.
7
*
8
*****************************************************************************/
9
10
#include <acpi/acpi.h>
11
12
#include <stdio.h>
13
#include <stdlib.h>
14
#include <string.h>
15
#include <dirent.h>
16
#include <fnmatch.h>
17
#include <ctype.h>
18
#include <sys/stat.h>
19
20
/*
21
* Allocated structure returned from os_open_directory
22
*/
23
typedef struct external_find_info {
24
char *dir_pathname;
25
DIR *dir_ptr;
26
char temp_buffer[256];
27
char *wildcard_spec;
28
char requested_file_type;
29
30
} external_find_info;
31
32
/*******************************************************************************
33
*
34
* FUNCTION: acpi_os_open_directory
35
*
36
* PARAMETERS: dir_pathname - Full pathname to the directory
37
* wildcard_spec - string of the form "*.c", etc.
38
*
39
* RETURN: A directory "handle" to be used in subsequent search operations.
40
* NULL returned on failure.
41
*
42
* DESCRIPTION: Open a directory in preparation for a wildcard search
43
*
44
******************************************************************************/
45
46
void *acpi_os_open_directory(char *dir_pathname,
47
char *wildcard_spec, char requested_file_type)
48
{
49
struct external_find_info *external_info;
50
DIR *dir;
51
52
/* Allocate the info struct that will be returned to the caller */
53
54
external_info = calloc(1, sizeof(struct external_find_info));
55
if (!external_info) {
56
return (NULL);
57
}
58
59
/* Get the directory stream */
60
61
dir = opendir(dir_pathname);
62
if (!dir) {
63
fprintf(stderr, "Cannot open directory - %s\n", dir_pathname);
64
free(external_info);
65
return (NULL);
66
}
67
68
/* Save the info in the return structure */
69
70
external_info->wildcard_spec = wildcard_spec;
71
external_info->requested_file_type = requested_file_type;
72
external_info->dir_pathname = dir_pathname;
73
external_info->dir_ptr = dir;
74
return (external_info);
75
}
76
77
/*******************************************************************************
78
*
79
* FUNCTION: acpi_os_get_next_filename
80
*
81
* PARAMETERS: dir_handle - Created via acpi_os_open_directory
82
*
83
* RETURN: Next filename matched. NULL if no more matches.
84
*
85
* DESCRIPTION: Get the next file in the directory that matches the wildcard
86
* specification.
87
*
88
******************************************************************************/
89
90
char *acpi_os_get_next_filename(void *dir_handle)
91
{
92
struct external_find_info *external_info = dir_handle;
93
struct dirent *dir_entry;
94
char *temp_str;
95
int str_len;
96
struct stat temp_stat;
97
int err;
98
99
while ((dir_entry = readdir(external_info->dir_ptr))) {
100
if (!fnmatch
101
(external_info->wildcard_spec, dir_entry->d_name, 0)) {
102
if (dir_entry->d_name[0] == '.') {
103
continue;
104
}
105
106
str_len = strlen(dir_entry->d_name) +
107
strlen(external_info->dir_pathname) + 2;
108
109
temp_str = calloc(str_len, 1);
110
if (!temp_str) {
111
fprintf(stderr,
112
"Could not allocate buffer for temporary string\n");
113
return (NULL);
114
}
115
116
strcpy(temp_str, external_info->dir_pathname);
117
strcat(temp_str, "/");
118
strcat(temp_str, dir_entry->d_name);
119
120
err = stat(temp_str, &temp_stat);
121
if (err == -1) {
122
fprintf(stderr,
123
"Cannot stat file (should not happen) - %s\n",
124
temp_str);
125
free(temp_str);
126
return (NULL);
127
}
128
129
free(temp_str);
130
131
if ((S_ISDIR(temp_stat.st_mode)
132
&& (external_info->requested_file_type ==
133
REQUEST_DIR_ONLY))
134
|| ((!S_ISDIR(temp_stat.st_mode)
135
&& external_info->requested_file_type ==
136
REQUEST_FILE_ONLY))) {
137
138
/* copy to a temp buffer because dir_entry struct is on the stack */
139
140
strcpy(external_info->temp_buffer,
141
dir_entry->d_name);
142
return (external_info->temp_buffer);
143
}
144
}
145
}
146
147
return (NULL);
148
}
149
150
/*******************************************************************************
151
*
152
* FUNCTION: acpi_os_close_directory
153
*
154
* PARAMETERS: dir_handle - Created via acpi_os_open_directory
155
*
156
* RETURN: None.
157
*
158
* DESCRIPTION: Close the open directory and cleanup.
159
*
160
******************************************************************************/
161
162
void acpi_os_close_directory(void *dir_handle)
163
{
164
struct external_find_info *external_info = dir_handle;
165
166
/* Close the directory and free allocations */
167
168
closedir(external_info->dir_ptr);
169
free(dir_handle);
170
}
171
172