home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume10
/
pipes.os2
< prev
next >
Wrap
Text File
|
1990-01-19
|
5KB
|
177 lines
Newsgroups: comp.sources.misc
subject: v10i026: Anonymous Pipes in OS/2
summary: emulation of the bsd unix pipe(2), popen(3), and pclose(3) calls
keywords: pipe, handles, fork, execl, spawn, popen, pclose
organization: Racal InterLan Inc., Boxborough, MA (1-800-LAN-TALK)
From: towfiq@interlan.interlan.com (Mark Mehdi Towfigh)
Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
Posting-number: Volume 10, Issue 26
Submitted-by: towfiq@interlan.interlan.com (Mark Mehdi Towfigh)
Archive-name: pipes.os2
Several people in the past have asked about having Unix-like pipe
calls in OS/2. The following source file, adapted from 4.3 BSD Unix,
uses a #define to give you a pipe(2) call, and contains function
definitions for popen(3) and pclose(3). Anyone with problems should
send mail to me; they seem to work fine.
Mark Towfigh
Racal Interlan, Inc.
----------------------------------cut-here------------------------------------
/*
* The following code segment is derived from BSD 4.3 Unix. See
* copyright below. Any bugs, questions, improvements, or problems
* should be sent to Mark Towfigh (towfiq@interlan.interlan.com).
*
* Racal InterLan Inc.
*
* Description of the three functions contained in this file, adapted
* from the BSD 4.3 Manual Pages:
*
* SYNOPSIS
* pipe(fildes)
* int fildes[2];
*
* DESCRIPTION
* The pipe call creates an I/O mechanism called a pipe.
* The file descriptors returned can be used in read and write
* operations. When the pipe is written using the descriptor
* fildes[1] up to 4096 bytes of data are buffered before the
* writing process is suspended. A read using the descriptor
* fildes[0] will pick up the data.
*
* It is assumed that after the pipe has been set up, two (or
* more) cooperating processes (created by subsequent spawn
* calls) will pass data through the pipe with read and write
* calls.
*
* Read calls on an empty pipe (no buffered data) with only one
* end (all write file descriptors closed) returns EOF.
*
* RETURN VALUE
* The function value zero is returned if the pipe was created;
* -1 if an error occurred.
*
* ERRORS
* The pipe call will fail if:
*
* [EMFILE] Too many descriptors are active.
*
* [ENFILE] The system file table is full.
*
* [EFAULT] The fildes buffer is in an invalid area of
* the process's address space.
*
* SYNOPSIS
*
* FILE *popen(command, type)
* char *command, *type;
*
* pclose(stream)
* FILE *stream;
*
* DESCRIPTION
* The arguments to popen are pointers to null-terminated
* strings containing respectively a command line and an
* I/O mode, either "r" for reading or "w" for writing. It
* creates a pipe between the calling process and the command
* to be executed. The value returned is a stream pointer that
* can be used (as appropriate) to write to the standard input
* of the command or read from its standard output.
*
* A stream opened by popen should be closed by pclose, which
* waits for the associated process to terminate and returns
* the exit status of the command.
*
* Because open files are shared, a type "r" command may be
* used as an input filter, and a type "w" as an output filter.
*
* DIAGNOSTICS
* Popen returns a null pointer if files or processes cannot be
* created.
*
* Pclose returns the exit status of the command.
*/
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#include <stdio.h>
#include <stddef.h>
#include <process.h>
#include <errno.h>
#define INCL_DOS
#include <os2.h>
#define tst(a,b) (*mode == 'r'? (b) : (a))
/*
* emulate Unix pipe(2) call
*/
#define pipe(x) DosMakePipe((PHFILE) &x[0], (PHFILE) &x[1], 4096)
#define RDR 0
#define WTR 1
static int popen_pid[20];
FILE *
popen(cmd, mode)
char *cmd;
char *mode;
{
int p[2];
register myside, hisside, save_stream;
if (pipe(p) < 0)
return NULL;
myside = tst(p[WTR], p[RDR]);
hisside = tst(p[RDR], p[WTR]);
/* set up file descriptors for remote function */
save_stream = dup(tst(0, 1)); /* don't lose stdin/out! */
if (dup2(hisside, tst(0, 1)) < 0) {
perror("dup2");
return NULL;
}
(void) close(hisside);
/*
* make sure that we can close our side of the pipe, by
* preventing it from being inherited!
*/
/* set no-inheritance flag */
DosSetFHandState(myside, OPEN_FLAGS_NOINHERIT);
/* execute the command: it will inherit our other file descriptors */
popen_pid[myside] = spawnlp(P_NOWAIT, cmd, cmd, NULL);
/* now restore our previous file descriptors */
if (dup2(save_stream, tst(0, 1)) < 0) { /* retrieve stdin/out */
perror("dup2");
return NULL;
}
(void) close(save_stream);
return fdopen(myside, mode); /* return a FILE pointer */
}
pclose(ptr)
FILE *ptr;
{
register f;
int status;
f = fileno(ptr);
(void) fclose(ptr);
/* wait for process to terminate */
cwait(&status, popen_pid[f], WAIT_GRANDCHILD);
return status;
}