home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / unix / unixlib_1 / !UnixLib37_src_unix_c_unix < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-09  |  10.0 KB  |  505 lines

  1. /****************************************************************************
  2.  *
  3.  * $Source: /unixb/home/unixlib/source/unixlib37/src/unix/c/RCS/unix,v $
  4.  * $Date: 1996/11/06 22:01:42 $
  5.  * $Revision: 1.6 $
  6.  * $State: Rel $
  7.  * $Author: unixlib $
  8.  *
  9.  * $Log: unix,v $
  10.  * Revision 1.6  1996/11/06 22:01:42  unixlib
  11.  * Yet more changes by NB, PB and SC.
  12.  *
  13.  * Revision 1.5  1996/10/30 22:04:51  unixlib
  14.  * Massive changes made by Nick Burret and Peter Burwood.
  15.  *
  16.  * Revision 1.4  1996/07/21 22:12:31  unixlib
  17.  * CL_0001 Nick Burret
  18.  * Improve memory handling. Remove C++ library incompatibilities.
  19.  * Improve file stat routines.
  20.  *
  21.  * Revision 1.3  1996/05/06 18:56:11  unixlib
  22.  * Remove declaration of unused variable.
  23.  *
  24.  * Revision 1.2  1996/05/06 09:01:35  unixlib
  25.  * Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
  26.  * Saved for 3.7a release.
  27.  *
  28.  * Revision 1.1  1996/04/19 21:35:27  simon
  29.  * Initial revision
  30.  *
  31.  ***************************************************************************/
  32.  
  33. static const char rcs_id[] = "$Id: unix,v 1.6 1996/11/06 22:01:42 unixlib Rel $";
  34.  
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <errno.h>
  38. #include <ctype.h>
  39. #include <limits.h>
  40.  
  41. #include <fcntl.h>
  42. #include <termio.h>
  43. #include <unistd.h>
  44.  
  45. #include <sys/types.h>
  46. #include <sys/dev.h>
  47. #include <sys/os.h>
  48. #include <sys/unix.h>
  49. #include <sys/syslib.h>
  50. #include <sys/param.h>
  51. #include <sys/debug.h>
  52. #include <sys/swis.h>
  53.  
  54. struct sdir __sdir[MAXSDIR];    /* special directory list */
  55.  
  56. char *__sfix[MAXSFIX];        /* special suffix list */
  57.  
  58. static void __initialise_proc (struct proc *);
  59.  
  60. static void
  61. __sdirinit (void)
  62. {
  63.   int r[10];
  64.   char buf[256];
  65.  
  66.   _kernel_oserror *e = 0;
  67.   int i;
  68.   int tmp_found = 0;
  69.  
  70.   r[1] = (int) buf;
  71.   r[3] = 0;
  72.  
  73.   for (i = 0; i < MAXSDIR;)
  74.     {
  75.       register char *s1, *s2;
  76.  
  77.       r[0] = (int) "UnixFS$/*";
  78.       /* One less than buf size so can zero terminate below.  */
  79.       r[2] = sizeof (buf) - 1;
  80.       r[4] = 3;
  81.  
  82.       if (e = os_swi (OS_ReadVarVal, r))
  83.     break;
  84.  
  85.       buf[r[2]] = 0;
  86.  
  87.       s1 = (char *) r[3] + 8;
  88.       if (!*s1)
  89.     continue;
  90.  
  91.       if (!(s2 = __permstr (s1)))
  92.     break;
  93.       __sdir[i].name = s2;
  94.  
  95.       if (!(s2 = __permstr (buf)))
  96.     break;
  97.       __sdir[i].riscos_name = s2;
  98.  
  99.       if (stricmp (__sdir[i].name, "tmp") == 0)
  100.     tmp_found = 1;
  101.  
  102.       i++;
  103.     }
  104.  
  105.   if (!tmp_found && (i < MAXSDIR))
  106.     {
  107.       __sdir[i].name = "tmp";
  108.       __sdir[i].riscos_name = "<Wimp$ScrapDir>";
  109.       i++;
  110.     }
  111.  
  112.   if (i < MAXSDIR)
  113.     __sdir[i].name = 0;        /* terminate list */
  114. }
  115.  
  116. static void
  117. __panic (char *s)
  118. {
  119.   s = s ? s : sys_errlist[errno];
  120.   os_print ("\r\n");
  121.   os_print (s);
  122.   os_print ("\r\n\n");
  123.   _exit (1);
  124. }
  125.  
  126. static void
  127. __badr (void)
  128. {
  129.   __panic ("Bad redirection");
  130. }
  131.  
  132. void
  133. __unixlib_fatal (char *s)
  134. {
  135.   __panic (s);
  136. }
  137.  
  138. void
  139. __unixinit (void)
  140. {
  141.   int i, j;
  142.   char cli[MAXCOMMANDLEN];
  143.   int r[10];
  144.   char *s1, *s2, *tty;
  145.  
  146.   __u = 0;            /* trap early exits */
  147.  
  148.   __svccli (cli);        /* copy __cli in SVC mode */
  149.  
  150.   /* if DDE Utils is present then copy in the extra command line */
  151.   if (!os_swi (DDEUtils_GetCLSize, r) && (r[0] != 0))
  152.     {
  153.       int len = strlen (cli);
  154.       if (len + r[0] + 2 > MAXCOMMANDLEN)    /* command line too long */
  155.     {
  156.       errno = -1;
  157.       __panic ("command line far too long");
  158.     }
  159.       else
  160.     {
  161.       /* command line will fit, append it to cli. */
  162.       cli[len] = ' ';
  163.       r[0] = (int) cli + len + 1;
  164.       os_swi (DDEUtils_GetCl, r);
  165.       /* set length to zero */
  166.       r[0] = 0;
  167.       os_swi (DDEUtils_SetCLSize, r);
  168.     }
  169.     }
  170.  
  171.   __envcnt = 0, __envsiz = 1;
  172.  
  173.   if (!(environ = malloc (sizeof (char *))))
  174.       __panic (0);
  175.   *environ = 0;
  176.  
  177.   if (__u = (struct proc *) __intenv ("UnixLib$env", 0))
  178.     {
  179.       /* Check the consistency of UnixLib$env. If a process previously
  180.          exited through a serious crash, it could be that UnixLib$env
  181.          is still set and points to some invalid proc structure.  If it
  182.          is invalid, we are probably the parent process, so just set
  183.          the proc struct to zero and re-create.  */
  184.       if (__u->__magic == _PROCMAGIC)
  185.     {
  186. #ifdef DEBUG
  187.       __debug ("__unixinit() (test)");
  188. #endif
  189.       s1 = cli;
  190.       s2 = __u->argb;
  191.  
  192.       while (*s2)
  193.         if (*s1++ != *s2++)
  194.           {
  195.         __u = 0;
  196.         break;
  197.           }
  198.     }
  199.       else
  200.     __u = 0;
  201.  
  202.       r[0] = (int) "UnixLib$env";
  203.       r[1] = r[3] = r[4] = 0;
  204.       r[2] = -1;
  205.       os_swi (OS_SetVarVal, r);
  206.     }
  207.  
  208.   __sdirinit ();
  209.  
  210.   /* Sort out the suffixes list.  */
  211.   if (!(s1 = s2 = __getenv ("UnixFS$sfix", 0)))
  212.     s1 = s2 = "a:c:cc:f:h:i:l:o:p:s:y";
  213.   for (i = 0; i < MAXSFIX;)
  214.     {
  215.       while ((j = *s2) && j != ':')
  216.     s2++;
  217.       if (j && s1 == s2)
  218.     {
  219.       s1++, s2++;
  220.       continue;
  221.     }
  222.       __sfix[i++] = s1;
  223.       if (!j)
  224.     break;
  225.       *s2++ = 0;
  226.       s1 = s2;
  227.     }
  228.   if (i < MAXSFIX)
  229.     __sfix[i] = 0;        /* terminate list */
  230.  
  231.   /* No process structure exists, so lets create one. */
  232.   if (!__u)
  233.     {
  234.       int argc;
  235.       char **argv;
  236.       char *ifile = 0, *ofile = 0;
  237.       int ioflag = 0;
  238.  
  239.       if (!(__u = calloc (1, sizeof (struct proc))))
  240.       __panic (0);
  241.       if (!(__u->tty = calloc (MAXTTY, sizeof (struct tty))))
  242.       __panic (0);
  243. #ifndef __TTY_STATIC_BUFS
  244.       /* While not strictly necessary to allocate the del buffer here,
  245.          it helps when we need to print a fatal message due to lack
  246.          of memory during a later part of the initialisation of Unixlib.  */
  247.       for (i = 0; i < MAXTTY; i++)
  248.     {
  249.       if (!(__u->tty[i].del = malloc (MAXPATHLEN)))
  250.         __panic (0);
  251.     }
  252. #endif
  253.       if (!(argv = malloc (sizeof (int) * (MAXCOMMANDLEN >> 2))))
  254.       __panic (0);
  255.       if (!(*argv = malloc (MAXCOMMANDLEN)))
  256.     __panic (0);
  257.  
  258.       /* Set the magic word for our new process structure. We will use
  259.          this when checking the validity of the pointer specified by
  260.          UnixLib$env.  */
  261.       __u->__magic = _PROCMAGIC;
  262.       argc = 0;
  263.       s1 = cli;
  264.       s2 = *argv;
  265.  
  266.       while (*s1 && argc < (MAXCOMMANDLEN >> 2))
  267.     {
  268.       while ((i = *s1) && isspace (i))
  269.         s1++;
  270.  
  271.       if (!i)
  272.         break;
  273.       if (argc && i == '>')
  274.         {
  275.         outfile:
  276.           if (*++s1 == '>')
  277.         ++s1, ioflag |= 1;
  278.           if (*s1 == '&')
  279.         ++s1, ioflag |= 2;
  280.           while ((i = *s1) && isspace (i))
  281.         s1++;
  282.           if (i)
  283.         ofile = s1;
  284.           else
  285.         __badr ();
  286.           while ((i = *s1) && !isspace (i) && i != '>' && i != '<')
  287.         s1++;
  288.           if (i == '<')
  289.         {
  290.           *s1 = 0;
  291.           goto infile;
  292.         }
  293.           if (i == '>')
  294.         __badr ();
  295.           if (i)
  296.         *s1++ = 0;
  297.           continue;
  298.         }
  299.       if (argc && i == '<')
  300.         {
  301.         infile:
  302.           if (*++s1 == '<')
  303.         __badr ();
  304.           while ((i = *s1) && isspace (i))
  305.         s1++;
  306.           if (i)
  307.         ifile = s1;
  308.           else
  309.         __badr ();
  310.           while ((i = *s1) && !isspace (i) && i != '>' && i != '<')
  311.         s1++;
  312.           if (i == '>')
  313.         {
  314.           *s1 = 0;
  315.           goto outfile;
  316.         }
  317.           if (i == '<')
  318.         __badr ();
  319.           if (i)
  320.         *s1++ = 0;
  321.           continue;
  322.         }
  323.       argv[argc] = s2;
  324.       while ((i = *s1) && !isspace (i) && (!argc || (i != '>' && i != '<')))
  325.         {
  326.           if (i == '\\')
  327.         {
  328.           s1++;
  329.           if (i = *s1)
  330.             *s2++ = i, s1++;
  331.           else
  332.             break;
  333.         }
  334.           else if (i == '"')
  335.         {
  336.           s1++;
  337.           while ((i = *s1) && i != '"')
  338.             {
  339.               if (i == '\\')
  340.             {
  341.               s1++;
  342.               if (i = *s1)
  343.                 *s2++ = i, s1++;
  344.               else
  345.                 break;
  346.             }
  347.               else
  348.             *s2++ = i, s1++;
  349.             }
  350.           if (i == '"')
  351.             s1++;
  352.         }
  353.           else
  354.         *s2++ = i, s1++;
  355.         }
  356.       argc++, *s2++ = 0;
  357.     }
  358.       argv[argc] = 0;
  359.  
  360.       __u->argc = argc;
  361.       __u->argv = argv;
  362.       __u->argb = *argv;
  363.  
  364. /* default UNIX process */
  365.       __initialise_proc (__u);
  366.  
  367. /* default UNIX I/O */
  368.  
  369.  
  370.       for (i = 0; i < MAXFD; i++)
  371.     __u->file[i].dup = 0;
  372.  
  373.       if (!(tty = __getenv ("Unix$tty", 0)))
  374.     tty = "/dev/tty";
  375.  
  376.       if (open (ifile ? ifile : tty, O_RDONLY) < 0)
  377.     __panic (0);
  378.       if (ioflag & 1)
  379.     {
  380.       if (open (ofile ? ofile : tty, O_WRONLY | O_CREAT, 0666) < 0)
  381.         __panic (0);
  382.       lseek (1, 0, 2);
  383.     }
  384.       else
  385.     {
  386.       if (open (ofile ? ofile : tty, O_WRONLY | O_CREAT | O_TRUNC, 0666) < 0)
  387.         __panic (0);
  388.     }
  389.       if (!ofile || (ioflag & 2))
  390.     {
  391.       if (dup (1) < 0)
  392.         __panic (0);
  393.     }
  394.       else
  395.     {
  396.       if (open (tty, O_WRONLY) < 0)
  397.         __panic (0);
  398.     }
  399.     }
  400.  
  401.   if (i = __intenv ("Unix$uid", 0))
  402.     __u->uid = __u->euid = i;
  403.  
  404. #ifdef DEBUG
  405.   __debug ("__unixinit() (final)");
  406. #endif
  407. }
  408.  
  409. void
  410. __unixexit (void)
  411. {
  412.   register int i;
  413.   register struct file *f = __u->file;
  414.  
  415. #ifdef DEBUG
  416.   __debug ("__unixexit()");
  417. #endif
  418.  
  419.   if (f)
  420.     for (i = 0; i < MAXFD; i++)
  421.       if (f[i].dup)
  422.     close (i);
  423.  
  424.   __stop_itimers ();
  425.  
  426. #ifdef DEBUG
  427.   __debug ("__unixexit() (close())");
  428. #endif
  429. }
  430.  
  431. int
  432. __fdalloc (void)
  433. {
  434.   register struct file *f = __u->file;
  435.   register int i;
  436.  
  437.   for (i = 0; i < MAXFD; i++, f++)
  438.     if (!f->dup)
  439.       return (i);
  440.  
  441.   errno = EMFILE;
  442.   return (-1);
  443. }
  444.  
  445. char *
  446. __permstr (register const char *s)
  447. {
  448.   register int i;
  449.   register char *r;
  450.  
  451.   if (!s)
  452.     return (0);
  453.  
  454.   i = strlen (s) + 1;
  455.   if (!(r = malloc (i)))
  456.     return (0);
  457.   memcpy ((void *) r, (void *) s, i);
  458.   return (r);
  459. }
  460.  
  461. void
  462. __stop_itimers (void)
  463. {
  464.   struct itimerval new_timer;
  465.  
  466.   /* Interval timers are not implemented in task windows so we don't
  467.      need to stop them.  */
  468.   if (__taskwindow)
  469.     return;
  470.  
  471.   /* Stop all interval timers.  */
  472.   new_timer.it_interval.tv_sec = 0;
  473.   new_timer.it_interval.tv_usec = 0;
  474.   new_timer.it_value.tv_sec = 0;
  475.   new_timer.it_value.tv_usec = 0;
  476.   setitimer (ITIMER_REAL, &new_timer, 0);
  477.   setitimer (ITIMER_VIRTUAL, &new_timer, 0);
  478.   setitimer (ITIMER_PROF, &new_timer, 0);
  479. }
  480.  
  481. static void
  482. __initialise_proc (struct proc *u)
  483. {
  484.   u->uid = u->euid = 1;
  485.   u->gid = u->egid = 1;
  486.   /* Give the process a process ID of 2 and a process group ID of 2.  */
  487.   u->pgrp = 2;
  488.   u->pid = 2;
  489.   u->ppid = 1;
  490.   u->pproc = 0;
  491.   u->umask = 0;
  492.   /* The priority of this process will currently be zero.  */
  493.   u->ppri = 0;
  494.   u->upri = 0;
  495.   u->gpri = 0;
  496.   /* We need to:
  497.      1. set the resource usage for this child to zero.
  498.      2. set the status for this child to zero.
  499.      3. initialise the itimer structures (since no itimers are running).  */
  500.   memset (&u->usage, 0, sizeof (struct rusage));
  501.   memset (&u->status, 0, sizeof (struct __process));
  502.   memset (&u->itimers, 0, sizeof (struct itimerval) * (__MAX_ITIMERS - 1));
  503.   u->status.tty_type = TTY_CON;
  504. }
  505.