home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / fonts / server / os / utils.c.orig < prev    next >
Encoding:
Text File  |  1991-07-25  |  11.6 KB  |  522 lines

  1. /* $XConsortium: utils.c,v 1.7 91/07/25 12:15:52 keith Exp $ */
  2. /*
  3.  * misc os utilities
  4.  */
  5. /*
  6.  * Copyright 1990, 1991 Network Computing Devices;
  7.  * Portions Copyright 1987 by Digital Equipment Corporation and the
  8.  * Massachusetts Institute of Technology
  9.  *
  10.  * Permission to use, copy, modify, and distribute this protoype software
  11.  * and its documentation to Members and Affiliates of the MIT X Consortium
  12.  * any purpose and without fee is hereby granted, provided
  13.  * that the above copyright notice appear in all copies and that both that
  14.  * copyright notice and this permission notice appear in supporting
  15.  * documentation, and that the names of Network Computing Devices, Digital or
  16.  * MIT not be used in advertising or publicity pertaining to distribution of
  17.  * the software without specific, written prior permission.
  18.  *
  19.  * NETWORK COMPUTING DEVICES, DIGITAL AND MIT DISCLAIM ALL WARRANTIES WITH
  20.  * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  21.  * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, DIGITAL OR MIT BE
  22.  * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  23.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  24.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  25.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  26.  *
  27.  * $NCDId: @(#)utils.c,v 4.9 1991/07/09 14:08:13 lemke Exp $
  28.  *
  29.  */
  30.  
  31. #include    <stdio.h>
  32. #include    <X11/Xos.h>
  33. #include    "misc.h"
  34. #include    "globals.h"
  35.  
  36. #ifndef X_NOT_POSIX
  37. #ifdef _POSIX_SOURCE
  38. #include <limits.h>
  39. #else
  40. #define _POSIX_SOURCE
  41. #include <limits.h>
  42. #undef _POSIX_SOURCE
  43. #endif
  44. #endif /* X_NOT_POSIX */
  45. #ifndef PATH_MAX
  46. #include <sys/param.h>
  47. #ifdef MAXPATHLEN
  48. #define PATH_MAX MAXPATHLEN
  49. #else
  50. #define PATH_MAX 1024
  51. #endif
  52. #endif /* PATH_MAX */
  53.  
  54. #ifdef SIGNALRETURNSINT
  55. #define SIGVAL int
  56. #else
  57. #define SIGVAL void
  58. #endif
  59.  
  60. extern char *configfilename;
  61. char       *progname;
  62. Bool        CloneSelf;
  63. int         ListenSock = -1;
  64. extern int  ListenPort;
  65.  
  66. SIGVAL
  67. AutoResetServer()
  68. {
  69.  
  70. #ifdef DEBUG
  71.     fprintf(stderr, "got a reset signal\n");
  72. #endif
  73.  
  74.     dispatchException |= DE_RESET;
  75.     isItTimeToYield = TRUE;
  76. }
  77.  
  78. SIGVAL
  79. GiveUp()
  80. {
  81.  
  82. #ifdef DEBUG
  83.     fprintf(stderr, "got a TERM signal\n");
  84. #endif
  85.  
  86.     dispatchException |= DE_TERMINATE;
  87.     isItTimeToYield = TRUE;
  88. }
  89.  
  90. SIGVAL
  91. ServerReconfig()
  92. {
  93.  
  94. #ifdef DEBUG
  95.     fprintf(stderr, "got a re-config signal\n");
  96. #endif
  97.  
  98.     dispatchException |= DE_RECONFIG;
  99.     isItTimeToYield = TRUE;
  100. }
  101.  
  102. SIGVAL
  103. ServerCacheFlush()
  104. {
  105.  
  106. #ifdef DEBUG
  107.     fprintf(stderr, "got a flush signal\n");
  108. #endif
  109.  
  110.     dispatchException |= DE_FLUSH;
  111.     isItTimeToYield = TRUE;
  112. }
  113.  
  114. long
  115. GetTimeInMillis()
  116. {
  117.     struct timeval tp;
  118.  
  119.     gettimeofday(&tp, 0);
  120.     return ((tp.tv_sec * 1000) + (tp.tv_usec / 1000));
  121. }
  122.  
  123. static void
  124. usage()
  125. {
  126.     fprintf(stderr, "%s: [-cf config-file] [-p tcp_port] [-s server_number]\n", progname);
  127.     exit(-1);
  128. }
  129.  
  130. /* ARGSUSED */
  131. void
  132. ProcessCmdLine(argc, argv)
  133.     int         argc;
  134.     char      **argv;
  135. {
  136.     int         i;
  137.  
  138. #ifdef MEMBUG
  139.     {
  140.     extern pointer MemoryAllocationBase;
  141.  
  142.     if (!MemoryAllocationBase)
  143.         MemoryAllocationBase = (pointer) sbrk(0);
  144.     }
  145. #endif
  146.  
  147.     progname = argv[0];
  148.     for (i = 1; i < argc; i++) {
  149.     if (!strcmp(argv[i], "-port")) {
  150.         if (argv[i + 1])
  151.         ListenPort = atoi(argv[++i]);
  152.         else
  153.         usage();
  154.     } else if (!strcmp(argv[i], "-ls")) {
  155.         if (argv[i + 1])
  156.         ListenSock = atoi(argv[++i]);
  157.         else
  158.         usage();
  159.     } else if (!strcmp(argv[i], "-cf") || !strcmp(argv[i], "-config")) {
  160.         if (argv[i + 1])
  161.         configfilename = argv[++i];
  162.         else
  163.         usage();
  164.     }
  165. #ifdef MEMBUG
  166.     else if ( strcmp( argv[i], "-alloc") == 0)
  167.     {
  168.         extern unsigned long    MemoryFail;
  169.         if(++i < argc)
  170.             MemoryFail = atoi(argv[i]);
  171.         else
  172.         usage ();
  173.     }
  174.     else if ( strcmp ( argv[i], "validateMemory") == 0)
  175.     {
  176.         extern unsigned long MemoryValidate;
  177.         MemoryValidate = 1;
  178.     }
  179.     else if ( strcmp ( argv[i], "neverFreeMemory") == 0)
  180.     {
  181.         extern unsigned long MemoryNeverFree;
  182.         MemoryNeverFree = 1;
  183.     }
  184. #endif
  185.     else
  186.         usage();
  187.     }
  188. }
  189.  
  190.  
  191. #ifndef SPECIAL_MALLOC
  192.  
  193. unsigned long    Must_have_memory;
  194.  
  195. #ifdef MEMBUG
  196. #define FIRSTMAGIC 0x11aaaa11
  197. #define SECONDMAGIC 0x22aaaa22
  198. #define FREEDMAGIC  0x33aaaa33
  199. #define BLANKMAGIC  0x44aaaa44
  200. #define ALLOCMAGIC  0x55aaaa55
  201. #define MEM_FAIL_SCALE    100000
  202.  
  203. typedef struct _MallocHeader    *MallocHeaderPtr;
  204.  
  205. typedef struct _MallocHeader {
  206.     unsigned long    amount;
  207.     unsigned long    time;
  208.     MallocHeaderPtr    prev;
  209.     MallocHeaderPtr    next;
  210.     unsigned long    magic;
  211. } MallocHeaderRec;
  212.  
  213. typedef struct _MallocTrailer {
  214.     unsigned long    magic;
  215. } MallocTrailerRec, *MallocTrailerPtr;
  216.  
  217. unsigned long    MemoryAllocTime;
  218. unsigned long    MemoryAllocBreakpoint = ~0;
  219. unsigned long    MemoryFreeBreakpoint = ~0;
  220. unsigned long    MemoryActive = 0;
  221. unsigned long    MemoryValidate;
  222. unsigned long    MemoryNeverFree;
  223. unsigned long    MemoryFail;
  224. pointer        MemoryAllocationBase = NULL;
  225.  
  226. static void    CheckNode ();
  227.  
  228. MallocHeaderPtr    MemoryInUse;
  229. MallocHeaderPtr    MemoryFreed;
  230.  
  231. #define request(amount)    ((amount) + sizeof (MallocHeaderRec) + sizeof (MallocTrailerRec))
  232. #define Header(ptr)    ((MallocHeaderPtr) (((char *) ptr) - sizeof (MallocHeaderRec)))
  233. #define Trailer(ptr)    ((MallocTrailerPtr) (((char *) ptr) + Header(ptr)->amount))
  234.  
  235. static unsigned long *
  236. SetupBlock(ptr, amount)
  237.     unsigned long   *ptr;
  238. {
  239.     MallocHeaderPtr    head = (MallocHeaderPtr) ptr;
  240.     MallocTrailerPtr    tail = (MallocTrailerPtr) (((char *) ptr) + amount + sizeof (MallocHeaderRec));
  241.  
  242.     MemoryActive += amount;
  243.     head->magic = FIRSTMAGIC;
  244.     head->amount = amount;
  245.     if (MemoryAllocTime == MemoryAllocBreakpoint)
  246.     head->amount = amount;
  247.     head->time = MemoryAllocTime++;
  248.     head->next = MemoryInUse;
  249.     head->prev = 0;
  250.     if (MemoryInUse)
  251.     MemoryInUse->prev = head;
  252.     MemoryInUse = head;
  253.  
  254.     tail->magic = SECONDMAGIC;
  255.     
  256.     return (unsigned long *)(((char *) ptr) + sizeof (MallocHeaderRec));
  257. }
  258.  
  259. ValidateAllActiveMemory ()
  260. {
  261.     MallocHeaderPtr    head;
  262.     MallocTrailerPtr    tail;
  263.  
  264.     for (head = MemoryInUse; head; head = head->next)
  265.     {
  266.     tail = (MallocTrailerPtr) (((char *) (head + 1)) + head->amount);
  267.         if (head->magic == FREEDMAGIC)
  268.         FatalError("Free data on active list");
  269.         if(head->magic != FIRSTMAGIC || tail->magic != SECONDMAGIC)
  270.         FatalError("Garbage object on active list");
  271.     }
  272.     for (head = MemoryFreed; head; head = head->next)
  273.     {
  274.     tail = (MallocTrailerPtr) (((char *) (head + 1)) + head->amount);
  275.     if (head->magic != FREEDMAGIC || tail->magic != FREEDMAGIC)
  276.         FatalError("Non free data on free list");
  277.     if (!CheckMemoryContents (head, BLANKMAGIC))
  278.         FatalError("Freed data reused");
  279.     }
  280. }
  281.  
  282. FillMemoryContents (head, value)
  283.     MallocHeaderPtr head;
  284.     long        value;
  285. {
  286.     int            count;
  287.     long        *store;
  288.  
  289.     count = head->amount / sizeof (long);
  290.     store = (long *) (head + 1);
  291.     while (count--)
  292.     *store++ = value;
  293. }
  294.  
  295. CheckMemoryContents (head, value)
  296.     MallocHeaderPtr head;
  297.     long        value;
  298. {
  299.     int            count;
  300.     long        *check;
  301.  
  302.     count = head->amount / sizeof (long);
  303.     check = (long *) (head + 1);
  304.     while (count--)
  305.     if (*check++ != value)
  306.         return FALSE;
  307.     return TRUE;
  308. }
  309.  
  310. #endif
  311.  
  312. /* FSalloc -- FS's internal memory allocator.  Why does it return unsigned
  313.  * int * instead of the more common char *?  Well, if you read K&R you'll
  314.  * see they say that alloc must return a pointer "suitable for conversion"
  315.  * to whatever type you really want.  In a full-blown generic allocator
  316.  * there's no way to solve the alignment problems without potentially
  317.  * wasting lots of space.  But we have a more limited problem. We know
  318.  * we're only ever returning pointers to structures which will have to
  319.  * be long word aligned.  So we are making a stronger guarantee.  It might
  320.  * have made sense to make FSalloc return char * to conform with people's
  321.  * expectations of malloc, but this makes lint happier.
  322.  */
  323.  
  324. unsigned long * 
  325. FSalloc (amount)
  326.     unsigned long amount;
  327. {
  328.     char        *malloc();
  329.     register pointer  ptr;
  330.     
  331.     if ((long)amount < 0)
  332.     return (unsigned long *)NULL;
  333.     if (amount == 0)
  334.     amount++;
  335.     /* aligned extra on long word boundary */
  336.     amount = (amount + 3) & ~3;
  337. #ifdef MEMBUG
  338.     if (MemoryValidate)
  339.     ValidateAllActiveMemory ();
  340.     if (!Must_have_memory && MemoryFail &&
  341.     ((random() % MEM_FAIL_SCALE) < MemoryFail))
  342.     return (unsigned long *)NULL;
  343.     if (ptr = (pointer)malloc(request(amount)))
  344.     {
  345.     unsigned long    *ret;
  346.     ret = SetupBlock (ptr, amount);
  347.     FillMemoryContents ((MallocHeaderPtr) ptr, ALLOCMAGIC);
  348.     return ret;
  349.     }
  350. #else
  351.     if (ptr = (pointer)malloc(amount))
  352.     return (unsigned long *)ptr;
  353. #endif
  354.     if (Must_have_memory)
  355.     FatalError("Out of memory");
  356.     return (unsigned long *)NULL;
  357. }
  358.  
  359. /*****************
  360.  * FScalloc
  361.  *****************/
  362.  
  363. unsigned long *
  364. FScalloc (amount)
  365.     unsigned long   amount;
  366. {
  367.     unsigned long   *ret;
  368.  
  369.     ret = FSalloc (amount);
  370.     if (ret)
  371.     bzero ((char *) ret, (int) amount);
  372.     return ret;
  373. }
  374.  
  375. /*****************
  376.  * FSrealloc
  377.  *****************/
  378.  
  379. unsigned long *
  380. FSrealloc (ptr, amount)
  381.     register pointer ptr;
  382.     unsigned long amount;
  383. {
  384.     char *malloc();
  385.     char *realloc();
  386.  
  387. #ifdef MEMBUG
  388.     if (ptr)
  389.     {
  390.         if (MemoryValidate)
  391.         ValidateAllActiveMemory ();
  392.         if ((long)amount <= 0)
  393.         {
  394.         if (!amount)
  395.             FSfree(ptr);
  396.         return (unsigned long *)NULL;
  397.         }
  398.         if (!Must_have_memory && MemoryFail &&
  399.         ((random() % MEM_FAIL_SCALE) < MemoryFail))
  400.         return (unsigned long *)NULL;
  401.         amount = (amount + 3) & ~3;
  402.     CheckNode(ptr);
  403.     ptr = (pointer)realloc((char *) Header (ptr), request(amount));
  404.     if (ptr)
  405.         return SetupBlock (ptr, amount);
  406.     }
  407.     else
  408.     {
  409.     return FSalloc (amount);
  410.     }
  411. #else
  412.     if ((long)amount <= 0)
  413.     {
  414.     if (ptr && !amount)
  415.         free(ptr);
  416.     return (unsigned long *)NULL;
  417.     }
  418.     amount = (amount + 3) & ~3;
  419.     if (ptr)
  420.         ptr = (pointer)realloc((char *)ptr, amount);
  421.     else
  422.     ptr = (pointer)malloc(amount);
  423.     if (ptr)
  424.         return (unsigned long *)ptr;
  425. #endif
  426.     if (Must_have_memory)
  427.     FatalError("Out of memory");
  428.     return (unsigned long *)NULL;
  429. }
  430.                     
  431. /*****************
  432.  *  FSfree
  433.  *    calls free 
  434.  *****************/    
  435.  
  436. void
  437. FSfree(ptr)
  438.     register pointer ptr;
  439. {
  440. #ifdef MEMBUG
  441.     if (MemoryValidate)
  442.     ValidateAllActiveMemory ();
  443.     if (ptr)
  444.     {
  445.     MallocHeaderPtr        head;
  446.     MallocTrailerPtr    trail;
  447.  
  448.     CheckNode(ptr);
  449.     head = Header(ptr);
  450.     trail = Trailer(ptr);
  451.     if (head->time == MemoryFreeBreakpoint)
  452.         head->magic = FIRSTMAGIC;
  453.     head->magic = FREEDMAGIC;
  454.     trail->magic = FREEDMAGIC;
  455.     FillMemoryContents (head, BLANKMAGIC);
  456.     if (MemoryNeverFree)
  457.     {
  458.         head->prev = 0;
  459.         head->next = MemoryFreed;
  460.         MemoryFreed = head;
  461.     }
  462.     else
  463.         free ((char *) head);
  464.     }
  465. #else
  466.     if (ptr)
  467.     free((char *)ptr); 
  468. #endif
  469. }
  470.  
  471. #ifdef MEMBUG
  472. static void
  473. CheckNode(ptr)
  474.     pointer ptr;
  475. {
  476.     MallocHeaderPtr    head;
  477.     MallocHeaderPtr    f, prev;
  478.  
  479.     if (ptr < MemoryAllocationBase)
  480.     FatalError("Trying to free static storage");
  481.     head = Header(ptr);
  482.     if (((pointer) head) < MemoryAllocationBase)
  483.     FatalError("Trying to free static storage");
  484.     if (head->magic == FREEDMAGIC)
  485.     FatalError("Freeing something already freed");
  486.     if(head->magic != FIRSTMAGIC || Trailer(ptr)->magic != SECONDMAGIC)
  487.     FatalError("Freeing a garbage object");
  488.     if(head->prev)
  489.     head->prev->next = head->next;
  490.     else
  491.     MemoryInUse = head->next;
  492.     if (head->next)
  493.     head->next->prev = head->prev;
  494.     MemoryActive -= head->amount;
  495. }
  496.  
  497. DumpMemoryInUse (time)
  498.     unsigned long   time;
  499. {
  500.     MallocHeaderPtr    head;
  501.  
  502.     for (head = MemoryInUse; head; head = head->next)
  503.     if (head->time >= time)
  504.         fprintf (stderr, "0x%08x %5d %6d\n", head,
  505.                     head->amount,
  506.                     head->time);
  507. }
  508.  
  509. static unsigned long    MarkedTime;
  510.  
  511. MarkMemoryTime ()
  512. {
  513.     MarkedTime = MemoryAllocTime;
  514. }
  515.  
  516. DumpMemorySince ()
  517. {
  518.     DumpMemoryInUse (MarkedTime);
  519. }
  520. #endif
  521. #endif /* SPECIAL_MALLOC */
  522.