home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnuc / library / rcs / _main.c,v < prev    next >
Encoding:
Text File  |  1992-08-09  |  10.3 KB  |  399 lines

  1. head    1.3;
  2. access;
  3. symbols
  4.     version39-41:1.2;
  5. locks;
  6. comment    @ *  @;
  7.  
  8.  
  9. 1.3
  10. date    92.08.09.20.41.54;    author amiga;    state Exp;
  11. branches;
  12. next    1.2;
  13.  
  14. 1.2
  15. date    92.07.04.19.10.06;    author mwild;    state Exp;
  16. branches;
  17. next    1.1;
  18.  
  19. 1.1
  20. date    92.05.17.21.01.29;    author mwild;    state Exp;
  21. branches;
  22. next    ;
  23.  
  24.  
  25. desc
  26. @@
  27.  
  28.  
  29. 1.3
  30. log
  31. @change to use 2.x header files by default
  32. add option to ignore global environment (ix.ix_ignore_global_env).
  33. @
  34. text
  35. @/*
  36.  *  This file is part of ixemul.library for the Amiga.
  37.  *  Copyright (C) 1991, 1992  Markus M. Wild
  38.  *
  39.  *  This library is free software; you can redistribute it and/or
  40.  *  modify it under the terms of the GNU Library General Public
  41.  *  License as published by the Free Software Foundation; either
  42.  *  version 2 of the License, or (at your option) any later version.
  43.  *
  44.  *  This library is distributed in the hope that it will be useful,
  45.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  46.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  47.  *  Library General Public License for more details.
  48.  *
  49.  *  You should have received a copy of the GNU Library General Public
  50.  *  License along with this library; if not, write to the Free
  51.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  52.  *
  53.  *  $Id: _main.c,v 1.2 1992/07/04 19:10:06 mwild Exp $
  54.  *
  55.  *  $Log: _main.c,v $
  56.  *  Revision 1.2  1992/07/04  19:10:06  mwild
  57.  *  add call to ix_install_sigwinch().
  58.  *
  59.  * Revision 1.1  1992/05/17  21:01:29  mwild
  60.  * Initial revision
  61.  *
  62.  * Revision 1.1  1992/05/14  19:55:40  mwild
  63.  * Initial revision
  64.  *
  65.  */
  66.  
  67. #define KERNEL
  68. #include "ixemul.h"
  69.  
  70. #include <dos/var.h>
  71. #include <workbench/startup.h>
  72. #include <dirent.h>
  73.  
  74. extern int _dos20;
  75. extern  struct ExecBase       *SysBase;
  76.  
  77. static char **
  78. __get_environ (void)
  79. {
  80.   static char *endmarker = 0;
  81.   char **env = &endmarker;
  82.   DIR *dp;
  83.   struct dirent *de;
  84.   int num_env, num_local = 0;
  85.   char **cp;
  86.  
  87.   /* 2.0 local environment overrides 1.3 global environment */
  88.  
  89.   if (_dos20)
  90.     {
  91.       struct Process *me = (struct Process *) FindTask (0);
  92.       struct LocalVar *lv, *nlv;
  93.       
  94.       /* count total number of local variables (skip aliases) */
  95.       for (num_local = 0, 
  96.          lv  = (struct LocalVar *) me->pr_LocalVars.mlh_Head;
  97.        nlv = (struct LocalVar *) lv->lv_Node.ln_Succ;
  98.        lv  = nlv)
  99.     if (lv->lv_Node.ln_Type == LV_VAR)
  100.       num_local ++;
  101.       
  102.       if (cp = (char **) syscall (SYS_malloc, (num_local + 1) * 4))
  103.     {
  104.       env = cp;
  105.  
  106.       for (lv  = (struct LocalVar *) me->pr_LocalVars.mlh_Head;
  107.            nlv = (struct LocalVar *) lv->lv_Node.ln_Succ;
  108.            lv  = nlv)
  109.         {
  110.           /* I'm not interested in aliases, really not ;-)) */
  111.           if (lv->lv_Node.ln_Type != LV_VAR)
  112.             continue;
  113.         
  114.           /* NAME=CONTENTS\0 */
  115.           *cp = (char *) syscall (SYS_malloc, (strlen (lv->lv_Node.ln_Name) 
  116.                            + 1 + lv->lv_Len + 1));
  117.           if (*cp)
  118.         sprintf (*cp, "%s=%*.*s", lv->lv_Node.ln_Name, 
  119.              lv->lv_Len, lv->lv_Len, lv->lv_Value);
  120.           else
  121.         break;
  122.  
  123.           cp ++;
  124.         }
  125.  
  126.       *cp = 0;
  127.     }
  128.       else
  129.     num_local = 0;
  130.     }
  131.  
  132.   if (ix.ix_ignore_global_env)
  133.     return env;
  134.  
  135.   /* now go for global variables */
  136.   
  137.   if (dp = (DIR *) syscall (SYS_opendir, "ENV:"))
  138.     {
  139.       /* first count how many entries we have */
  140.       for (num_env = 0; readdir (dp); num_env++) ;
  141.       
  142.       /* skip . and .. */
  143.       syscall (SYS_rewinddir, dp);
  144.       if ((de = (struct dirent *) syscall (SYS_readdir, dp)) 
  145.       && de->d_namlen == 1 && de->d_name[0] == '.' && --num_env &&
  146.       (de = (struct dirent *) syscall (SYS_readdir, dp)) 
  147.       && de->d_namlen == 2 && de->d_name[0] == '.' && de->d_name[1] == '.')
  148.     {
  149.       num_env --;
  150.       de = (struct dirent *) syscall (SYS_readdir, dp);
  151.     }
  152.  
  153.       if (num_local)
  154.     {
  155.       /* only (!) in this case is `env' allocated and not static */
  156.       char **tmp = (char **) syscall (SYS_realloc, 
  157.                       env, (num_local + num_env + 1) * 4);
  158.       if (tmp)
  159.         {
  160.           cp = tmp + (cp - env);
  161.           env = tmp;
  162.         }
  163.       else
  164.         /* out of memory !!! */
  165.         return &endmarker;
  166.     }
  167.       else
  168.     {
  169.       if (cp = (char **) syscall (SYS_malloc, (num_env + 1) * 4))
  170.         env = cp;
  171.       else
  172.         /* out of memory !!! */
  173.         return &endmarker;
  174.     }
  175.       
  176.  
  177.       for (;de; de = (struct dirent *) syscall (SYS_readdir, dp))
  178.     {
  179.       struct stat stb;
  180.       int len = 0;
  181.       char envfile[MAXPATHLEN];
  182.  
  183.       if (_dos20)
  184.         {
  185.           /* if this variable already exists locally, skip it */
  186.           if (FindVar (de->d_name, GVF_LOCAL_ONLY))
  187.         continue;
  188.         }
  189.  
  190.       /* don't include variables with funny names, and don't include
  191.          multiline variables either, they totally confuse ksh.. */
  192.       if (index (de->d_name, '.'))
  193.         continue;
  194.  
  195.       sprintf (envfile, "ENV:%s", de->d_name);
  196.  
  197.       if (stat (envfile, &stb) == 0)
  198.         {
  199.           len = stb.st_size;
  200.           /* skip directories... shudder */
  201.           if (! S_ISREG (stb.st_mode))
  202.             continue;
  203.         }
  204.  
  205.       /* NAME=CONTENTS\0 */
  206.       *cp = (char *) syscall (SYS_malloc, 
  207.                   de->d_namlen + 1 + len + 1);
  208.       if (*cp)
  209.         {
  210.           int written = sprintf (*cp, "%s=", de->d_name);
  211.           int fd;
  212.  
  213.           if (len)
  214.         {
  215.           fd = open (envfile, 0);
  216.           if (fd >= 0)
  217.             {
  218.               written += read (fd, *cp + written, len);
  219.               (*cp)[written] = 0;
  220.               if ((*cp)[--written] == '\n')
  221.             (*cp)[written] = 0;
  222.               close (fd);
  223.             }
  224.             
  225.           /* now filter out those multiliners (that is, 
  226.              variables containing \n, you can have variables
  227.              as long as want, but don't use \n... */
  228.           if (index (*cp, '\n'))
  229.             {
  230.               syscall (SYS_free, *cp);
  231.               continue;
  232.             }
  233.         }
  234.         }
  235.       else
  236.         break;
  237.  
  238.       cp ++;
  239.     }
  240.  
  241.       *cp = 0;
  242.  
  243.       syscall (SYS_closedir, dp);
  244.       
  245.       return env;
  246.     }
  247.   else
  248.     /* `panic!', no ENV: logical ! */
  249.     return &endmarker;
  250. }
  251.  
  252.  
  253. /* smells abit kludgy I know.. but can live with quite few variables in
  254.  * the user area 
  255.  */
  256.  
  257. int
  258. _main (union { char *_aline; struct WBStartup *_wb_msg; } a1,
  259.        union { int   _alen;  char *_def_window;         } a2,
  260.        int (* main(int, char **, char **)))
  261. #define aline           a1._aline
  262. #define alen            a2._alen
  263. #define wb_msg          a1._wb_msg
  264. #define def_window      a2._def_window
  265. {
  266.   struct Process        *me             = (struct Process *)SysBase->ThisTask;
  267.   int                   exit_val;
  268.   char                  **argv, **env;
  269.   int                   argc;
  270.  
  271.   if (! me->pr_CLI)
  272.     {
  273.       /* Workbench programs expect to have their CD where the executed
  274.        * program lives. */
  275.       if (wb_msg->sm_ArgList)
  276.     {
  277.       CurrentDir (wb_msg->sm_ArgList->wa_Lock);
  278.       syscall (SYS__wb_parse, me, wb_msg, def_window);
  279.     }
  280.       /* argc==0: this means, that argv is really a WBenchMsg, not a vector */
  281.       argc = 0;
  282.       argv = (char **) wb_msg;
  283.     }
  284.   else
  285.     {
  286.       /* if we were started from the CLI, alen & aline are valid and
  287.        * should now be split into arguments. This is done by the
  288.        * function "_cli_parse()", which does wildcard expansion if not
  289.        * disabled (see cli_parse.c). */
  290.       _cli_parse (me, alen, aline, &argc, &argv);
  291.     }
  292.  
  293.   env = __get_environ ();
  294.  
  295.   /* this is not really the right thing to do, the user should call
  296.      ix_get_vars2 () to initialize environ to the address of the variable
  297.      in the calling program. However, this setting guarantees that 
  298.      the user area entry is valid for getenv() calls. */
  299.   u.u_environ = &env;
  300.  
  301.   ix_install_sigwinch ();
  302.  
  303.   syscall (SYS_exit, main (argc, argv, env));
  304. }
  305. @
  306.  
  307.  
  308. 1.2
  309. log
  310. @add call to ix_install_sigwinch().
  311. @
  312. text
  313. @d19 1
  314. a19 1
  315.  *  $Id: _main.c,v 1.1 1992/05/17 21:01:29 mwild Exp $
  316. d22 3
  317. d36 1
  318. a36 55
  319. struct Process_20 {
  320.     struct  Task    pr_Task;
  321.     struct  MsgPort pr_MsgPort; /* This is BPTR address from DOS functions  */
  322.     WORD    pr_Pad;             /* Remaining variables on 4 byte boundaries */
  323.     BPTR    pr_SegList;         /* Array of seg lists used by this process  */
  324.     LONG    pr_StackSize;       /* Size of process stack in bytes           */
  325.     APTR    pr_GlobVec;         /* Global vector for this process (BCPL)    */
  326.     LONG    pr_TaskNum;         /* CLI task number of zero if not a CLI     */
  327.     BPTR    pr_StackBase;       /* Ptr to high memory end of process stack  */
  328.     LONG    pr_Result2;         /* Value of secondary result from last call */
  329.     BPTR    pr_CurrentDir;      /* Lock associated with current directory   */
  330.     BPTR    pr_CIS;             /* Current CLI Input Stream                 */
  331.     BPTR    pr_COS;             /* Current CLI Output Stream                */
  332.     APTR    pr_ConsoleTask;     /* Console handler process for current window*/
  333.     APTR    pr_FileSystemTask;  /* File handler process for current drive   */
  334.     BPTR    pr_CLI;             /* pointer to CommandLineInterface          */
  335.     APTR    pr_ReturnAddr;      /* pointer to previous stack frame          */
  336.     APTR    pr_PktWait;         /* Function to be called when awaiting msg  */
  337.     APTR    pr_WindowPtr;       /* Window for error printing                */
  338.  
  339.     /* following definitions are new with 2.0 */
  340.     BPTR    pr_HomeDir;         /* Home directory of executing program      */
  341.     LONG    pr_Flags;           /* flags telling dos about process          */
  342.     void    (*pr_ExitCode)();   /* code to call on exit of program or NULL  */
  343.     LONG    pr_ExitData;        /* Passed as an argument to pr_ExitCode.    */
  344.     UBYTE   *pr_Arguments;      /* Arguments passed to the process at start */
  345.     struct MinList pr_LocalVars; /* Local environment variables             */
  346.     ULONG   pr_ShellPrivate;    /* for the use of the current shell         */
  347.     BPTR    pr_CES;             /* Error stream - if NULL, use pr_COS       */
  348. };
  349. #include "gcc:include20/dos/var.h"
  350. #define BASE_EXT_DECL
  351. #define BASE_PAR_DECL    
  352. #define BASE_PAR_DECL0    
  353. #define BASE_NAME    ix.ix_dos_base
  354. __inline static struct LocalVar* FindVar(BASE_PAR_DECL UBYTE* name, long unsigned int type)
  355. {
  356.     BASE_EXT_DECL
  357.     register struct LocalVar* res __asm("d0");
  358.     register void *a6 __asm ("a6");
  359.     register UBYTE* d1 __asm("d1");
  360.     register long unsigned int d2 __asm("d2");
  361.  
  362.     a6 = BASE_NAME;
  363.     d1 = name;
  364.     d2 = type;
  365.     __asm volatile ("
  366.     jsr a6@@(-0x396)"
  367.     : "=r" (res)
  368.     : "r" (a6), "r" (d1), "r" (d2)
  369.     : "d0", "d1", "a0", "a1", "d2");
  370.     return res;
  371. }
  372.  
  373.  
  374. d41 1
  375. d57 1
  376. a57 1
  377.       struct Process_20 *me = (struct Process_20 *) FindTask (0);
  378. d68 1
  379. a68 1
  380.       if (cp = (char **) syscall (SYS_malloc, num_local * 4))
  381. d91 2
  382. d98 2
  383. a231 1
  384.   struct ExecBase       *SysBase        = *(void **)4;
  385. @
  386.  
  387.  
  388. 1.1
  389. log
  390. @Initial revision
  391. @
  392. text
  393. @d19 1
  394. a19 1
  395.  *  $Id: _main.c,v 1.1 1992/05/14 19:55:40 mwild Exp $
  396. d22 3
  397. d313 2
  398. @
  399.