MagickCore  7.0.8
Convert, Edit, Or Compose Bitmap Images
resource.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % RRRR EEEEE SSSSS OOO U U RRRR CCCC EEEEE %
7 % R R E SS O O U U R R C E %
8 % RRRR EEE SSS O O U U RRRR C EEE %
9 % R R E SS O O U U R R C E %
10 % R R EEEEE SSSSS OOO UUU R R CCCC EEEEE %
11 % %
12 % %
13 % Get/Set MagickCore Resources %
14 % %
15 % Software Design %
16 % Cristy %
17 % September 2002 %
18 % %
19 % %
20 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
22 % %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
25 % %
26 % https://www.imagemagick.org/script/license.php %
27 % %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 */
38 
39 /*
40  Include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/cache.h"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/exception.h"
48 #include "MagickCore/linked-list.h"
49 #include "MagickCore/log.h"
50 #include "MagickCore/image.h"
52 #include "MagickCore/memory_.h"
54 #include "MagickCore/option.h"
55 #include "MagickCore/policy.h"
56 #include "MagickCore/random_.h"
57 #include "MagickCore/registry.h"
58 #include "MagickCore/resource_.h"
60 #include "MagickCore/semaphore.h"
62 #include "MagickCore/string_.h"
64 #include "MagickCore/splay-tree.h"
66 #include "MagickCore/token.h"
67 #include "MagickCore/utility.h"
69 
70 /*
71  Define declarations.
72 */
73 #define MagickPathTemplate "XXXXXXXXXXXX"
74 
75 /*
76  Typedef declarations.
77 */
78 typedef struct _ResourceInfo
79 {
82  height,
84  area,
85  memory,
86  map,
87  disk,
88  file,
89  thread,
90  throttle,
91  time;
92 
97  area_limit,
99  map_limit,
100  disk_limit,
101  file_limit,
102  thread_limit,
104  time_limit;
105 } ResourceInfo;
106 
107 /*
108  Global declarations.
109 */
110 static RandomInfo
111  *random_info = (RandomInfo *) NULL;
112 
113 static ResourceInfo
115  {
116  MagickULLConstant(0), /* initial width */
117  MagickULLConstant(0), /* initial height */
118  MagickULLConstant(0), /* initial list length */
119  MagickULLConstant(0), /* initial area */
120  MagickULLConstant(0), /* initial memory */
121  MagickULLConstant(0), /* initial map */
122  MagickULLConstant(0), /* initial disk */
123  MagickULLConstant(0), /* initial file */
124  MagickULLConstant(0), /* initial thread */
125  MagickULLConstant(0), /* initial throttle */
126  MagickULLConstant(0), /* initial time */
127  (INT_MAX/(5*sizeof(Quantum))), /* width limit */
128  (INT_MAX/(5*sizeof(Quantum))), /* height limit */
129  MagickResourceInfinity, /* list length limit */
130  MagickULLConstant(3072)*1024*1024, /* area limit */
131  MagickULLConstant(1536)*1024*1024, /* memory limit */
132  MagickULLConstant(3072)*1024*1024, /* map limit */
133  MagickResourceInfinity, /* disk limit */
134  MagickULLConstant(768), /* file limit */
135  MagickULLConstant(1), /* thread limit */
136  MagickULLConstant(0), /* throttle limit */
137  MagickResourceInfinity /* time limit */
138  };
139 
140 static SemaphoreInfo
142 
143 static SplayTreeInfo
145 
146 /*
147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
148 % %
149 % %
150 % %
151 % A c q u i r e M a g i c k R e s o u r c e %
152 % %
153 % %
154 % %
155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
156 %
157 % AcquireMagickResource() acquires resources of the specified type.
158 % MagickFalse is returned if the specified resource is exhausted otherwise
159 % MagickTrue.
160 %
161 % The format of the AcquireMagickResource() method is:
162 %
163 % MagickBooleanType AcquireMagickResource(const ResourceType type,
164 % const MagickSizeType size)
165 %
166 % A description of each parameter follows:
167 %
168 % o type: the type of resource.
169 %
170 % o size: the number of bytes needed from for this resource.
171 %
172 */
174  const MagickSizeType size)
175 {
177  bi,
178  status;
179 
181  current,
182  request;
183 
185  limit;
186 
187  request=(MagickOffsetType) size;
188  if (request < 0)
189  return(MagickFalse);
190  limit=0;
191  bi=MagickFalse;
192  status=MagickFalse;
193  switch (type)
194  {
195  case AreaResource:
196  {
197  bi=MagickTrue;
198  resource_info.area=request;
200  break;
201  }
202  case HeightResource:
203  {
204  bi=MagickTrue;
205  resource_info.height=request;
207  break;
208  }
209  case ListLengthResource:
210  {
211  resource_info.list_length=request;
213  break;
214  }
215  case ThreadResource:
216  {
218  break;
219  }
220  case ThrottleResource:
221  {
223  break;
224  }
225  case WidthResource:
226  {
227  bi=MagickTrue;
228  resource_info.width=request;
230  break;
231  }
232  default:
233  break;
234  }
235  if (limit != 0)
236  {
237  if ((limit == MagickResourceInfinity) || (size < limit))
238  status=MagickTrue;
239  if (IsEventLogging() != MagickFalse)
240  {
241  char
242  resource_limit[MagickFormatExtent],
243  resource_request[MagickFormatExtent];
244 
245  (void) FormatMagickSize(size,MagickFalse,(bi != MagickFalse) ?
246  "P" : (const char *) NULL,MagickFormatExtent,resource_request);
248  (bi != MagickFalse) ? "P" : (const char *) NULL,
249  MagickFormatExtent,resource_limit);
250  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s",
252  resource_request,resource_limit);
253  }
254  return(status);
255  }
256  if (resource_semaphore == (SemaphoreInfo *) NULL)
259  switch (type)
260  {
261  case DiskResource:
262  {
263  bi=MagickTrue;
265  if ((resource_info.disk+request) > resource_info.disk)
266  {
267  resource_info.disk+=request;
268  if ((limit == MagickResourceInfinity) ||
269  (resource_info.disk < (MagickOffsetType) limit))
270  status=MagickTrue;
271  else
272  resource_info.disk-=request;
273  }
274  current=resource_info.disk;
275  break;
276  }
277  case FileResource:
278  {
280  if ((resource_info.file+request) > resource_info.file)
281  {
282  resource_info.file+=request;
283  if ((limit == MagickResourceInfinity) ||
284  (resource_info.file < (MagickOffsetType) limit))
285  status=MagickTrue;
286  }
287  current=resource_info.file;
288  break;
289  }
290  case MapResource:
291  {
292  bi=MagickTrue;
293  limit=resource_info.map_limit;
294  if ((resource_info.map+request) > resource_info.map)
295  {
296  resource_info.map+=request;
297  if ((limit == MagickResourceInfinity) ||
298  (resource_info.map < (MagickOffsetType) limit))
299  status=MagickTrue;
300  else
301  resource_info.map-=request;
302  }
303  current=resource_info.map;
304  break;
305  }
306  case MemoryResource:
307  {
308  bi=MagickTrue;
310  if ((resource_info.memory+request) > resource_info.memory)
311  {
312  resource_info.memory+=request;
313  if ((limit == MagickResourceInfinity) ||
315  status=MagickTrue;
316  else
317  resource_info.memory-=request;
318  }
319  current=resource_info.memory;
320  break;
321  }
322  case TimeResource:
323  {
325  if ((resource_info.time+request) > resource_info.time)
326  {
327  resource_info.time+=request;
328  if ((limit == MagickResourceInfinity) ||
329  (resource_info.time < (MagickOffsetType) limit))
330  status=MagickTrue;
331  else
332  resource_info.time-=request;
333  }
334  current=resource_info.time;
335  break;
336  }
337  default:
338  {
339  current=0;
340  break;
341  }
342  }
344  if (IsEventLogging() != MagickFalse)
345  {
346  char
347  resource_current[MagickFormatExtent],
348  resource_limit[MagickFormatExtent],
349  resource_request[MagickFormatExtent];
350 
351  (void) FormatMagickSize(size,bi,(bi != MagickFalse) ? "B" :
352  (const char *) NULL,MagickFormatExtent,resource_request);
353  (void) FormatMagickSize((MagickSizeType) current,bi,(bi != MagickFalse) ?
354  "B" : (const char *) NULL,MagickFormatExtent,resource_current);
355  (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ? "B" :
356  (const char *) NULL,MagickFormatExtent,resource_limit);
357  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
359  resource_request,resource_current,resource_limit);
360  }
361  return(status);
362 }
363 
364 /*
365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366 % %
367 % %
368 % %
369 + A s y n c h r o n o u s R e s o u r c e C o m p o n e n t T e r m i n u s %
370 % %
371 % %
372 % %
373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374 %
375 % AsynchronousResourceComponentTerminus() destroys the resource environment.
376 % It differs from ResourceComponentTerminus() in that it can be called from a
377 % asynchronous signal handler.
378 %
379 % The format of the ResourceComponentTerminus() method is:
380 %
381 % ResourceComponentTerminus(void)
382 %
383 */
385 {
386  const char
387  *path;
388 
389  if (temporary_resources == (SplayTreeInfo *) NULL)
390  return;
391  /*
392  Remove any lingering temporary files.
393  */
395  path=(const char *) GetNextKeyInSplayTree(temporary_resources);
396  while (path != (const char *) NULL)
397  {
398  (void) ShredFile(path);
399  path=(const char *) GetNextKeyInSplayTree(temporary_resources);
400  }
401 }
402 
403 /*
404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
405 % %
406 % %
407 % %
408 % A c q u i r e U n i q u e F i l e R e s o u r c e %
409 % %
410 % %
411 % %
412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
413 %
414 % AcquireUniqueFileResource() returns a unique file name, and returns a file
415 % descriptor for the file open for reading and writing.
416 %
417 % The format of the AcquireUniqueFileResource() method is:
418 %
419 % int AcquireUniqueFileResource(char *path)
420 %
421 % A description of each parameter follows:
422 %
423 % o path: Specifies a pointer to an array of characters. The unique path
424 % name is returned in this array.
425 %
426 */
427 
428 static void *DestroyTemporaryResources(void *temporary_resource)
429 {
430  (void) ShredFile((char *) temporary_resource);
431  temporary_resource=DestroyString((char *) temporary_resource);
432  return((void *) NULL);
433 }
434 
436 {
437  char
438  *directory,
439  *value;
440 
442  *exception;
443 
445  status;
446 
447  struct stat
448  attributes;
449 
450  (void) FormatLocaleString(path,MagickPathExtent,"magick-%.20g"
451  MagickPathTemplate,(double) getpid());
452  exception=AcquireExceptionInfo();
453  directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
454  exception);
455  exception=DestroyExceptionInfo(exception);
456  if (directory == (char *) NULL)
457  directory=GetEnvironmentValue("MAGICK_TEMPORARY_PATH");
458  if (directory == (char *) NULL)
459  directory=GetEnvironmentValue("MAGICK_TMPDIR");
460  if (directory == (char *) NULL)
461  directory=GetEnvironmentValue("TMPDIR");
462 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
463  if (directory == (char *) NULL)
464  directory=GetEnvironmentValue("TMP");
465  if (directory == (char *) NULL)
466  directory=GetEnvironmentValue("TEMP");
467 #endif
468 #if defined(__VMS)
469  if (directory == (char *) NULL)
470  directory=GetEnvironmentValue("MTMPDIR");
471 #endif
472 #if defined(P_tmpdir)
473  if (directory == (char *) NULL)
474  directory=ConstantString(P_tmpdir);
475 #endif
476  if (directory == (char *) NULL)
477  return(MagickTrue);
478  value=GetPolicyValue("resource:temporary-path");
479  if (value != (char *) NULL)
480  {
481  (void) CloneString(&directory,value);
482  value=DestroyString(value);
483  }
484  if (strlen(directory) > (MagickPathExtent-25))
485  {
486  directory=DestroyString(directory);
487  return(MagickFalse);
488  }
489  status=GetPathAttributes(directory,&attributes);
490  if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
491  {
492  directory=DestroyString(directory);
493  return(MagickFalse);
494  }
495  if (directory[strlen(directory)-1] == *DirectorySeparator)
497  "%smagick-%.20g" MagickPathTemplate,directory,(double) getpid());
498  else
500  "%s%smagick-%.20g" MagickPathTemplate,directory,DirectorySeparator,
501  (double) getpid());
502  directory=DestroyString(directory);
503 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
504  {
505  register char
506  *p;
507 
508  /*
509  Ghostscript does not like backslashes so we need to replace them. The
510  forward slash also works under Windows.
511  */
512  for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p != '\0'; p++)
513  if (*p == *DirectorySeparator)
514  *p='/';
515  }
516 #endif
517  return(MagickTrue);
518 }
519 
521 {
522 #if !defined(O_NOFOLLOW)
523 #define O_NOFOLLOW 0
524 #endif
525 #if !defined(TMP_MAX)
526 # define TMP_MAX 238328
527 #endif
528 
529  int
530  c,
531  file;
532 
533  register char
534  *p;
535 
536  register ssize_t
537  i;
538 
539  static const char
540  portable_filename[65] =
541  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
542 
543  StringInfo
544  *key;
545 
546  unsigned char
547  *datum;
548 
549  assert(path != (char *) NULL);
551  if (random_info == (RandomInfo *) NULL)
552  {
553  if (resource_semaphore == (SemaphoreInfo *) NULL)
556  if (random_info == (RandomInfo *) NULL)
559  }
560  file=(-1);
561  for (i=0; i < (ssize_t) TMP_MAX; i++)
562  {
563  register ssize_t
564  j;
565 
566  /*
567  Get temporary pathname.
568  */
569  (void) GetPathTemplate(path);
570  key=GetRandomKey(random_info,6);
571  p=path+strlen(path)-strlen(MagickPathTemplate);
572  datum=GetStringInfoDatum(key);
573  for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
574  {
575  c=(int) (datum[j] & 0x3f);
576  *p++=portable_filename[c];
577  }
578  key=DestroyStringInfo(key);
579 #if defined(MAGICKCORE_HAVE_MKSTEMP)
580  file=mkstemp(path);
581  if (file != -1)
582  {
583 #if defined(MAGICKCORE_HAVE_FCHMOD)
584  (void) fchmod(file,0600);
585 #endif
586 #if defined(__OS2__)
587  setmode(file,O_BINARY);
588 #endif
589  break;
590  }
591 #endif
593  p=path+strlen(path)-strlen(MagickPathTemplate);
594  datum=GetStringInfoDatum(key);
595  for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
596  {
597  c=(int) (datum[j] & 0x3f);
598  *p++=portable_filename[c];
599  }
600  key=DestroyStringInfo(key);
601  file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
602  S_MODE);
603  if ((file >= 0) || (errno != EEXIST))
604  break;
605  }
606  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
607  if (file == -1)
608  return(file);
609  if (resource_semaphore == (SemaphoreInfo *) NULL)
612  if (temporary_resources == (SplayTreeInfo *) NULL)
614  DestroyTemporaryResources,(void *(*)(void *)) NULL);
617  (const void *) NULL);
618  return(file);
619 }
620 
621 /*
622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
623 % %
624 % %
625 % %
626 % G e t M a g i c k R e s o u r c e %
627 % %
628 % %
629 % %
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
631 %
632 % GetMagickResource() returns the specified resource.
633 %
634 % The format of the GetMagickResource() method is:
635 %
636 % MagickSizeType GetMagickResource(const ResourceType type)
637 %
638 % A description of each parameter follows:
639 %
640 % o type: the type of resource.
641 %
642 */
644 {
646  resource;
647 
648  resource=0;
649  switch (type)
650  {
651  case AreaResource:
652  {
653  resource=(MagickSizeType) resource_info.area;
654  break;
655  }
656  case HeightResource:
657  {
659  break;
660  }
661  case ListLengthResource:
662  {
664  break;
665  }
666  case ThreadResource:
667  {
669  break;
670  }
671  case ThrottleResource:
672  {
674  break;
675  }
676  case WidthResource:
677  {
679  break;
680  }
681  default:
682  {
683  if (resource_semaphore == (SemaphoreInfo *) NULL)
686  switch (type)
687  {
688  case DiskResource:
689  {
690  resource=(MagickSizeType) resource_info.disk;
691  break;
692  }
693  case FileResource:
694  {
695  resource=(MagickSizeType) resource_info.file;
696  break;
697  }
698  case MapResource:
699  {
700  resource=(MagickSizeType) resource_info.map;
701  break;
702  }
703  case MemoryResource:
704  {
706  break;
707  }
708  case TimeResource:
709  {
710  resource=(MagickSizeType) resource_info.time;
711  break;
712  }
713  default:
714  break;
715  }
717  break;
718  }
719  }
720  return(resource);
721 }
722 
723 /*
724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
725 % %
726 % %
727 % %
728 % G e t M a g i c k R e s o u r c e L i m i t %
729 % %
730 % %
731 % %
732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
733 %
734 % GetMagickResourceLimit() returns the specified resource limit.
735 %
736 % The format of the GetMagickResourceLimit() method is:
737 %
738 % MagickSizeType GetMagickResourceLimit(const ResourceType type)
739 %
740 % A description of each parameter follows:
741 %
742 % o type: the type of resource.
743 %
744 */
746 {
748  resource;
749 
750  resource=0;
751  switch (type)
752  {
753  case AreaResource:
754  {
755  resource=resource_info.area_limit;
756  break;
757  }
758  case DiskResource:
759  {
760  resource=resource_info.disk_limit;
761  break;
762  }
763  case FileResource:
764  {
765  resource=resource_info.file_limit;
766  break;
767  }
768  case HeightResource:
769  {
770  resource=resource_info.height_limit;
771  break;
772  }
773  case ListLengthResource:
774  {
776  break;
777  }
778  case MemoryResource:
779  {
780  resource=resource_info.memory_limit;
781  break;
782  }
783  case MapResource:
784  {
785  resource=resource_info.map_limit;
786  break;
787  }
788  case ThreadResource:
789  {
790  resource=resource_info.thread_limit;
791  break;
792  }
793  case ThrottleResource:
794  {
795  resource=resource_info.throttle_limit;
796  break;
797  }
798  case TimeResource:
799  {
800  resource=resource_info.time_limit;
801  break;
802  }
803  case WidthResource:
804  {
805  resource=resource_info.width_limit;
806  break;
807  }
808  default:
809  break;
810  }
811  return(resource);
812 }
813 
814 /*
815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816 % %
817 % %
818 % %
819 % L i s t M a g i c k R e s o u r c e I n f o %
820 % %
821 % %
822 % %
823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 %
825 % ListMagickResourceInfo() lists the resource info to a file.
826 %
827 % The format of the ListMagickResourceInfo method is:
828 %
829 % MagickBooleanType ListMagickResourceInfo(FILE *file,
830 % ExceptionInfo *exception)
831 %
832 % A description of each parameter follows.
833 %
834 % o file: An pointer to a FILE.
835 %
836 % o exception: return any errors or warnings in this structure.
837 %
838 */
840  ExceptionInfo *magick_unused(exception))
841 {
842  char
843  area_limit[MagickFormatExtent],
844  disk_limit[MagickFormatExtent],
845  height_limit[MagickFormatExtent],
846  map_limit[MagickFormatExtent],
847  memory_limit[MagickFormatExtent],
848  time_limit[MagickFormatExtent],
849  width_limit[MagickFormatExtent];
850 
851  magick_unreferenced(exception);
852 
853  if (file == (const FILE *) NULL)
854  file=stdout;
855  if (resource_semaphore == (SemaphoreInfo *) NULL)
859  MagickFormatExtent,width_limit);
861  MagickFormatExtent,height_limit);
863  MagickFormatExtent,area_limit);
865  MagickFormatExtent,memory_limit);
867  MagickFormatExtent,map_limit);
868  (void) CopyMagickString(disk_limit,"unlimited",MagickFormatExtent);
871  MagickFormatExtent,disk_limit);
872  (void) CopyMagickString(time_limit,"unlimited",MagickFormatExtent);
874  (void) FormatLocaleString(time_limit,MagickFormatExtent,"%.20g",(double)
876  (void) FormatLocaleFile(file,"Resource limits:\n");
877  (void) FormatLocaleFile(file," Width: %s\n",width_limit);
878  (void) FormatLocaleFile(file," Height: %s\n",height_limit);
879  (void) FormatLocaleFile(file," List length: %.20g\n",(double)
881  (void) FormatLocaleFile(file," Area: %s\n",area_limit);
882  (void) FormatLocaleFile(file," Memory: %s\n",memory_limit);
883  (void) FormatLocaleFile(file," Map: %s\n",map_limit);
884  (void) FormatLocaleFile(file," Disk: %s\n",disk_limit);
885  (void) FormatLocaleFile(file," File: %.20g\n",(double) ((MagickOffsetType)
887  (void) FormatLocaleFile(file," Thread: %.20g\n",(double) ((MagickOffsetType)
889  (void) FormatLocaleFile(file," Throttle: %.20g\n",(double)
891  (void) FormatLocaleFile(file," Time: %s\n",time_limit);
892  (void) fflush(file);
894  return(MagickTrue);
895 }
896 
897 /*
898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
899 % %
900 % %
901 % %
902 % R e l i n q u i s h M a g i c k R e s o u r c e %
903 % %
904 % %
905 % %
906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
907 %
908 % RelinquishMagickResource() relinquishes resources of the specified type.
909 %
910 % The format of the RelinquishMagickResource() method is:
911 %
912 % void RelinquishMagickResource(const ResourceType type,
913 % const MagickSizeType size)
914 %
915 % A description of each parameter follows:
916 %
917 % o type: the type of resource.
918 %
919 % o size: the size of the resource.
920 %
921 */
923  const MagickSizeType size)
924 {
926  bi;
927 
929  current,
930  limit;
931 
932  switch (type)
933  {
934  case AreaResource:
935  case HeightResource:
936  case ListLengthResource:
937  case ThreadResource:
938  case ThrottleResource:
939  case WidthResource:
940  return;
941  default:
942  break;
943  }
944  bi=MagickFalse;
945  limit=0;
946  if (resource_semaphore == (SemaphoreInfo *) NULL)
949  switch (type)
950  {
951  case DiskResource:
952  {
953  bi=MagickTrue;
954  resource_info.disk-=size;
957  assert(resource_info.disk >= 0);
958  break;
959  }
960  case FileResource:
961  {
962  resource_info.file-=size;
965  assert(resource_info.file >= 0);
966  break;
967  }
968  case MapResource:
969  {
970  bi=MagickTrue;
971  resource_info.map-=size;
972  current=(MagickSizeType) resource_info.map;
973  limit=resource_info.map_limit;
974  assert(resource_info.map >= 0);
975  break;
976  }
977  case MemoryResource:
978  {
979  bi=MagickTrue;
980  resource_info.memory-=size;
983  assert(resource_info.memory >= 0);
984  break;
985  }
986  case TimeResource:
987  {
988  bi=MagickTrue;
989  resource_info.time-=size;
992  assert(resource_info.time >= 0);
993  break;
994  }
995  default:
996  {
997  current=0;
998  break;
999  }
1000  }
1002  if (IsEventLogging() != MagickFalse)
1003  {
1004  char
1005  resource_current[MagickFormatExtent],
1006  resource_limit[MagickFormatExtent],
1007  resource_request[MagickFormatExtent];
1008 
1009  (void) FormatMagickSize(size,bi,(bi != MagickFalse) ? "B" :
1010  (const char *) NULL,MagickFormatExtent,resource_request);
1011  (void) FormatMagickSize(current,bi,(bi != MagickFalse) ? "B" :
1012  (const char *) NULL,MagickFormatExtent,resource_current);
1013  (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ? "B" :
1014  (const char *) NULL,MagickFormatExtent,resource_limit);
1015  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
1017  resource_request,resource_current,resource_limit);
1018  }
1019 }
1020 
1021 /*
1022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1023 % %
1024 % %
1025 % %
1026 % R e l i n q u i s h U n i q u e F i l e R e s o u r c e %
1027 % %
1028 % %
1029 % %
1030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031 %
1032 % RelinquishUniqueFileResource() relinquishes a unique file resource.
1033 %
1034 % The format of the RelinquishUniqueFileResource() method is:
1035 %
1036 % MagickBooleanType RelinquishUniqueFileResource(const char *path)
1037 %
1038 % A description of each parameter follows:
1039 %
1040 % o name: the name of the temporary resource.
1041 %
1042 */
1044 {
1045  char
1046  cache_path[MagickPathExtent];
1047 
1049  status;
1050 
1051  assert(path != (const char *) NULL);
1052  status=MagickFalse;
1053  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
1054  if (resource_semaphore == (SemaphoreInfo *) NULL)
1057  if (temporary_resources != (SplayTreeInfo *) NULL)
1058  status=DeleteNodeFromSplayTree(temporary_resources,(const void *) path);
1060  (void) CopyMagickString(cache_path,path,MagickPathExtent);
1061  AppendImageFormat("cache",cache_path);
1062  if (access_utf8(cache_path,F_OK) == 0)
1063  (void) ShredFile(cache_path);
1064  if (status == MagickFalse)
1065  status=ShredFile(path);
1066  return(status);
1067 }
1068 
1069 /*
1070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1071 % %
1072 % %
1073 % %
1074 + R e s o u r c e C o m p o n e n t G e n e s i s %
1075 % %
1076 % %
1077 % %
1078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079 %
1080 % ResourceComponentGenesis() instantiates the resource component.
1081 %
1082 % The format of the ResourceComponentGenesis method is:
1083 %
1084 % MagickBooleanType ResourceComponentGenesis(void)
1085 %
1086 */
1087 
1089 {
1090  char
1091  *limit;
1092 
1094  memory;
1095 
1096  ssize_t
1097  files,
1098  pages,
1099  pagesize;
1100 
1101  /*
1102  Set Magick resource limits.
1103  */
1104  if (resource_semaphore == (SemaphoreInfo *) NULL)
1107  limit=GetEnvironmentValue("MAGICK_WIDTH_LIMIT");
1108  if (limit != (char *) NULL)
1109  {
1111  100.0));
1112  limit=DestroyString(limit);
1113  }
1115  limit=GetEnvironmentValue("MAGICK_HEIGHT_LIMIT");
1116  if (limit != (char *) NULL)
1117  {
1119  limit,100.0));
1120  limit=DestroyString(limit);
1121  }
1122  pagesize=GetMagickPageSize();
1123  pages=(-1);
1124 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1125  pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1126 #endif
1127  memory=(MagickSizeType) pages*pagesize;
1128  if ((pagesize <= 0) || (pages <= 0))
1129  memory=2048UL*1024UL*1024UL;
1130 #if defined(PixelCacheThreshold)
1131  memory=PixelCacheThreshold;
1132 #endif
1133  (void) SetMagickResourceLimit(AreaResource,2*memory);
1134  limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
1135  if (limit != (char *) NULL)
1136  {
1138  100.0));
1139  limit=DestroyString(limit);
1140  }
1141  (void) SetMagickResourceLimit(MemoryResource,memory);
1142  limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
1143  if (limit != (char *) NULL)
1144  {
1146  limit,100.0));
1147  limit=DestroyString(limit);
1148  }
1149  (void) SetMagickResourceLimit(MapResource,2*memory);
1150  limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
1151  if (limit != (char *) NULL)
1152  {
1154  100.0));
1155  limit=DestroyString(limit);
1156  }
1158  limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
1159  if (limit != (char *) NULL)
1160  {
1162  100.0));
1163  limit=DestroyString(limit);
1164  }
1165  files=(-1);
1166 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1167  files=(ssize_t) sysconf(_SC_OPEN_MAX);
1168 #endif
1169 #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1170  if (files < 0)
1171  {
1172  struct rlimit
1173  resources;
1174 
1175  if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1176  files=(ssize_t) resources.rlim_cur;
1177  }
1178 #endif
1179 #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1180  if (files < 0)
1181  files=(ssize_t) getdtablesize();
1182 #endif
1183  if (files < 0)
1184  files=64;
1186  (3*files/4),64));
1187  limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
1188  if (limit != (char *) NULL)
1189  {
1191  100.0));
1192  limit=DestroyString(limit);
1193  }
1195  limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
1196  if (limit != (char *) NULL)
1197  {
1199  limit,100.0));
1200  limit=DestroyString(limit);
1201  }
1203  limit=GetEnvironmentValue("MAGICK_THROTTLE_LIMIT");
1204  if (limit != (char *) NULL)
1205  {
1207  limit,100.0));
1208  limit=DestroyString(limit);
1209  }
1211  limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
1212  if (limit != (char *) NULL)
1213  {
1215  100.0));
1216  limit=DestroyString(limit);
1217  }
1219  limit=GetEnvironmentValue("MAGICK_LIST_LENGTH_LIMIT");
1220  if (limit != (char *) NULL)
1221  {
1223  StringToMagickSizeType(limit,100.0));
1224  limit=DestroyString(limit);
1225  }
1226  return(MagickTrue);
1227 }
1228 
1229 /*
1230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1231 % %
1232 % %
1233 % %
1234 + R e s o u r c e C o m p o n e n t T e r m i n u s %
1235 % %
1236 % %
1237 % %
1238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1239 %
1240 % ResourceComponentTerminus() destroys the resource component.
1241 %
1242 % The format of the ResourceComponentTerminus() method is:
1243 %
1244 % ResourceComponentTerminus(void)
1245 %
1246 */
1248 {
1249  if (resource_semaphore == (SemaphoreInfo *) NULL)
1252  if (temporary_resources != (SplayTreeInfo *) NULL)
1254  if (random_info != (RandomInfo *) NULL)
1258 }
1259 
1260 /*
1261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262 % %
1263 % %
1264 % %
1265 % S e t M a g i c k R e s o u r c e L i m i t %
1266 % %
1267 % %
1268 % %
1269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1270 %
1271 % SetMagickResourceLimit() sets the limit for a particular resource.
1272 %
1273 % The format of the SetMagickResourceLimit() method is:
1274 %
1275 % MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1276 % const MagickSizeType limit)
1277 %
1278 % A description of each parameter follows:
1279 %
1280 % o type: the type of resource.
1281 %
1282 % o limit: the maximum limit for the resource.
1283 %
1284 */
1286  const MagickSizeType limit)
1287 {
1288  char
1289  *value;
1290 
1292  status;
1293 
1294  status=MagickTrue;
1295  value=(char *) NULL;
1296  switch (type)
1297  {
1298  case AreaResource:
1299  {
1300  value=GetPolicyValue("resource:area");
1301  if (value == (char *) NULL)
1302  resource_info.area_limit=limit;
1303  else
1305  100.0));
1306  break;
1307  }
1308  case DiskResource:
1309  {
1310  value=GetPolicyValue("resource:disk");
1311  if (value == (char *) NULL)
1312  resource_info.disk_limit=limit;
1313  else
1315  100.0));
1316  break;
1317  }
1318  case FileResource:
1319  {
1320  value=GetPolicyValue("resource:file");
1321  if (value == (char *) NULL)
1322  resource_info.file_limit=limit;
1323  else
1325  100.0));
1326  break;
1327  }
1328  case HeightResource:
1329  {
1330  value=GetPolicyValue("resource:height");
1331  if (value == (char *) NULL)
1333  else
1335  value,100.0));
1336  break;
1337  }
1338  case ListLengthResource:
1339  {
1340  value=GetPolicyValue("resource:list-length");
1341  if (value == (char *) NULL)
1343  else
1345  StringToMagickSizeType(value,100.0));
1346  break;
1347  }
1348  case MapResource:
1349  {
1350  value=GetPolicyValue("resource:map");
1351  if (value == (char *) NULL)
1352  resource_info.map_limit=limit;
1353  else
1355  value,100.0));
1356  break;
1357  }
1358  case MemoryResource:
1359  {
1360  value=GetPolicyValue("resource:memory");
1361  if (value == (char *) NULL)
1363  else
1365  value,100.0));
1366  break;
1367  }
1368  case ThreadResource:
1369  {
1370  value=GetPolicyValue("resource:thread");
1371  if (value == (char *) NULL)
1373  else
1375  value,100.0));
1378  else
1379  if (resource_info.thread_limit == 0)
1381  break;
1382  }
1383  case ThrottleResource:
1384  {
1385  value=GetPolicyValue("resource:throttle");
1386  if (value == (char *) NULL)
1388  else
1390  value,100.0));
1391  break;
1392  }
1393  case TimeResource:
1394  {
1395  value=GetPolicyValue("resource:time");
1396  if (value == (char *) NULL)
1397  resource_info.time_limit=limit;
1398  else
1400  100.0));
1402  break;
1403  }
1404  case WidthResource:
1405  {
1406  value=GetPolicyValue("resource:width");
1407  if (value == (char *) NULL)
1408  resource_info.width_limit=limit;
1409  else
1411  100.0));
1412  break;
1413  }
1414  default:
1415  {
1416  status=MagickFalse;
1417  break;
1418  }
1419  }
1420  if (value != (char *) NULL)
1421  value=DestroyString(value);
1422  return(status);
1423 }
MagickExport ssize_t FormatMagickSize(const MagickSizeType size, const MagickBooleanType bi, const char *suffix, const size_t length, char *format)
Definition: string.c:1093
MagickOffsetType map
Definition: resource.c:81
MagickExport MagickBooleanType GetPathAttributes(const char *path, void *attributes)
Definition: utility.c:1165
MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree, const void *key, const void *value)
Definition: splay-tree.c:154
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:450
MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file, ExceptionInfo *magick_unused(exception))
Definition: resource.c:839
static void * DestroyTemporaryResources(void *temporary_resource)
Definition: resource.c:428
#define MagickULLConstant(c)
Definition: magick-type.h:36
struct _ResourceInfo ResourceInfo
MagickOffsetType file
Definition: resource.c:81
static size_t GetOpenMPMaximumThreads(void)
MagickOffsetType thread
Definition: resource.c:81
MagickSizeType height_limit
Definition: resource.c:94
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:192
static ResourceInfo resource_info
Definition: resource.c:114
MagickSizeType map_limit
Definition: resource.c:94
MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
Definition: resource.c:1088
MagickOffsetType memory
Definition: resource.c:81
MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type, const MagickSizeType limit)
Definition: resource.c:1285
MagickOffsetType area
Definition: resource.c:81
#define S_ISDIR(mode)
Definition: studio.h:200
MagickSizeType area_limit
Definition: resource.c:94
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:108
MagickOffsetType time
Definition: resource.c:81
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
Definition: locale.c:504
MagickExport void RelinquishMagickResource(const ResourceType type, const MagickSizeType size)
Definition: resource.c:922
#define O_BINARY
Definition: studio.h:325
MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type, const MagickSizeType size)
Definition: resource.c:173
ssize_t MagickOffsetType
Definition: magick-type.h:127
MagickOffsetType disk
Definition: resource.c:81
MagickExport RandomInfo * DestroyRandomInfo(RandomInfo *random_info)
Definition: random.c:274
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
MagickExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition: string.c:1295
MagickSizeType memory_limit
Definition: resource.c:94
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
Definition: locale.c:409
MagickBooleanType
Definition: magick-type.h:156
#define DirectorySeparator
Definition: studio.h:259
MagickExport int AcquireUniqueFileResource(char *path)
Definition: resource.c:520
MagickPrivate ssize_t GetMagickPageSize(void)
Definition: utility.c:1122
MagickExport const char * CommandOptionToMnemonic(const CommandOption option, const ssize_t type)
Definition: option.c:2676
static SplayTreeInfo * temporary_resources
Definition: resource.c:144
MagickExport StringInfo * DestroyStringInfo(StringInfo *string_info)
Definition: string.c:850
MagickOffsetType list_length
Definition: resource.c:81
MagickSizeType time_limit
Definition: resource.c:94
MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
Definition: resource.c:1043
#define magick_unused(x)
MagickExport SplayTreeInfo * DestroySplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:682
size_t MagickSizeType
Definition: magick-type.h:128
#define MagickPathExtent
MagickOffsetType width
Definition: resource.c:81
MagickExport MagickBooleanType IsEventLogging(void)
Definition: log.c:717
MagickExport SplayTreeInfo * NewSplayTree(int(*compare)(const void *, const void *), void *(*relinquish_key)(void *), void *(*relinquish_value)(void *))
Definition: splay-tree.c:1141
#define O_NOFOLLOW
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1398
static int open_utf8(const char *path, int flags, mode_t mode)
MagickExport RandomInfo * AcquireRandomInfo(void)
Definition: random.c:164
MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
Definition: resource.c:745
MagickExport char * GetEnvironmentValue(const char *name)
Definition: string.c:1262
MagickExport size_t CopyMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:755
MagickPrivate MagickBooleanType ShredFile(const char *)
Definition: utility.c:1806
#define S_MODE
Definition: studio.h:239
#define MagickMax(x, y)
Definition: image-private.h:26
MagickExport void AppendImageFormat(const char *format, char *filename)
Definition: utility.c:281
ResourceType
Definition: resource_.h:25
MagickSizeType throttle_limit
Definition: resource.c:94
MagickPrivate void AsynchronousResourceComponentTerminus(void)
Definition: resource.c:384
#define MagickFormatExtent
#define GetMagickModule()
Definition: log.h:28
MagickExport int CompareSplayTreeString(const void *target, const void *source)
Definition: splay-tree.c:412
MagickExport MagickSizeType GetMagickResource(const ResourceType type)
Definition: resource.c:643
#define MagickResourceInfinity
Definition: resource_.h:41
MagickExport const void * GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:769
unsigned short Quantum
Definition: magick-type.h:82
MagickExport char * DestroyString(char *string)
Definition: string.c:823
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:97
MagickOffsetType throttle
Definition: resource.c:81
static MagickSizeType StringToMagickSizeType(const char *string, const double interval)
static int access_utf8(const char *path, int mode)
MagickSizeType list_length_limit
Definition: resource.c:94
MagickExport MagickBooleanType DeleteNodeFromSplayTree(SplayTreeInfo *splay_tree, const void *key)
Definition: splay-tree.c:603
#define MagickMin(x, y)
Definition: image-private.h:27
MagickExport char * GetPolicyValue(const char *name)
Definition: policy.c:505
MagickSizeType thread_limit
Definition: resource.c:94
MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:1472
static RandomInfo * random_info
Definition: resource.c:111
MagickPrivate void ResetPixelCacheEpoch(void)
#define magick_unreferenced(x)
#define MagickPathTemplate
Definition: resource.c:73
MagickSizeType width_limit
Definition: resource.c:94
MagickExport void * GetImageRegistry(const RegistryType type, const char *key, ExceptionInfo *exception)
Definition: registry.c:187
MagickExport char * CloneString(char **destination, const char *source)
Definition: string.c:286
#define MagickPrivate
#define MagickExport
MagickOffsetType height
Definition: resource.c:81
MagickExport StringInfo * GetRandomKey(RandomInfo *random_info, const size_t length)
Definition: random.c:710
#define TMP_MAX
MagickSizeType file_limit
Definition: resource.c:94
MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
Definition: string.c:1324
MagickSizeType disk_limit
Definition: resource.c:94
MagickExport MagickBooleanType GetPathTemplate(char *path)
Definition: resource.c:435
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:351
MagickExport char * ConstantString(const char *source)
Definition: string.c:700
static SemaphoreInfo * resource_semaphore
Definition: resource.c:141
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:411
MagickPrivate void ResourceComponentTerminus(void)
Definition: resource.c:1247