prism2.device: fix strict aliasing issue detected with gcc 4.8.3
[AROS.git] / compiler / posixc / popen.c
blobb3c8c7ba5bf4cfd5f1d62527a36aa0be220a4d51
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 POSIX.1-2008 function popen().
6 */
8 #include <utility/tagitem.h>
9 #include <proto/dos.h>
10 #include <fcntl.h>
11 #include <unistd.h>
13 #include "__fdesc.h"
15 #include <errno.h>
18 /*****************************************************************************
20 NAME */
21 #include <stdio.h>
23 FILE * popen (
25 /* SYNOPSIS */
26 const char * command,
27 const char * mode)
29 /* FUNCTION
30 "opens" a process by creating a pipe, spawning a new process and invoking
31 the shell.
33 INPUTS
34 command - Pointer to a null terminated string containing the command
35 to be executed by the shell.
37 mode - Since a pipe is unidirectional, mode can be only one of
39 r: Open for reading. After popen() returns, the stream can
40 be used to read from it, as if it were a normal file stream,
41 in order to get the command's output.
43 w: Open for writing. After popen() returns, the stream can
44 be used to write to it, as if it were a normal file stream,
45 in order to provide the command with some input.
47 RESULT
48 A pointer to a FILE handle or NULL in case of an error. When NULL
49 is returned, then errno is set to indicate the error.
51 NOTES
52 This function must not be used in a shared library or
53 in a threaded application.
55 EXAMPLE
57 BUGS
59 SEE ALSO
60 fclose(), fread(), fwrite(), pipe(), pclose()
62 INTERNALS
64 ******************************************************************************/
66 int pipefds[2];
68 if (!mode || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != '\0')
70 errno = !mode ? EFAULT : EINVAL;
71 return NULL;
74 if (pipe(pipefds) == 0)
76 int fdtopass = (mode[0] == 'r');
78 struct TagItem tags[] =
80 { SYS_Input , 0 },
81 { SYS_Output , 0 },
82 { SYS_Error , SYS_DupStream },
83 { SYS_Asynch , TRUE },
84 { NP_StackSize, Cli()->cli_DefaultStack * CLI_DEFAULTSTACK_UNIT },
85 { TAG_DONE , 0 }
88 tags[fdtopass].ti_Data = (IPTR)__getfdesc(pipefds[fdtopass])->fcb->handle;
89 tags[1 - fdtopass].ti_Data = SYS_DupStream;
91 if (SystemTagList(command, tags) != -1)
93 /* Little trick to deallocate memory which otherwise wouldn't get deallocated */
94 __getfdesc(pipefds[fdtopass])->fcb->handle = BNULL;
95 close(pipefds[fdtopass]);
97 return fdopen(pipefds[1 - fdtopass], NULL);
100 close(pipefds[0]);
101 close(pipefds[1]);
104 return NULL;
105 } /* popen */