summaryrefslogtreecommitdiff
path: root/amigaos4/amigaos.c
diff options
context:
space:
mode:
authorAndy Broad <andy@broad.ology.org.uk>2016-03-05 13:18:08 -0500
committerJarkko Hietaniemi <jhi@iki.fi>2016-03-05 13:20:46 -0500
commitb80d877540658f2420223d8dca4483b085983376 (patch)
tree26e8468b4b1fc781162bf65d688e0834872eaa64 /amigaos4/amigaos.c
parent710740a6ed7f31a3bcc5f991f3cb7b55fed8a68e (diff)
downloadperl-b80d877540658f2420223d8dca4483b085983376.tar.gz
amigaos4: execvp() and popen() enhancements
myexecvp() Replaces alloca() in execvp() with IExec->AllocVecTags() with the memory type explicitly set to MEMF_SHARED (alloca allocating on the stack which is MEMF_PRIVATE and in theory at least you can't share that with the sub process (in practice this isn't enforced yet, too much old software would break, but one of these days)). amigaos_popen() Alters file opening order to ensure that the write end of the pipe is always opened first. Now attempts to pass Input() out Output() (stdin or stout) to the non-pipe file handles rather than NIL: reverting to NIL: if the above can't be DupFileHandled() (say if they were redirected to a file opened with an exclusive lock).
Diffstat (limited to 'amigaos4/amigaos.c')
-rw-r--r--amigaos4/amigaos.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/amigaos4/amigaos.c b/amigaos4/amigaos.c
index 5e6a6438df..44860c9101 100644
--- a/amigaos4/amigaos.c
+++ b/amigaos4/amigaos.c
@@ -161,7 +161,7 @@ char *mystrdup(const char *s)
return result;
}
-static int pipenum = 0;
+static unsigned int pipenum = 0;
int pipe(int filedes[2])
{
@@ -317,11 +317,11 @@ int myexecvp(bool isperlthread, const char *filename, char *argv[])
/* if there's a slash or a colon consider filename a path and skip
* search */
int res;
+ char *name = NULL;
+ char *pathpart = NULL;
if ((strchr(filename, '/') == NULL) && (strchr(filename, ':') == NULL))
{
const char *path;
- char *name;
- char *pathpart;
const char *p;
size_t len;
struct stat st;
@@ -332,8 +332,8 @@ int myexecvp(bool isperlthread, const char *filename, char *argv[])
}
len = strlen(filename) + 1;
- name = (char *)alloca(strlen(path) + len);
- pathpart = (char *)alloca(strlen(path) + 1);
+ name = (char *)IExec->AllocVecTags(strlen(path) + len, AVT_ClearWithValue,0,AVT_Type,MEMF_SHARED,TAG_DONE);
+ pathpart = (char *)IExec->AllocVecTags(strlen(path) + 1, AVT_ClearWithValue,0,AVT_Type,MEMF_SHARED,TAG_DONE);
p = path;
do
{
@@ -364,7 +364,19 @@ int myexecvp(bool isperlthread, const char *filename, char *argv[])
}
while (*p++ != '\0');
}
+
res = myexecve(isperlthread, filename, argv, myenviron);
+
+ if(name)
+ {
+ IExec->FreeVec((APTR)name);
+ name = NULL;
+ }
+ if(pathpart)
+ {
+ IExec->FreeVec((APTR)pathpart);
+ pathpart = NULL;
+ }
return res;
}
@@ -532,6 +544,7 @@ int popen_child()
return 0;
}
+
FILE *amigaos_popen(const char *cmd, const char *mode)
{
FILE *result = NULL;
@@ -572,29 +585,42 @@ FILE *amigaos_popen(const char *cmd, const char *mode)
sprintf(unix_pipe, "/PIPE/%s", pipe_name);
sprintf(ami_pipe, "PIPE:%s", pipe_name);
- /* Now we open the AmigaOs Filehandles That we wil pass to our
- * Sub process
+ /* Now we open the AmigaOs filehandles that we will pass to our
+ * subprocess
*/
if (mode[0] == 'r')
{
- /* A read mode pipe: Output from pipe input from NIL:*/
- input = IDOS->Open("NIL:", MODE_NEWFILE);
+ /* A read mode pipe: Output from pipe input from Output() or NIL:*/
+ /* First attempt to DUP Output() */
+ input = IDOS->DupFileHandle(IDOS->Output());
+ if(input == 0)
+ {
+ input = IDOS->Open("NIL:", MODE_READWRITE);
+ }
if (input != 0)
{
output = IDOS->Open(ami_pipe, MODE_NEWFILE);
}
+ result = fopen(unix_pipe, mode);
}
else
{
+ /* Open the write end first! */
- input = IDOS->Open(ami_pipe, MODE_NEWFILE);
+ result = fopen(unix_pipe, mode);
+
+ input = IDOS->Open(ami_pipe, MODE_OLDFILE);
if (input != 0)
{
- output = IDOS->Open("NIL:", MODE_NEWFILE);
+ output = IDOS->DupFileHandle(IDOS->Input());
+ if(output == 0)
+ {
+ output = IDOS->Open("NIL:", MODE_READWRITE);
+ }
}
}
- if ((input == 0) || (output == 0))
+ if ((input == 0) || (output == 0) || (result == NULL))
{
/* Ouch stream opening failed */
/* Close and bail */
@@ -602,6 +628,11 @@ FILE *amigaos_popen(const char *cmd, const char *mode)
IDOS->Close(input);
if (output)
IDOS->Close(output);
+ if(result)
+ {
+ fclose(result);
+ result = NULL;
+ }
return result;
}
@@ -635,16 +666,21 @@ FILE *amigaos_popen(const char *cmd, const char *mode)
IDOS->Close(output);
if (cmd_copy)
IExec->FreeVec(cmd_copy);
+ if(result)
+ {
+ fclose(result);
+ result = NULL;
+ }
}
/* Our new process is running and will close it streams etc
* once its done. All we need to is open the pipe via stdio
*/
- return fopen(unix_pipe, mode);
+ return result;
}
-/* Work arround for clib2 fstat */
+/* Workaround for clib2 fstat */
#ifndef S_IFCHR
#define S_IFCHR 0x0020000
#endif