MagickCore  7.1.0
utility-private.h
Go to the documentation of this file.
1 /*
2  Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization
3  dedicated to making software imaging solutions freely available.
4 
5  You may not use this file except in compliance with the License. You may
6  obtain a copy of the License at
7 
8  https://imagemagick.org/script/license.php
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  MagickCore private utility methods.
17 */
18 #ifndef MAGICKCORE_UTILITY_PRIVATE_H
19 #define MAGICKCORE_UTILITY_PRIVATE_H
20 
21 #include "MagickCore/memory_.h"
22 #include "MagickCore/nt-base.h"
24 #if defined(MAGICKCORE_HAVE_UTIME_H)
25 #include <utime.h>
26 #endif
27 
28 #if defined(__cplusplus) || defined(c_plusplus)
29 extern "C" {
30 #endif
31 
32 extern MagickPrivate char
33  **GetPathComponents(const char *,size_t *),
34  **ListFiles(const char *,const char *,size_t *);
35 
37  GetExecutionPath(char *,const size_t),
38  ShredFile(const char *);
39 
40 extern MagickPrivate ssize_t
41  GetMagickPageSize(void);
42 
43 extern MagickPrivate void
44  ChopPathComponents(char *,const size_t),
45  ExpandFilename(char *);
46 
47 static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
48  struct dirent **result)
49 {
50  (void) entry;
51  errno=0;
52  *result=readdir(directory);
53  return(errno);
54 }
55 
56 /*
57  Windows UTF8 compatibility methods.
58 */
59 
60 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
61 static inline wchar_t *create_wchar_path(const char *utf8)
62 {
63  int
64  count;
65 
66  wchar_t
67  *wideChar;
68 
69  count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,NULL,0);
70  if ((count > MAX_PATH) && (strncmp(utf8,"\\\\?\\",4) != 0) &&
71  (NTLongPathsEnabled() == MagickFalse))
72  {
73  char
74  buffer[MagickPathExtent];
75 
76  wchar_t
77  shortPath[MAX_PATH],
78  *longPath;
79 
80  (void) FormatLocaleString(buffer,MagickPathExtent,"\\\\?\\%s",utf8);
81  count+=4;
82  longPath=(wchar_t *) AcquireQuantumMemory(count,sizeof(*longPath));
83  if (longPath == (wchar_t *) NULL)
84  return((wchar_t *) NULL);
85  count=MultiByteToWideChar(CP_UTF8,0,buffer,-1,longPath,count);
86  if (count != 0)
87  count=GetShortPathNameW(longPath,shortPath,MAX_PATH);
88  longPath=(wchar_t *) RelinquishMagickMemory(longPath);
89  if ((count < 5) || (count >= MAX_PATH))
90  return((wchar_t *) NULL);
91  wideChar=(wchar_t *) AcquireQuantumMemory(count-3,sizeof(*wideChar));
92  wcscpy(wideChar,shortPath+4);
93  return(wideChar);
94  }
95  wideChar=(wchar_t *) AcquireQuantumMemory(count,sizeof(*wideChar));
96  if (wideChar == (wchar_t *) NULL)
97  return((wchar_t *) NULL);
98  count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,wideChar,count);
99  if (count == 0)
100  {
101  wideChar=(wchar_t *) RelinquishMagickMemory(wideChar);
102  return((wchar_t *) NULL);
103  }
104  return(wideChar);
105 }
106 #endif
107 
108 static inline int access_utf8(const char *path,int mode)
109 {
110 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
111  return(access(path,mode));
112 #else
113  int
114  status;
115 
116  wchar_t
117  *path_wide;
118 
119  path_wide=create_wchar_path(path);
120  if (path_wide == (wchar_t *) NULL)
121  return(-1);
122  status=_waccess(path_wide,mode);
123  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
124  return(status);
125 #endif
126 }
127 
128 static inline FILE *fopen_utf8(const char *path,const char *mode)
129 {
130 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
131  return(fopen(path,mode));
132 #else
133  FILE
134  *file;
135 
136  wchar_t
137  *mode_wide,
138  *path_wide;
139 
140  path_wide=create_wchar_path(path);
141  if (path_wide == (wchar_t *) NULL)
142  return((FILE *) NULL);
143  mode_wide=create_wchar_path(mode);
144  if (mode_wide == (wchar_t *) NULL)
145  {
146  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
147  return((FILE *) NULL);
148  }
149  file=_wfopen(path_wide,mode_wide);
150  mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide);
151  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
152  return(file);
153 #endif
154 }
155 
156 static inline void getcwd_utf8(char *path,size_t extent)
157 {
158 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
159  char
160  *directory;
161 
162  directory=getcwd(path,extent);
163  (void) directory;
164 #else
165  wchar_t
166  wide_path[MagickPathExtent];
167 
168  (void) _wgetcwd(wide_path,MagickPathExtent-1);
169  (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,NULL);
170 #endif
171 }
172 
173 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
174 typedef int
175  mode_t;
176 #endif
177 
178 static inline int open_utf8(const char *path,int flags,mode_t mode)
179 {
180 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
181  return(open(path,flags,mode));
182 #else
183  int
184  status;
185 
186  wchar_t
187  *path_wide;
188 
189  path_wide=create_wchar_path(path);
190  if (path_wide == (wchar_t *) NULL)
191  return(-1);
192  status=_wopen(path_wide,flags,mode);
193  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
194  return(status);
195 #endif
196 }
197 
198 static inline FILE *popen_utf8(const char *command,const char *type)
199 {
200 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
201  return(popen(command,type));
202 #else
203  FILE
204  *file;
205 
206  int
207  length;
208 
209  wchar_t
210  *command_wide,
211  type_wide[5];
212 
213  file=(FILE *) NULL;
214  length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
215  if (length == 0)
216  return(file);
217  length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
218  if (length == 0)
219  return(file);
220  command_wide=(wchar_t *) AcquireQuantumMemory(length,sizeof(*command_wide));
221  if (command_wide == (wchar_t *) NULL)
222  return(file);
223  length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
224  if (length != 0)
225  file=_wpopen(command_wide,type_wide);
226  command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
227  return(file);
228 #endif
229 }
230 
231 static inline int remove_utf8(const char *path)
232 {
233 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
234  return(unlink(path));
235 #else
236  int
237  status;
238 
239  wchar_t
240  *path_wide;
241 
242  path_wide=create_wchar_path(path);
243  if (path_wide == (wchar_t *) NULL)
244  return(-1);
245  status=_wremove(path_wide);
246  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
247  return(status);
248 #endif
249 }
250 
251 static inline int rename_utf8(const char *source,const char *destination)
252 {
253 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
254  return(rename(source,destination));
255 #else
256  int
257  status;
258 
259  wchar_t
260  *destination_wide,
261  *source_wide;
262 
263  source_wide=create_wchar_path(source);
264  if (source_wide == (wchar_t *) NULL)
265  return(-1);
266  destination_wide=create_wchar_path(destination);
267  if (destination_wide == (wchar_t *) NULL)
268  {
269  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
270  return(-1);
271  }
272  status=_wrename(source_wide,destination_wide);
273  destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide);
274  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
275  return(status);
276 #endif
277 }
278 
279 static inline int set_file_timestamp(const char *path,struct stat *attributes)
280 {
281  int
282  status;
283 
284 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
285 #if defined(MAGICKCORE_HAVE_UTIMENSAT)
286 #if defined(__APPLE__) || defined(__NetBSD__)
287 #define st_atim st_atimespec
288 #define st_ctim st_ctimespec
289 #define st_mtim st_mtimespec
290 #endif
291 
292  struct timespec
293  timestamp[2];
294 
295  timestamp[0]=attributes->st_atim;
296  timestamp[1]=attributes->st_mtim;
297  status=utimensat(AT_FDCWD,path,timestamp,0);
298 #else
299  struct utimbuf
300  timestamp;
301 
302  timestamp.actime=attributes->st_atime;
303  timestamp.modtime=attributes->st_mtime;
304  status=utime(path,&timestamp);
305 #endif
306 #else
307  HANDLE
308  handle;
309 
310  wchar_t
311  *path_wide;
312 
313  status=(-1);
314  path_wide=create_wchar_path(path);
315  if (path_wide == (WCHAR *) NULL)
316  return(status);
317  handle=CreateFileW(path_wide,FILE_WRITE_ATTRIBUTES,FILE_SHARE_WRITE |
318  FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
319  if (handle != (HANDLE) NULL)
320  {
321  FILETIME
322  creationTime,
323  lastAccessTime,
324  lastWriteTime;
325 
326  LONGLONG
327  dateTime;
328 
329  dateTime=Int32x32To64(attributes->st_ctime,10000000)+116444736000000000;
330  creationTime.dwLowDateTime=(DWORD) dateTime;
331  creationTime.dwHighDateTime=dateTime>>32;
332  dateTime=Int32x32To64(attributes->st_atime,10000000)+116444736000000000;
333  lastAccessTime.dwLowDateTime=(DWORD) dateTime;
334  lastAccessTime.dwHighDateTime=dateTime>>32;
335  dateTime=Int32x32To64(attributes->st_mtime,10000000)+116444736000000000;
336  lastWriteTime.dwLowDateTime=(DWORD) dateTime;
337  lastWriteTime.dwHighDateTime=dateTime>>32;
338  status=SetFileTime(handle,&creationTime,&lastAccessTime,&lastWriteTime);
339  CloseHandle(handle);
340  status=0;
341  }
342  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
343 #endif
344  return(status);
345 }
346 
347 static inline int stat_utf8(const char *path,struct stat *attributes)
348 {
349 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
350  return(stat(path,attributes));
351 #else
352  int
353  status;
354 
355  wchar_t
356  *path_wide;
357 
358  path_wide=create_wchar_path(path);
359  if (path_wide == (WCHAR *) NULL)
360  return(-1);
361  status=wstat(path_wide,attributes);
362  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
363  return(status);
364 #endif
365 }
366 
367 #if defined(__cplusplus) || defined(c_plusplus)
368 }
369 #endif
370 
371 #endif
static int set_file_timestamp(const char *path, struct stat *attributes)
static FILE * popen_utf8(const char *command, const char *type)
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
Definition: locale.c:463
static void getcwd_utf8(char *path, size_t extent)
Definition: vms.h:941
static int stat_utf8(const char *path, struct stat *attributes)
MagickBooleanType
Definition: magick-type.h:165
MagickPrivate ssize_t GetMagickPageSize(void)
Definition: utility.c:1132
static int remove_utf8(const char *path)
MagickPrivate void ExpandFilename(char *)
Definition: utility.c:616
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:665
static FILE * fopen_utf8(const char *path, const char *mode)
Definition: vms.h:950
struct dirent * readdir(DIR *)
#define MagickPathExtent
static int open_utf8(const char *path, int flags, mode_t mode)
MagickPrivate MagickBooleanType ShredFile(const char *)
Definition: utility.c:1845
MagickPrivate char ** GetPathComponents(const char *, size_t *)
MagickPrivate char ** ListFiles(const char *, const char *, size_t *)
Definition: utility.c:1609
MagickPrivate MagickBooleanType GetExecutionPath(char *, const size_t)
static int rename_utf8(const char *source, const char *destination)
static int access_utf8(const char *path, int mode)
static int MagickReadDirectory(DIR *directory, struct dirent *entry, struct dirent **result)
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1162
MagickPrivate void ChopPathComponents(char *, const size_t)
#define MagickPrivate