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((size_t) count-3,
92  sizeof(*wideChar));
93  wcscpy(wideChar,shortPath+4);
94  return(wideChar);
95  }
96  wideChar=(wchar_t *) AcquireQuantumMemory(count,sizeof(*wideChar));
97  if (wideChar == (wchar_t *) NULL)
98  return((wchar_t *) NULL);
99  count=MultiByteToWideChar(CP_UTF8,0,utf8,-1,wideChar,count);
100  if (count == 0)
101  {
102  wideChar=(wchar_t *) RelinquishMagickMemory(wideChar);
103  return((wchar_t *) NULL);
104  }
105  return(wideChar);
106 }
107 
108 static inline wchar_t *create_wchar_mode(const char *mode)
109 {
110  int
111  count;
112 
113  wchar_t
114  *wideChar;
115 
116  count=MultiByteToWideChar(CP_UTF8,0,mode,-1,NULL,0);
117  wideChar=(wchar_t *) AcquireQuantumMemory((size_t) count+1,
118  sizeof(*wideChar));
119  if (wideChar == (wchar_t *) NULL)
120  return((wchar_t *) NULL);
121  count=MultiByteToWideChar(CP_UTF8,0,mode,-1,wideChar,count);
122  if (count == 0)
123  {
124  wideChar=(wchar_t *) RelinquishMagickMemory(wideChar);
125  return((wchar_t *) NULL);
126  }
127  /* Specifies that the file is not inherited by child processes */
128  wideChar[count] = L'\0';
129  wideChar[count-1] = L'N';
130  return(wideChar);
131 }
132 #endif
133 
134 static inline int access_utf8(const char *path,int mode)
135 {
136 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
137  return(access(path,mode));
138 #else
139  int
140  status;
141 
142  wchar_t
143  *path_wide;
144 
145  path_wide=create_wchar_path(path);
146  if (path_wide == (wchar_t *) NULL)
147  return(-1);
148  status=_waccess(path_wide,mode);
149  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
150  return(status);
151 #endif
152 }
153 
154 static inline FILE *fopen_utf8(const char *path,const char *mode)
155 {
156 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
157  return(fopen(path,mode));
158 #else
159  FILE
160  *file;
161 
162  wchar_t
163  *mode_wide,
164  *path_wide;
165 
166  path_wide=create_wchar_path(path);
167  if (path_wide == (wchar_t *) NULL)
168  return((FILE *) NULL);
169  mode_wide=create_wchar_mode(mode);
170  if (mode_wide == (wchar_t *) NULL)
171  {
172  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
173  return((FILE *) NULL);
174  }
175  file=_wfopen(path_wide,mode_wide);
176  mode_wide=(wchar_t *) RelinquishMagickMemory(mode_wide);
177  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
178  return(file);
179 #endif
180 }
181 
182 static inline void getcwd_utf8(char *path,size_t extent)
183 {
184 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
185  char
186  *directory;
187 
188  directory=getcwd(path,extent);
189  (void) directory;
190 #else
191  wchar_t
192  wide_path[MagickPathExtent];
193 
194  (void) _wgetcwd(wide_path,MagickPathExtent-1);
195  (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,NULL);
196 #endif
197 }
198 
199 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__CYGWIN__) && !defined(__MINGW32__)
200 typedef int
201  mode_t;
202 #endif
203 
204 static inline int open_utf8(const char *path,int flags,mode_t mode)
205 {
206 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
207  return(open(path,flags,mode));
208 #else
209  int
210  status;
211 
212  wchar_t
213  *path_wide;
214 
215  path_wide=create_wchar_path(path);
216  if (path_wide == (wchar_t *) NULL)
217  return(-1);
218  /* O_NOINHERIT specifies that the file is not inherited by child processes */
219  status=_wopen(path_wide,flags | O_NOINHERIT,mode);
220  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
221  return(status);
222 #endif
223 }
224 
225 static inline FILE *popen_utf8(const char *command,const char *type)
226 {
227 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
228  return(popen(command,type));
229 #else
230  FILE
231  *file;
232 
233  int
234  length;
235 
236  wchar_t
237  *command_wide,
238  type_wide[5];
239 
240  file=(FILE *) NULL;
241  length=MultiByteToWideChar(CP_UTF8,0,type,-1,type_wide,5);
242  if (length == 0)
243  return(file);
244  length=MultiByteToWideChar(CP_UTF8,0,command,-1,NULL,0);
245  if (length == 0)
246  return(file);
247  command_wide=(wchar_t *) AcquireQuantumMemory(length,sizeof(*command_wide));
248  if (command_wide == (wchar_t *) NULL)
249  return(file);
250  length=MultiByteToWideChar(CP_UTF8,0,command,-1,command_wide,length);
251  if (length != 0)
252  file=_wpopen(command_wide,type_wide);
253  command_wide=(wchar_t *) RelinquishMagickMemory(command_wide);
254  return(file);
255 #endif
256 }
257 
258 static inline int remove_utf8(const char *path)
259 {
260 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
261  return(unlink(path));
262 #else
263  int
264  status;
265 
266  wchar_t
267  *path_wide;
268 
269  path_wide=create_wchar_path(path);
270  if (path_wide == (wchar_t *) NULL)
271  return(-1);
272  status=_wremove(path_wide);
273  path_wide=(wchar_t *) RelinquishMagickMemory(path_wide);
274  return(status);
275 #endif
276 }
277 
278 static inline int rename_utf8(const char *source,const char *destination)
279 {
280 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
281  return(rename(source,destination));
282 #else
283  int
284  status;
285 
286  wchar_t
287  *destination_wide,
288  *source_wide;
289 
290  source_wide=create_wchar_path(source);
291  if (source_wide == (wchar_t *) NULL)
292  return(-1);
293  destination_wide=create_wchar_path(destination);
294  if (destination_wide == (wchar_t *) NULL)
295  {
296  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
297  return(-1);
298  }
299  status=_wrename(source_wide,destination_wide);
300  destination_wide=(wchar_t *) RelinquishMagickMemory(destination_wide);
301  source_wide=(wchar_t *) RelinquishMagickMemory(source_wide);
302  return(status);
303 #endif
304 }
305 
306 static inline int set_file_timestamp(const char *path,struct stat *attributes)
307 {
308  int
309  status;
310 
311 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
312 #if defined(MAGICKCORE_HAVE_UTIMENSAT)
313 #if defined(__APPLE__) || defined(__NetBSD__)
314 #define st_atim st_atimespec
315 #define st_ctim st_ctimespec
316 #define st_mtim st_mtimespec
317 #endif
318 
319  struct timespec
320  timestamp[2];
321 
322  timestamp[0]=attributes->st_atim;
323  timestamp[1]=attributes->st_mtim;
324  status=utimensat(AT_FDCWD,path,timestamp,0);
325 #else
326  struct utimbuf
327  timestamp;
328 
329  timestamp.actime=attributes->st_atime;
330  timestamp.modtime=attributes->st_mtime;
331  status=utime(path,&timestamp);
332 #endif
333 #else
334  HANDLE
335  handle;
336 
337  wchar_t
338  *path_wide;
339 
340  status=(-1);
341  path_wide=create_wchar_path(path);
342  if (path_wide == (WCHAR *) NULL)
343  return(status);
344  handle=CreateFileW(path_wide,FILE_WRITE_ATTRIBUTES,FILE_SHARE_WRITE |
345  FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
346  if (handle != (HANDLE) NULL)
347  {
348  FILETIME
349  creationTime,
350  lastAccessTime,
351  lastWriteTime;
352 
353  LONGLONG
354  dateTime;
355 
356  dateTime=Int32x32To64(attributes->st_ctime,10000000)+116444736000000000;
357  creationTime.dwLowDateTime=(DWORD) dateTime;
358  creationTime.dwHighDateTime=dateTime>>32;
359  dateTime=Int32x32To64(attributes->st_atime,10000000)+116444736000000000;
360  lastAccessTime.dwLowDateTime=(DWORD) dateTime;
361  lastAccessTime.dwHighDateTime=dateTime>>32;
362  dateTime=Int32x32To64(attributes->st_mtime,10000000)+116444736000000000;
363  lastWriteTime.dwLowDateTime=(DWORD) dateTime;
364  lastWriteTime.dwHighDateTime=dateTime>>32;
365  status=SetFileTime(handle,&creationTime,&lastAccessTime,&lastWriteTime);
366  CloseHandle(handle);
367  status=0;
368  }
369  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
370 #endif
371  return(status);
372 }
373 
374 static inline int stat_utf8(const char *path,struct stat *attributes)
375 {
376 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
377  return(stat(path,attributes));
378 #else
379  int
380  status;
381 
382  wchar_t
383  *path_wide;
384 
385  path_wide=create_wchar_path(path);
386  if (path_wide == (WCHAR *) NULL)
387  return(-1);
388  status=wstat(path_wide,attributes);
389  path_wide=(WCHAR *) RelinquishMagickMemory(path_wide);
390  return(status);
391 #endif
392 }
393 
394 #if defined(__cplusplus) || defined(c_plusplus)
395 }
396 #endif
397 
398 #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:465
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:161
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