home *** CD-ROM | disk | FTP | other *** search
- #include "amiga.h"
- #include "processes.h"
- #include <amiga/ioctl.h>
- #include <exec/memory.h>
- #include <dos/dosextens.h>
- #include <dos/dostags.h>
- #include <string.h>
-
- /* Variables used by a child that is starting up */
- struct MemList *_child_entry; /* Memory used for child's code */
- static struct Message startup_message;
- struct exit_message *_child_exit;
- char *_child_command;
- int _child_command_len;
- char *_child_door_name;
-
- static void __saveds __interrupt _child_startup(void)
- {
- struct exit_message *exit = _child_exit;
- char *command = _child_command;
- int command_len = _child_command_len;
- char *door_name = _child_door_name;
- struct Process *us = (struct Process *)FindTask(0);
- struct DOSBase *local_DOSBase = DOSBase;
- #pragma libcall local_DOSBase local_SystemTagList 25E 2102
- struct TagItem stags[2];
- struct MsgPort *parent;
-
- AddTail(&us->pr_Task.tc_MemEntry, _child_entry);
-
- PutMsg(_startup_port, &startup_message);
-
- /* From now on parent may disappear */
- stags[0].ti_Tag = SYS_UserShell; stags[0].ti_Data = TRUE;
- stags[1].ti_Tag = TAG_END;
- exit->rc = local_SystemTagList(command, stags) << 8;
-
- /* Send result to parent if he is around */
- Forbid();
- if (parent = FindPort(door_name)) PutMsg(parent, exit);
- else FreeMem(exit, sizeof(struct exit_message));
- Permit();
-
- FreeMem(door_name, DOOR_LEN);
- FreeMem(command, command_len);
- }
-
- int _start_process(char *command,
- BPTR input, int close_input,
- BPTR output, int close_output,
- BPTR error, int close_error,
- BPTR dir,
- long stacksize)
- {
- struct process *entry = (struct process *)malloc(sizeof(struct process));
- static struct MemList alloc_child = { { 0 }, 1 };
-
- _child_command_len = strlen(command) + 1;
- _child_command = AllocMem(_child_command_len, MEMF_PUBLIC);
- strcpy(_child_command, command);
-
- _child_exit = AllocMem(sizeof(struct exit_message), MEMF_PUBLIC);
- _child_door_name = AllocMem(DOOR_LEN, MEMF_PUBLIC);
-
- alloc_child.ml_ME[0].me_Reqs = MEMF_PUBLIC;
- alloc_child.ml_ME[0].me_Length = (char *)&_start_process - (char *)&_child_startup;
- _child_entry = AllocEntry(&alloc_child);
-
- if (entry && _child_command && _child_exit && _child_door_name &&
- (long)_child_entry > 0)
- {
- memcpy(_child_entry->ml_ME[0].me_Addr, &_child_startup,
- _child_entry->ml_ME[0].me_Length);
- strcpy(_child_door_name, _door_name);
-
- entry->pid = _next_pid++;
- entry->input = input;
-
- /* This message is sent by the child when it has started */
- startup_message.mn_Length = sizeof(startup_message);
- startup_message.mn_Node.ln_Type = NT_MESSAGE;
-
- /* This message is sent by the child when it exits */
- _child_exit->m.mn_Length = sizeof(*_child_exit);
- _child_exit->m.mn_Node.ln_Type = NT_MESSAGE;
- _child_exit->pid = entry->pid;
-
- entry->process = CreateNewProcTags(NP_Entry, _child_entry->ml_ME[0].me_Addr,
- NP_Input, input,
- NP_CloseInput, (long)close_input,
- NP_Output, output,
- NP_CloseOutput, (long)close_output,
- NP_Error, error,
- NP_CloseError, (long)close_error,
- dir ? NP_CurrentDir : TAG_IGNORE, dir,
- NP_StackSize,
- stacksize > 0 ? stacksize : _stack_size,
- NP_Cli, TRUE,
- TAG_END);
- if (entry->process)
- {
- do WaitPort(_startup_port); while (!GetMsg(_startup_port));
- entry->status = alive;
- AddHead((struct List *)&_processes, (struct Node *)entry);
- return entry->pid;
- }
- errno = convert_oserr(IoErr());
- }
- else errno = ENOMEM;
-
- if (entry) free(entry);
- if (_child_command) FreeMem(_child_command, _child_command_len);
- if (_child_exit) FreeMem(_child_exit, sizeof(struct exit_message));
- if (_child_door_name) FreeMem(_child_door_name, DOOR_LEN);
- if ((long)_child_entry > 0) FreeEntry(_child_entry);
-
- return -1;
- }
-