home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * $Source: /unixb/home/unixlib/source/unixlib37/src/unix/c/RCS/unix,v $
- * $Date: 1996/11/06 22:01:42 $
- * $Revision: 1.6 $
- * $State: Rel $
- * $Author: unixlib $
- *
- * $Log: unix,v $
- * Revision 1.6 1996/11/06 22:01:42 unixlib
- * Yet more changes by NB, PB and SC.
- *
- * Revision 1.5 1996/10/30 22:04:51 unixlib
- * Massive changes made by Nick Burret and Peter Burwood.
- *
- * Revision 1.4 1996/07/21 22:12:31 unixlib
- * CL_0001 Nick Burret
- * Improve memory handling. Remove C++ library incompatibilities.
- * Improve file stat routines.
- *
- * Revision 1.3 1996/05/06 18:56:11 unixlib
- * Remove declaration of unused variable.
- *
- * Revision 1.2 1996/05/06 09:01:35 unixlib
- * Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
- * Saved for 3.7a release.
- *
- * Revision 1.1 1996/04/19 21:35:27 simon
- * Initial revision
- *
- ***************************************************************************/
-
- static const char rcs_id[] = "$Id: unix,v 1.6 1996/11/06 22:01:42 unixlib Rel $";
-
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <ctype.h>
- #include <limits.h>
-
- #include <fcntl.h>
- #include <termio.h>
- #include <unistd.h>
-
- #include <sys/types.h>
- #include <sys/dev.h>
- #include <sys/os.h>
- #include <sys/unix.h>
- #include <sys/syslib.h>
- #include <sys/param.h>
- #include <sys/debug.h>
- #include <sys/swis.h>
-
- struct sdir __sdir[MAXSDIR]; /* special directory list */
-
- char *__sfix[MAXSFIX]; /* special suffix list */
-
- static void __initialise_proc (struct proc *);
-
- static void
- __sdirinit (void)
- {
- int r[10];
- char buf[256];
-
- _kernel_oserror *e = 0;
- int i;
- int tmp_found = 0;
-
- r[1] = (int) buf;
- r[3] = 0;
-
- for (i = 0; i < MAXSDIR;)
- {
- register char *s1, *s2;
-
- r[0] = (int) "UnixFS$/*";
- /* One less than buf size so can zero terminate below. */
- r[2] = sizeof (buf) - 1;
- r[4] = 3;
-
- if (e = os_swi (OS_ReadVarVal, r))
- break;
-
- buf[r[2]] = 0;
-
- s1 = (char *) r[3] + 8;
- if (!*s1)
- continue;
-
- if (!(s2 = __permstr (s1)))
- break;
- __sdir[i].name = s2;
-
- if (!(s2 = __permstr (buf)))
- break;
- __sdir[i].riscos_name = s2;
-
- if (stricmp (__sdir[i].name, "tmp") == 0)
- tmp_found = 1;
-
- i++;
- }
-
- if (!tmp_found && (i < MAXSDIR))
- {
- __sdir[i].name = "tmp";
- __sdir[i].riscos_name = "<Wimp$ScrapDir>";
- i++;
- }
-
- if (i < MAXSDIR)
- __sdir[i].name = 0; /* terminate list */
- }
-
- static void
- __panic (char *s)
- {
- s = s ? s : sys_errlist[errno];
- os_print ("\r\n");
- os_print (s);
- os_print ("\r\n\n");
- _exit (1);
- }
-
- static void
- __badr (void)
- {
- __panic ("Bad redirection");
- }
-
- void
- __unixlib_fatal (char *s)
- {
- __panic (s);
- }
-
- void
- __unixinit (void)
- {
- int i, j;
- char cli[MAXCOMMANDLEN];
- int r[10];
- char *s1, *s2, *tty;
-
- __u = 0; /* trap early exits */
-
- __svccli (cli); /* copy __cli in SVC mode */
-
- /* if DDE Utils is present then copy in the extra command line */
- if (!os_swi (DDEUtils_GetCLSize, r) && (r[0] != 0))
- {
- int len = strlen (cli);
- if (len + r[0] + 2 > MAXCOMMANDLEN) /* command line too long */
- {
- errno = -1;
- __panic ("command line far too long");
- }
- else
- {
- /* command line will fit, append it to cli. */
- cli[len] = ' ';
- r[0] = (int) cli + len + 1;
- os_swi (DDEUtils_GetCl, r);
- /* set length to zero */
- r[0] = 0;
- os_swi (DDEUtils_SetCLSize, r);
- }
- }
-
- __envcnt = 0, __envsiz = 1;
-
- if (!(environ = malloc (sizeof (char *))))
- __panic (0);
- *environ = 0;
-
- if (__u = (struct proc *) __intenv ("UnixLib$env", 0))
- {
- /* Check the consistency of UnixLib$env. If a process previously
- exited through a serious crash, it could be that UnixLib$env
- is still set and points to some invalid proc structure. If it
- is invalid, we are probably the parent process, so just set
- the proc struct to zero and re-create. */
- if (__u->__magic == _PROCMAGIC)
- {
- #ifdef DEBUG
- __debug ("__unixinit() (test)");
- #endif
- s1 = cli;
- s2 = __u->argb;
-
- while (*s2)
- if (*s1++ != *s2++)
- {
- __u = 0;
- break;
- }
- }
- else
- __u = 0;
-
- r[0] = (int) "UnixLib$env";
- r[1] = r[3] = r[4] = 0;
- r[2] = -1;
- os_swi (OS_SetVarVal, r);
- }
-
- __sdirinit ();
-
- /* Sort out the suffixes list. */
- if (!(s1 = s2 = __getenv ("UnixFS$sfix", 0)))
- s1 = s2 = "a:c:cc:f:h:i:l:o:p:s:y";
- for (i = 0; i < MAXSFIX;)
- {
- while ((j = *s2) && j != ':')
- s2++;
- if (j && s1 == s2)
- {
- s1++, s2++;
- continue;
- }
- __sfix[i++] = s1;
- if (!j)
- break;
- *s2++ = 0;
- s1 = s2;
- }
- if (i < MAXSFIX)
- __sfix[i] = 0; /* terminate list */
-
- /* No process structure exists, so lets create one. */
- if (!__u)
- {
- int argc;
- char **argv;
- char *ifile = 0, *ofile = 0;
- int ioflag = 0;
-
- if (!(__u = calloc (1, sizeof (struct proc))))
- __panic (0);
- if (!(__u->tty = calloc (MAXTTY, sizeof (struct tty))))
- __panic (0);
- #ifndef __TTY_STATIC_BUFS
- /* While not strictly necessary to allocate the del buffer here,
- it helps when we need to print a fatal message due to lack
- of memory during a later part of the initialisation of Unixlib. */
- for (i = 0; i < MAXTTY; i++)
- {
- if (!(__u->tty[i].del = malloc (MAXPATHLEN)))
- __panic (0);
- }
- #endif
- if (!(argv = malloc (sizeof (int) * (MAXCOMMANDLEN >> 2))))
- __panic (0);
- if (!(*argv = malloc (MAXCOMMANDLEN)))
- __panic (0);
-
- /* Set the magic word for our new process structure. We will use
- this when checking the validity of the pointer specified by
- UnixLib$env. */
- __u->__magic = _PROCMAGIC;
- argc = 0;
- s1 = cli;
- s2 = *argv;
-
- while (*s1 && argc < (MAXCOMMANDLEN >> 2))
- {
- while ((i = *s1) && isspace (i))
- s1++;
-
- if (!i)
- break;
- if (argc && i == '>')
- {
- outfile:
- if (*++s1 == '>')
- ++s1, ioflag |= 1;
- if (*s1 == '&')
- ++s1, ioflag |= 2;
- while ((i = *s1) && isspace (i))
- s1++;
- if (i)
- ofile = s1;
- else
- __badr ();
- while ((i = *s1) && !isspace (i) && i != '>' && i != '<')
- s1++;
- if (i == '<')
- {
- *s1 = 0;
- goto infile;
- }
- if (i == '>')
- __badr ();
- if (i)
- *s1++ = 0;
- continue;
- }
- if (argc && i == '<')
- {
- infile:
- if (*++s1 == '<')
- __badr ();
- while ((i = *s1) && isspace (i))
- s1++;
- if (i)
- ifile = s1;
- else
- __badr ();
- while ((i = *s1) && !isspace (i) && i != '>' && i != '<')
- s1++;
- if (i == '>')
- {
- *s1 = 0;
- goto outfile;
- }
- if (i == '<')
- __badr ();
- if (i)
- *s1++ = 0;
- continue;
- }
- argv[argc] = s2;
- while ((i = *s1) && !isspace (i) && (!argc || (i != '>' && i != '<')))
- {
- if (i == '\\')
- {
- s1++;
- if (i = *s1)
- *s2++ = i, s1++;
- else
- break;
- }
- else if (i == '"')
- {
- s1++;
- while ((i = *s1) && i != '"')
- {
- if (i == '\\')
- {
- s1++;
- if (i = *s1)
- *s2++ = i, s1++;
- else
- break;
- }
- else
- *s2++ = i, s1++;
- }
- if (i == '"')
- s1++;
- }
- else
- *s2++ = i, s1++;
- }
- argc++, *s2++ = 0;
- }
- argv[argc] = 0;
-
- __u->argc = argc;
- __u->argv = argv;
- __u->argb = *argv;
-
- /* default UNIX process */
- __initialise_proc (__u);
-
- /* default UNIX I/O */
-
-
- for (i = 0; i < MAXFD; i++)
- __u->file[i].dup = 0;
-
- if (!(tty = __getenv ("Unix$tty", 0)))
- tty = "/dev/tty";
-
- if (open (ifile ? ifile : tty, O_RDONLY) < 0)
- __panic (0);
- if (ioflag & 1)
- {
- if (open (ofile ? ofile : tty, O_WRONLY | O_CREAT, 0666) < 0)
- __panic (0);
- lseek (1, 0, 2);
- }
- else
- {
- if (open (ofile ? ofile : tty, O_WRONLY | O_CREAT | O_TRUNC, 0666) < 0)
- __panic (0);
- }
- if (!ofile || (ioflag & 2))
- {
- if (dup (1) < 0)
- __panic (0);
- }
- else
- {
- if (open (tty, O_WRONLY) < 0)
- __panic (0);
- }
- }
-
- if (i = __intenv ("Unix$uid", 0))
- __u->uid = __u->euid = i;
-
- #ifdef DEBUG
- __debug ("__unixinit() (final)");
- #endif
- }
-
- void
- __unixexit (void)
- {
- register int i;
- register struct file *f = __u->file;
-
- #ifdef DEBUG
- __debug ("__unixexit()");
- #endif
-
- if (f)
- for (i = 0; i < MAXFD; i++)
- if (f[i].dup)
- close (i);
-
- __stop_itimers ();
-
- #ifdef DEBUG
- __debug ("__unixexit() (close())");
- #endif
- }
-
- int
- __fdalloc (void)
- {
- register struct file *f = __u->file;
- register int i;
-
- for (i = 0; i < MAXFD; i++, f++)
- if (!f->dup)
- return (i);
-
- errno = EMFILE;
- return (-1);
- }
-
- char *
- __permstr (register const char *s)
- {
- register int i;
- register char *r;
-
- if (!s)
- return (0);
-
- i = strlen (s) + 1;
- if (!(r = malloc (i)))
- return (0);
- memcpy ((void *) r, (void *) s, i);
- return (r);
- }
-
- void
- __stop_itimers (void)
- {
- struct itimerval new_timer;
-
- /* Interval timers are not implemented in task windows so we don't
- need to stop them. */
- if (__taskwindow)
- return;
-
- /* Stop all interval timers. */
- new_timer.it_interval.tv_sec = 0;
- new_timer.it_interval.tv_usec = 0;
- new_timer.it_value.tv_sec = 0;
- new_timer.it_value.tv_usec = 0;
- setitimer (ITIMER_REAL, &new_timer, 0);
- setitimer (ITIMER_VIRTUAL, &new_timer, 0);
- setitimer (ITIMER_PROF, &new_timer, 0);
- }
-
- static void
- __initialise_proc (struct proc *u)
- {
- u->uid = u->euid = 1;
- u->gid = u->egid = 1;
- /* Give the process a process ID of 2 and a process group ID of 2. */
- u->pgrp = 2;
- u->pid = 2;
- u->ppid = 1;
- u->pproc = 0;
- u->umask = 0;
- /* The priority of this process will currently be zero. */
- u->ppri = 0;
- u->upri = 0;
- u->gpri = 0;
- /* We need to:
- 1. set the resource usage for this child to zero.
- 2. set the status for this child to zero.
- 3. initialise the itimer structures (since no itimers are running). */
- memset (&u->usage, 0, sizeof (struct rusage));
- memset (&u->status, 0, sizeof (struct __process));
- memset (&u->itimers, 0, sizeof (struct itimerval) * (__MAX_ITIMERS - 1));
- u->status.tty_type = TTY_CON;
- }
-