1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

- popen() now accepts "rb" and "wb" as mode parameters. However, "r+",

"w+" and variants thereof are still unsupported due to the
  unidirectional pipe support in the standard "PIPE:" device.


git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14776 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
Olaf Barthel
2004-11-28 09:33:19 +00:00
parent be2d80a86a
commit 9bf1e01518
2 changed files with 60 additions and 62 deletions

View File

@ -31,6 +31,9 @@
- For sockets, ioctl() and fcntl() now interact on the FIONBIO/FIOASYNC
requests (ioctl) and the O_NOBLOCK/O_ASYNC flags (fcntl).
- popen() now accepts "rb" and "wb" as mode parameters. However, "r+",
"w+" and variants thereof are still unsupported due to the
unidirectional pipe support in the standard "PIPE:" device.
c.lib 1.183 (13.11.2004)

View File

@ -1,5 +1,5 @@
/*
* $Id: stdio_popen.c,v 1.2 2004-08-07 09:15:32 obarthel Exp $
* $Id: stdio_popen.c,v 1.3 2004-11-28 09:33:19 obarthel Exp $
*
* :ts=4
*
@ -94,20 +94,6 @@ pclose(FILE *stream)
/****************************************************************************/
#define SET_TAG(t,v,d) \
do \
{ \
(t)->ti_Tag = (Tag)(v); \
(t)->ti_Data = (ULONG)(d); \
(t)++; \
} \
while(0)
#define END_TAG(t) \
(void)((t)->ti_Tag = TAG_END)
/****************************************************************************/
FILE *
popen(const char *command, const char *type)
{
@ -118,14 +104,10 @@ popen(const char *command, const char *type)
BPTR input = ZERO;
BPTR output = ZERO;
char pipe_file_name[40];
struct TagItem tags[5];
struct TagItem * tag;
FILE * result = NULL;
LONG status;
unsigned long task_address;
time_t now;
size_t type_len;
char actual_type[8];
int i;
ENTER();
@ -150,6 +132,36 @@ popen(const char *command, const char *type)
if(__check_abort_enabled)
__check_abort();
/* The first character selects the access mode: read or write. We don't
support anything else. */
switch(type[0])
{
case 'r':
SHOWMSG("read mode");
break;
case 'w':
SHOWMSG("write mode");
break;
default:
D(("unsupported access mode '%lc'",type[0]));
errno = EINVAL;
goto out;
}
/* The current PIPE: device only supports unidirectional connections. */
if((type[1] == '+') || (type[1] != '\0' && type[2] == '+'))
{
D(("unsupported access mode '%s'",type));
errno = EINVAL;
goto out;
}
#if defined(UNIX_PATH_SEMANTICS)
{
if(__unix_path_semantics)
@ -237,33 +249,10 @@ popen(const char *command, const char *type)
}
#endif /* UNIX_PATH_SEMANTICS */
/* Skip any options following the comma. */
type_len = strlen(type);
for(i = 0 ; i < (int)type_len ; i++)
{
if(type[i] == ',')
{
type_len = i;
break;
}
}
/* Keep only the first few letters of the type string. */
if(type_len > sizeof(actual_type)-1)
type_len = sizeof(actual_type)-1;
memmove(actual_type,type,type_len);
actual_type[type_len] = '\0';
/* The current PIPE: device only supports unidirectional connections. */
if(strcmp(actual_type,"r+") == SAME)
{
SHOWMSG("unsupported access mode");
errno = EINVAL;
goto out;
}
/* Build a (hopefully) unique name for the pipe stream to open. We
construct it from the current process address, converted into
an octal number, followed by the current time (in seconds),
converted into another octal number. */
strcpy(pipe_file_name,"PIPE:");
task_address = (unsigned long)FindTask(NULL);
@ -290,26 +279,27 @@ popen(const char *command, const char *type)
PROFILE_OFF();
if(strcmp(actual_type,"r") == SAME)
/* Now open the input and output streams for the program to launch. */
if(type[0] == 'r')
{
/* Read mode: we want to read the output of the program; the program
should read from "NIL:". */
input = Open("NIL:",MODE_NEWFILE);
if(input != ZERO)
output = Open(pipe_file_name,MODE_NEWFILE);
}
else if (strcmp(actual_type,"w") == SAME)
else
{
/* Write mode: we want to send data to the program; the program
should write to "NIL:". */
input = Open(pipe_file_name,MODE_NEWFILE);
if(input != ZERO)
output = Open("NIL:",MODE_NEWFILE);
}
else
{
errno = EINVAL;
goto out;
}
PROFILE_ON();
/* Check if both I/O streams could be opened. */
if(input == ZERO || output == ZERO)
{
SHOWMSG("couldn't open the streams");
@ -318,18 +308,20 @@ popen(const char *command, const char *type)
goto out;
}
tag = tags;
SET_TAG(tag,SYS_Input, input);
SET_TAG(tag,SYS_Output, output);
SET_TAG(tag,SYS_Asynch, TRUE);
SET_TAG(tag,SYS_UserShell, TRUE);
END_TAG(tag);
PROFILE_OFF();
status = SystemTagList((STRPTR)command,tags);
/* Now try to launch the program. */
status = SystemTags((STRPTR)command,
SYS_Input, input,
SYS_Output, output,
SYS_Asynch, TRUE,
SYS_UserShell, TRUE,
TAG_END);
PROFILE_ON();
/* If launching the program returned -1 then it could not be started.
We'll need to close the I/O streams we opened above. */
if(status == -1)
{
SHOWMSG("SystemTagList() failed");
@ -338,8 +330,11 @@ popen(const char *command, const char *type)
goto out;
}
/* OK, the program is running. Once it terminates, it will automatically
shut down the streams we opened for it. */
input = output = ZERO;
/* Now try to open the pipe we will use to exchange data with the program. */
result = fopen(pipe_file_name,type);
out: