home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / library / ix_startup.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  176 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Portions Copyright (C) 1994 Rafael W. Luebbert
  5.  *  Portions Copyright (C) 1995 Jeff Shepherd
  6.  *
  7.  *  This library is free software; you can redistribute it and/or
  8.  *  modify it under the terms of the GNU Library General Public
  9.  *  License as published by the Free Software Foundation; either
  10.  *  version 2 of the License, or (at your option) any later version.
  11.  *
  12.  *  This library is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  *  Library General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU Library General Public
  18.  *  License along with this library; if not, write to the Free
  19.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *  $Id: ix_startup.c,v 1.5 1994/06/19 15:13:22 rluebbert Exp $
  22.  *
  23.  *  $Log: ix_startup.c,v $
  24.  *  Revision 1.5  1994/06/19  15:13:22  rluebbert
  25.  *  *** empty log message ***
  26.  *
  27.  *  Revision 1.3  1992/08/09  20:55:51  amiga
  28.  *  import sysbase
  29.  *
  30.  *  Revision 1.2  1992/07/04  19:18:21  mwild
  31.  *  remove SIGWINCH handler before returning
  32.  *
  33.  * Revision 1.1  1992/05/14  19:55:40  mwild
  34.  * Initial revision
  35.  *
  36.  */
  37.  
  38. #define _KERNEL
  39. #include "ixemul.h"
  40. #include <sys/wait.h>
  41. #include "kprintf.h"
  42.  
  43. /* this just jumps right back into ix_startup() */
  44.  
  45.  
  46. /*
  47.  * Note: I kept the partition into startup and _main(), although in this
  48.  *       case, both functions could be done in one function, since this is
  49.  *       a library, and the user can't override _main anyway but globally...
  50.  */
  51.  
  52. int
  53. ix_startup (char *aline, int alen,
  54.         int expand, char *wb_default_window, u_int main, int *real_errno)
  55. {
  56.   struct Process *me = (struct Process *) SysBase->ThisTask;
  57.   int exit_val;
  58.   struct WBStartup *wb_msg = NULL;
  59.   int fd;
  60.  
  61.   /*
  62.    * The following code to reset the fpu might not be necessary, BUT since
  63.    * a CLI shell doesn't spawn a new process when executing a command - it 
  64.    * insteads calls the command like a subroutine - it depends on the Shell
  65.    * whether the fpu is setup correctly. And I don't like to depend on any
  66.    * thing ;-)
  67.    */
  68.  
  69.   if (gotanfpu())
  70.     resetfpu();
  71.   /* first deal with WB messages, since those HAVE to be answered properly,
  72.    * even if we should fail later (memory, whatever..) */
  73.  
  74.   if (! me->pr_CLI)
  75.     {
  76.       /* we have been started by Workbench. Get the StartupMsg */
  77.       WaitPort (& me->pr_MsgPort);
  78.       wb_msg = (struct WBStartup *) GetMsg (& me->pr_MsgPort);
  79.       /* further processing in _main () */
  80.     }
  81.   else
  82.     {
  83.       struct CommandLineInterface *cli = (void *)BADDR(me->pr_CLI);
  84.       long segs;
  85.  
  86.       /* for usage by sys_exit() for example */
  87.       KPRINTF (("CLI command line '%s'\n", aline));
  88.       u.u_argline = aline;
  89.       u.u_arglinelen = alen;
  90.       segs = cli->cli_Module;
  91.       if ((u.u_segs = (struct my_seg *)kmalloc(sizeof(struct my_seg))))
  92.         {
  93.           u.u_segs->segment = segs;
  94.           u.u_segs->name = NULL;
  95.         }
  96.       segs <<= 2;
  97.       u.u_start_pc = segs + 4;
  98.       u.u_end_pc = segs + *(long *)(segs - 4) - 8;
  99.     }
  100.  
  101.   u.u_expand_cmd_line = expand;
  102.  
  103.   /* put some AmiTCP and AS225 in here since it can't go into ix_open
  104.    * I need a pointer to the REAL errno
  105.    */
  106.   if (real_errno)
  107.    {
  108.       u.u_errno = real_errno;
  109.       if (u.u_ixnetbase)
  110.     netcall(NET_set_errno, real_errno, NULL);
  111.    }
  112.  
  113.   KPRINTF (("&errno = %lx\n", real_errno));
  114.  
  115.   exit_val = _setjmp (u.u_jmp_buf);
  116.   if (! exit_val)
  117.     {
  118.       /* from now on it's safe to allow signals */
  119.       syscall (SYS_sigsetmask, 0);
  120.       /* the first time thru call the program */
  121.       KPRINTF (("calling __main()\n"));
  122.       if (me->pr_CLI)
  123.         syscall (SYS__main, aline, alen, main);
  124.       else
  125.     syscall (SYS__main, wb_msg, wb_default_window, main);
  126.       /* NORETURN */
  127.     }
  128.   /* in this case we came from a longjmp-call */
  129.  
  130.   exit_val = u.p_xstat;
  131.  
  132.   ix_remove_sigwinch ();
  133.  
  134.   /* had to move the closing of files out of ix_close(), as close() may 
  135.      actually wait for the last packet to arrive, and inside ix_close() we're
  136.      inside Forbid, and may thus never wait! */
  137.  
  138.   /* close all files */
  139.   for (fd = 0; fd < NOFILE; fd++) 
  140.     if (u.u_ofile[fd]) syscall (SYS_close, fd);
  141.  
  142.   /* if at all possible, free memory before entering Forbid ! (Semaphore
  143.      problems..) */
  144.   all_free ();
  145.  
  146.   /*
  147.    * If we were traced by a debugger who got us through a ptrace 'attach',
  148.    * we need to unlink us from our parent and to give it a signal telling
  149.    * it that we've died.
  150.    */
  151.   if (u.p_pptr && u.p_pptr != (struct Process *) 1)
  152.     {
  153.       send_death_msg(&u);
  154.       Permit();  /* send_death_msg did the matching Forbid() */
  155.     }
  156.  
  157.   /* if started from workbench, Forbid(), since on reply WB will deallocate
  158.    * our task... */
  159.   if (! me->pr_CLI)
  160.     {
  161.       Forbid ();
  162.       ReplyMsg ((struct Message *) wb_msg);
  163.     }
  164.  
  165.   return WEXITSTATUS(exit_val);
  166. }
  167.  
  168. void
  169. _exit (int retcode)
  170. {
  171.   /* ignore all signals from now on */
  172.   syscall (SYS_sigsetmask, ~0);
  173.   u.p_xstat = W_EXITCODE(retcode, 0);
  174.   _longjmp (u.u_jmp_buf, 1);
  175. }
  176.