home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / emacs-19.28-src.tgz / tar.out / fsf / emacs / unixlib / src / start.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-28  |  3.7 KB  |  119 lines

  1. #include "amiga.h"
  2. #include "processes.h"
  3. #include <amiga/ioctl.h>
  4. #include <exec/memory.h>
  5. #include <dos/dosextens.h>
  6. #include <dos/dostags.h>
  7. #include <string.h>
  8.  
  9. /* Variables used by a child that is starting up */
  10. struct MemList *_child_entry;    /* Memory used for child's code */
  11. static struct Message startup_message;
  12. struct exit_message *_child_exit;
  13. char *_child_command;
  14. int _child_command_len;
  15. char *_child_door_name;
  16.  
  17. static void __saveds __interrupt _child_startup(void)
  18. {
  19.   struct exit_message *exit = _child_exit;
  20.   char *command = _child_command;
  21.   int command_len = _child_command_len;
  22.   char *door_name = _child_door_name;
  23.   struct Process *us = (struct Process *)FindTask(0);
  24.   struct DOSBase *local_DOSBase = DOSBase;
  25. #pragma libcall local_DOSBase local_SystemTagList 25E 2102
  26.   struct TagItem stags[2];
  27.   struct MsgPort *parent;
  28.  
  29.   AddTail(&us->pr_Task.tc_MemEntry, _child_entry);
  30.  
  31.   PutMsg(_startup_port, &startup_message);
  32.  
  33.   /* From now on parent may disappear */
  34.   stags[0].ti_Tag = SYS_UserShell; stags[0].ti_Data = TRUE;
  35.   stags[1].ti_Tag = TAG_END;
  36.   exit->rc = local_SystemTagList(command, stags) << 8;
  37.  
  38.   /* Send result to parent if he is around */
  39.   Forbid();
  40.   if (parent = FindPort(door_name)) PutMsg(parent, exit);
  41.   else FreeMem(exit, sizeof(struct exit_message));
  42.   Permit();
  43.  
  44.   FreeMem(door_name, DOOR_LEN);
  45.   FreeMem(command, command_len);
  46. }
  47.  
  48. int _start_process(char *command,
  49.            BPTR input, int close_input,
  50.            BPTR output, int close_output,
  51.            BPTR error, int close_error,
  52.            BPTR dir,
  53.            long stacksize)
  54. {
  55.   struct process *entry = (struct process *)malloc(sizeof(struct process));
  56.   static struct MemList alloc_child = { { 0 }, 1 };
  57.  
  58.   _child_command_len = strlen(command) + 1;
  59.   _child_command = AllocMem(_child_command_len, MEMF_PUBLIC);
  60.   strcpy(_child_command, command);
  61.  
  62.   _child_exit = AllocMem(sizeof(struct exit_message), MEMF_PUBLIC);
  63.   _child_door_name = AllocMem(DOOR_LEN, MEMF_PUBLIC);
  64.  
  65.   alloc_child.ml_ME[0].me_Reqs = MEMF_PUBLIC;
  66.   alloc_child.ml_ME[0].me_Length = (char *)&_start_process - (char *)&_child_startup;
  67.   _child_entry = AllocEntry(&alloc_child);
  68.  
  69.   if (entry && _child_command && _child_exit && _child_door_name &&
  70.       (long)_child_entry > 0)
  71.     {
  72.       memcpy(_child_entry->ml_ME[0].me_Addr, &_child_startup,
  73.          _child_entry->ml_ME[0].me_Length);
  74.       strcpy(_child_door_name, _door_name);
  75.  
  76.       entry->pid = _next_pid++;
  77.       entry->input = input;
  78.  
  79.       /* This message is sent by the child when it has started */
  80.       startup_message.mn_Length = sizeof(startup_message);
  81.       startup_message.mn_Node.ln_Type = NT_MESSAGE;
  82.  
  83.       /* This message is sent by the child when it exits */
  84.       _child_exit->m.mn_Length = sizeof(*_child_exit);
  85.       _child_exit->m.mn_Node.ln_Type = NT_MESSAGE;
  86.       _child_exit->pid = entry->pid;
  87.  
  88.       entry->process = CreateNewProcTags(NP_Entry, _child_entry->ml_ME[0].me_Addr,
  89.                      NP_Input, input,
  90.                      NP_CloseInput, (long)close_input,
  91.                      NP_Output, output,
  92.                      NP_CloseOutput, (long)close_output,
  93.                      NP_Error, error,
  94.                      NP_CloseError, (long)close_error,
  95.                      dir ? NP_CurrentDir : TAG_IGNORE, dir,
  96.                      NP_StackSize,
  97.                      stacksize > 0 ? stacksize : _stack_size,
  98.                      NP_Cli, TRUE,
  99.                      TAG_END);
  100.       if (entry->process)
  101.     {
  102.       do WaitPort(_startup_port); while (!GetMsg(_startup_port));
  103.       entry->status = alive;
  104.       AddHead((struct List *)&_processes, (struct Node *)entry);
  105.       return entry->pid;
  106.     }
  107.       errno = convert_oserr(IoErr());
  108.     }
  109.   else errno = ENOMEM;
  110.  
  111.   if (entry) free(entry);
  112.   if (_child_command) FreeMem(_child_command, _child_command_len);
  113.   if (_child_exit) FreeMem(_child_exit, sizeof(struct exit_message));
  114.   if (_child_door_name) FreeMem(_child_door_name, DOOR_LEN);
  115.   if ((long)_child_entry > 0) FreeEntry(_child_entry);
  116.  
  117.   return -1;
  118. }
  119.