define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / compiler / clib / popen.c
bloba447bbb1f3e0037bdc9e2b0276b8a3fd9217f08b
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
5 ANSI C function popen().
6 */
8 #include <utility/tagitem.h>
9 #include <proto/dos.h>
10 #include <fcntl.h>
11 #include <unistd.h>
13 #include "__stdio.h"
14 #include "__open.h"
16 #include <errno.h>
19 /*****************************************************************************
21 NAME */
22 #include <stdio.h>
24 FILE * popen (
26 /* SYNOPSIS */
27 const char * command,
28 const char * mode)
30 /* FUNCTION
31 "opens" a process by creating a pipe, spawning a new process and invoking
32 the shell.
34 INPUTS
35 command - Pointer to a null terminated string containing the command
36 to be executed by the shell.
38 mode - Since a pipe is unidirectional, mode can be only one of
40 r: Open for reading. After popen() returns, the stream can
41 be used to read from it, as if it were a normal file stream,
42 in order to get the command's output.
44 w: Open for writing. After popen() returns, the stream can
45 be used to write to it, as if it were a normal file stream,
46 in order to provide the command with some input.
48 RESULT
49 A pointer to a FILE handle or NULL in case of an error. When NULL
50 is returned, then errno is set to indicate the error.
52 NOTES
53 This function must not be used in a shared library or
54 in a threaded application.
56 EXAMPLE
58 BUGS
60 SEE ALSO
61 fclose(), fread(), fwrite(), pipe(), pclose()
63 INTERNALS
65 ******************************************************************************/
67 int pipefds[2];
69 if (!mode || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != '\0')
71 errno = !mode ? EFAULT : EINVAL;
72 return NULL;
75 if (pipe(pipefds) == 0)
77 int fdtopass = (mode[0] == 'r');
79 struct TagItem tags[] =
81 { SYS_Input , 0 },
82 { SYS_Output , 0 },
83 { SYS_Error , SYS_DupStream },
84 { SYS_Asynch , TRUE },
85 { NP_StackSize, Cli()->cli_DefaultStack * CLI_DEFAULTSTACK_UNIT },
86 { TAG_DONE , 0 }
89 tags[fdtopass].ti_Data = (IPTR)__getfdesc(pipefds[fdtopass])->fcb->fh;
90 tags[1 - fdtopass].ti_Data = SYS_DupStream;
92 if (SystemTagList(command, tags) != -1)
94 /* Little trick to deallocate memory which otherwise wouldn't get deallocated */
95 __getfdesc(pipefds[fdtopass])->fcb->fh = NULL;
96 close(pipefds[fdtopass]);
98 return fdopen(pipefds[1 - fdtopass], NULL);
101 close(pipefds[0]);
102 close(pipefds[1]);
105 return NULL;
106 } /* popen */