home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacPerl 5.0.3 / MacPerl Source ƒ / Perl5 / missing.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-27  |  9.8 KB  |  532 lines  |  [TEXT/MPS ]

  1. /* $Header: tyrathect:Development:Perl::RCS:missing.c,v 1.2 1994/05/04 02:12:43 neeri Exp $
  2.  *
  3.  *    Copyright (c) 1991-1994 Matthias Neeracher
  4.  *
  5.  *    You may distribute under the terms of the Perl Artistic License,
  6.  *    as specified in the README file.
  7.  *
  8.  * $Log: missing.c,v $
  9.  * Revision 1.2  1994/05/04  02:12:43  neeri
  10.  * Added gmtime(), enabled utime(), reduced spinning.
  11.  *
  12.  * Revision 1.1  1994/03/01  23:38:17  neeri
  13.  * Initial revision
  14.  *
  15.  */
  16.  
  17. /* NEVER try including perl.h here ! */
  18.  
  19. /* DISPATCH_START */
  20. #define MAC_CONTEXT
  21. #define MP_EXT
  22. #define MP_INIT(x) = x
  23.  
  24. #include <time.h>
  25. #include <stdio.h>
  26. #include <Folders.h>
  27. #include <Events.h>
  28. #include <OSUtils.h>
  29. #include <LowMem.h>
  30. #include <GUSI.h>
  31. #include <TFileSpec.h>
  32. #include <TFileGlob.h>
  33. #include <fp.h>
  34. #include <LowMem.h>
  35.  
  36. #define MEM_SIZE    Size_t
  37.  
  38. #include "config.h"
  39. #include "handy.h"
  40. #include "macish.h"
  41. #include "SubLaunch.h"
  42. /* DISPATCH_END */
  43.  
  44. /* Calls that don't exist on the mac */
  45.  
  46. /* Borrowed from msdos.c
  47.  * Just pretend that everyone is a superuser
  48.  */
  49. /* DISPATCH_START */
  50. #define ROOT_UID    0
  51. #define ROOT_GID    0
  52. int
  53. (getuid)(void)
  54. {
  55.     return ROOT_UID;
  56. }
  57.  
  58. int
  59. (geteuid)(void)
  60. {
  61.     return ROOT_UID;
  62. }
  63.  
  64. int
  65. (getgid)(void)
  66. {
  67.     return ROOT_GID;
  68. }
  69.  
  70. int
  71. (getegid)(void)
  72. {
  73.     return ROOT_GID;
  74. }
  75.  
  76. int
  77. (setuid)(int uid)
  78.     return (uid==ROOT_UID?0:-1);
  79. }
  80.  
  81. int
  82. setgid(int gid)
  83.     return (gid==ROOT_GID?0:-1); 
  84. }
  85.  
  86. #undef execv
  87.  
  88. (execv)()
  89. {
  90.     croak("execv() not implemented on the Macintosh");
  91. }
  92.  
  93. #undef execvp
  94.  
  95. (execvp)()
  96. {
  97.     croak("execvp() not implemented on the Macintosh");
  98. }
  99.  
  100. kill()
  101. {
  102.     croak("kill() not implemented on the Macintosh");
  103. }
  104. /* DISPATCH_END */
  105.  
  106. char **environ;
  107. static    char *    gEnvpool;
  108. extern int StandAlone;
  109.  
  110. char ** init_env(char ** env)
  111. {
  112.     int        envcnt    =    0;
  113.     int        envsize    =    0;
  114.     int        varlen;
  115.     char *    envpool;
  116.     FILE *    envfile    =    0;
  117.     
  118.     for (envcnt = 0; env[envcnt]; envcnt++)    {
  119.         varlen    = strlen(env[envcnt]);
  120.         envsize    +=    varlen+strlen(env[envcnt]+varlen+1)+2;
  121.     }
  122.     
  123.     if (gEnvpool) {
  124.         Safefree(environ);
  125.         Safefree(gEnvpool);
  126.     }
  127.     
  128.     New(50, environ, envcnt+1, char *);
  129.     New(50, gEnvpool, envsize, char);
  130.     
  131.     envpool = gEnvpool;
  132.     for (envcnt = 0; env[envcnt]; envcnt++)    {
  133.         environ[envcnt]     = envpool;
  134.         varlen                = strlen(env[envcnt]);
  135.         strcpy(envpool, env[envcnt]);
  136.         envpool              += varlen+1;
  137.         envpool[-1]            = '=';
  138.         strcpy(envpool, env[envcnt]+varlen+1);
  139.         envpool              += strlen(env[envcnt]+varlen+1)+1;
  140.     }
  141.  
  142.     environ[envcnt] = 0;
  143.     
  144.     return environ;
  145. }    
  146.  
  147. typedef struct PD {
  148.     struct PD *    next;
  149.     FILE *        tempFile;
  150.     FSSpec        pipeFile;
  151.     char *        execute;
  152.     long            status;
  153. } PipeDescr, *PipeDescrPtr;
  154.  
  155. static PipeDescrPtr    pipes        =    nil;
  156. static Boolean            sweeper    =    false;
  157.  
  158. void sweep()
  159. {
  160.     while (pipes)
  161.         my_pclose(pipes->tempFile);
  162.     sweeper = false;
  163. }
  164.  
  165. typedef struct WEPDesc {
  166.     struct WEPDesc *    next;
  167.     const char *                            command;
  168.     EmulationProc                             proc;
  169. } WEPDesc, * WEPDescPtr;
  170.  
  171. static WEPDescPtr         gEmulators[128];
  172. static Boolean            gHasEmulators = false;
  173.  
  174. void AddWriteEmulationProc(const char * command, EmulationProc proc)
  175. {
  176.     WEPDescPtr    wepdesc     = (WEPDescPtr) malloc(sizeof(WEPDesc));
  177.     
  178.     wepdesc->next             =     gEmulators[*command];
  179.     wepdesc->command        =    command;
  180.     wepdesc->proc            =    proc;
  181.     gEmulators[*command]    =    wepdesc;
  182. }
  183.  
  184. EmulationProc FindWriteEmulationProc(char * command, char ** rest)
  185. {
  186.     char *         end;
  187.     WEPDescPtr    queue;
  188.     
  189.     for (end = command; isalnum(*end); ++end);
  190.     
  191.     if (end == command || (*command & 0x80))
  192.         return nil;
  193.     
  194.     for (queue = gEmulators[*command]; queue; queue = queue->next)
  195.         if (!strncmp(command, queue->command, end-command))
  196.             if (!queue->command[end-command]) {
  197.                 while (isspace(*end))
  198.                     ++end;
  199.                 *rest = end;
  200.                 
  201.                 return queue->proc;
  202.             }
  203.     
  204.     return nil;
  205. }
  206.  
  207. static int EmulatePwd(FILE * tempFile, char * command)
  208. {
  209.     char curdir[256];
  210.     
  211.     if (!getcwd(curdir, 256)) 
  212.         return -1;
  213.     
  214.     fprintf(tempFile, "%s\n", curdir);
  215.     
  216.     return 0;
  217. }
  218.  
  219. static int EmulateHostname(FILE * tempFile, char * command)
  220. {
  221.     char curhostname[256];
  222.     
  223.     if (gethostname(curhostname, 256)) 
  224.         return -1;
  225.     
  226.     fprintf(tempFile, "%s\n", curhostname);
  227.     
  228.     return 0;
  229. }
  230.  
  231. static int EmulateGlob(FILE * tempFile, char * command)
  232. {
  233.     char             curbuf[256];
  234.     char *        curcmd;
  235.     Boolean        relativePath;
  236.     int            colonCount;
  237.     FileGlobRef    glob;
  238.     FSSpec         spec;
  239.     FSSpec        curDir;
  240.     
  241.     for (curcmd = curbuf; !isspace(*command); )
  242.         if (!(*curcmd++ = *command++))
  243.             break;
  244.  
  245.     if (!(glob = NewFileGlob(curbuf)))
  246.         return -1;
  247.     
  248.     relativePath = true;
  249.     
  250.     if (curbuf[0] == ':') {
  251.         /* Explicitely relative path, e.g. <:*.c> */
  252.         char     ch;
  253.         
  254.         for (curcmd = curbuf+1; *curcmd == ':'; ++curcmd)
  255.             ;
  256.         
  257.         ch             = *curcmd; 
  258.         *curcmd        = 0;
  259.         Path2FSSpec(curbuf, &curDir);
  260.         *curcmd        = ch;
  261.         colonCount     =    curcmd - curbuf;
  262.     } else if (!strchr(curbuf, ':')) {
  263.         /* Implicitely relative path, e.g. <*.c> */
  264.         colonCount     =     0;
  265.         Path2FSSpec(":", &curDir);
  266.     } else
  267.         relativePath = false;
  268.         
  269.     while (FileGlob2FSSpec(glob, &spec)) {
  270.         if (relativePath) {
  271.             curcmd = FSp2DirRelPath(&spec, &curDir);
  272.             if (colonCount) {
  273.                 int i = colonCount - (*curcmd == ':');
  274.                 while (i--)
  275.                     putc(':', tempFile);
  276.             }
  277.         } else
  278.             curcmd = FSp2FullPath(&spec);
  279.         
  280.         fprintf(tempFile, "%s\n", curcmd);
  281.         NextFileGlob(glob);
  282.     }
  283.     DisposeFileGlob(glob);
  284.     
  285.     return 0;
  286. }
  287.  
  288. FILE * my_popen(char * command, char * mode)
  289. {
  290.     PipeDescrPtr    pipe;
  291.     
  292.     if (!gHasEmulators) {
  293.         gHasEmulators = true;
  294.         AddWriteEmulationProc("pwd", EmulatePwd);
  295.         AddWriteEmulationProc("directory", EmulatePwd);
  296.         AddWriteEmulationProc("Directory", EmulatePwd);
  297.         AddWriteEmulationProc("hostname", EmulateHostname);
  298.         AddWriteEmulationProc("glob", EmulateGlob);
  299.     }
  300.     
  301.     if (!strcmp(command, "-"))
  302.         croak("Implicit fork() on a Mac? No forking chance");
  303.     
  304.     New(666, pipe, 1, PipeDescr);
  305.     
  306.     if (!pipe)
  307.         return NULL;
  308.         
  309.     if (FSpMakeTempFile(&pipe->pipeFile))
  310.         goto failed;
  311.     pipe->execute    =    nil;
  312.     
  313.     switch(*mode)    {
  314.     case 'r':
  315.         {
  316.             /* Ugh ! A hardcoded command  ! */
  317.             EmulationProc proc = FindWriteEmulationProc(command, &command);
  318.             
  319.             if (proc) {
  320.                 if (!(pipe->tempFile    = fopen(FSp2FullPath(&pipe->pipeFile), "w")))
  321.                     goto delete;
  322.                 if (proc(pipe->tempFile, command))
  323.                     goto delete;
  324.                 fclose(pipe->tempFile);
  325.             } else if (SubLaunch(command, nil, &pipe->pipeFile, &pipe->pipeFile, &pipe->status))
  326.                 goto delete;
  327.             
  328.             if (!(pipe->tempFile    = fopen(FSp2FullPath(&pipe->pipeFile), "r")))
  329.                 goto delete;
  330.             break;
  331.         }
  332.     case 'w':
  333.         New(667, pipe->execute, strlen(command)+1, char);
  334.         if (!pipe->execute || !(pipe->tempFile    = fopen(FSp2FullPath(&pipe->pipeFile), "w")))
  335.             goto delete;
  336.         strcpy(pipe->execute, command);
  337.         break;
  338.     }
  339.     
  340.     pipe->next    =    pipes;
  341.     pipes            =    pipe;
  342.     
  343.     if (!sweeper)    {
  344.         atexit(sweep);
  345.         sweeper    =    true;
  346.     }
  347.  
  348.     return pipe->tempFile;
  349. delete:
  350.     if (pipe->execute)
  351.         Safefree(pipe->execute);
  352.     HDelete(pipe->pipeFile.vRefNum, pipe->pipeFile.parID, pipe->pipeFile.name);
  353. failed:
  354.     Safefree(pipe);
  355.     
  356.     return NULL;
  357. }
  358.  
  359. int my_pclose(FILE *    f)
  360. {
  361.     OSErr                err;
  362.     PipeDescrPtr *    prev;
  363.     PipeDescrPtr    pipe;
  364.     
  365.     for (prev = (PipeDescrPtr *) &pipes; pipe = *prev; prev = &pipe->next)
  366.         if (pipe->tempFile == f)
  367.             break;
  368.     
  369.     if (!pipe)
  370.         return -1;
  371.     
  372.     *prev = pipe->next;
  373.     
  374.     fclose(f);
  375.     
  376.     if (pipe->execute)
  377.         err = SubLaunch(pipe->execute, &pipe->pipeFile, nil, nil, &pipe->status);
  378.     else
  379.         err = noErr;
  380.         
  381.     HDelete(pipe->pipeFile.vRefNum, pipe->pipeFile.parID, pipe->pipeFile.name);
  382.     if (pipe->execute)
  383.         Safefree(pipe->execute);
  384.     Safefree(pipe);
  385.     
  386.     return err? -1 : (int) pipe->status;    
  387. }
  388.  
  389. void SpinMacCursor()
  390. {
  391.     static long lastSpin = 0;
  392.         
  393.     if (LMGetTicks() - lastSpin < 5)
  394.         return;
  395.         
  396.     lastSpin = LMGetTicks();
  397.         
  398.     (GUSIGetSpin())(SP_AUTO_SPIN, 1);
  399. }
  400.  
  401. /* DISPATCH_START */
  402. struct tm * gmtime(const time_t * timer)
  403. {
  404.     MachineLocation     loc;
  405.     struct tm *            swatch;
  406.     long                    delta;
  407.     time_t                rolex;
  408.     
  409.     ReadLocation(&loc);
  410.     
  411.     if (!loc.latitude && !loc.longitude)
  412.         return localtime(timer);    /* This is incorrect unless you live in Greenwich */
  413.     
  414.     delta = loc.u.gmtDelta & 0xFFFFFF;
  415.     
  416.     if (delta & 0x800000)
  417.         delta = (long) ((unsigned long) delta | 0xFF000000);
  418.         
  419.     rolex = (unsigned long) ((long) *timer - delta);
  420.     
  421.     swatch = localtime(&rolex);
  422.     
  423.     swatch->tm_isdst = (loc.u.dlsDelta & 0x80) != 0;
  424.     
  425.     return swatch;
  426.  }
  427. /* DISPATCH_END */
  428.  
  429. void mac_times(struct tms * t)
  430. {
  431.     t->tms_utime = clock() - gStartClock;
  432.     t->tms_stime = 0;
  433.     t->tms_cutime = 0;
  434.     t->tms_cstime = 0;
  435. }
  436.  
  437. #undef atof
  438.  
  439. double mac_atof(const char * nptr)
  440. {
  441.     /* The Mac returns NaN(17) on undefined strings, which is not acceptable
  442.        for Perl
  443.     */
  444.     double res = atof(nptr);
  445.     
  446.     if (isnan(res) /* This doesn't work: && res == nan("17") */)
  447.         return 0.0;
  448.     else
  449.         return res;
  450. }
  451.  
  452. void CopyC2PStr(char * cstr, StringPtr pstr)
  453. {
  454.     int    len;
  455.     
  456.     for (len = 0; *cstr && len<256; )
  457.         pstr[++len] = *cstr++;
  458.     
  459.     pstr[0] = len;
  460. }
  461.  
  462.  
  463. char * MPWFileName(char * file)
  464. {
  465.     if (!strcmp(file, "Dev:Pseudo"))
  466.         return gPseudoFileName;
  467.     else if (!strncmp(file, "Dev:Pseudo:", 11))
  468.         return file + 11;
  469.     else
  470.         return file;
  471. }
  472.  
  473. char * MPWPosIndication(char * buf, char * file, long line)
  474. {
  475.     file = MPWFileName(file);
  476.  
  477.     if (gFirstErrorLine == -1 && !Path2FSSpec(file, &gFirstErrorFile))
  478.         gFirstErrorLine = line;
  479.     
  480.     strcpy(buf, "File '"); 
  481.     buf += 6;
  482.     
  483.     while (*file) 
  484.         if (*file == '\'') {
  485.         strcpy(buf, "'∂''");
  486.         buf += 3;
  487.         ++file;
  488.     } else
  489.         *buf++ = *file++;
  490.         
  491.     if (buf[-1] == '\'' && buf[-2] == '\'')
  492.         --buf;
  493.     else
  494.         *buf++ = '\'';
  495.  
  496.     return buf + sprintf(buf, "; Line %ld", line);
  497. }
  498.  
  499. int OverrideExtract(char * origname)
  500. {
  501.     char         file[256];
  502.     
  503.     strcpy(file+1, MPWFileName(origname));
  504.     file[0] = strlen(file+1);
  505.     ParamText((StringPtr) file, "\p", "\p", "\p");
  506.     
  507.     return Alert(270, (ModalFilterUPP) nil) == 1;
  508. }
  509.  
  510. #define STACK_INTERVENTION_LIMIT    8192
  511.  
  512. void StackAttack()
  513. {
  514.     if (StackSpace() < STACK_INTERVENTION_LIMIT)
  515.         croak("Stack space getting low ! Aborting script for your own good...\n");
  516. }
  517.  
  518. void mac_initminiperl()
  519. {
  520.     InitGraf((Ptr) &qd.thePort);
  521.     gStartClock      = LMGetTicks();
  522. }
  523.  
  524. /* DISPATCH_START */
  525. pid_t (getpid)()
  526. {
  527.     return 1;
  528. }
  529. /* DISPATCH_END */
  530.