home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
shar349.zip
/
src
/
pipes.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-22
|
5KB
|
233 lines
/* pipes.c - simple pipes for MS-DOS
Copyright (C) 1990 Free Software Foundation, Inc.
Thorsten Ohl <ohl@gnu.ai.mit.edu>, 1990
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Header: e:/gnu/shar/RCS/pipes.c 0.1 90/09/25 21:34:19 tho Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <process.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
#include <errno.h>
#include <gnulib.h>
extern char *_pipe_file (int n);
extern int filter_through_command (char *infile, char *outfile,
char *command, ...);
#ifndef DONT_USE_SWAPLIB
/* Since the Microsoft C runtime library has a bug in the redirection
of binary files, it is preferable to use the spawn?? () functions
from the swaplib, since these don't have this problem. But the
swapping is not really needed. */
#include <swaplib.h>
/* But we don't need the fancy swaplib actions, so we provide stubs
to prevent their linkage. */
int swap_smart_p (char *name) { return 0; }
char * swap_invoke_shell (char *cmd, char ***argvp) { return NULL; }
struct swap_respondfile_action *
swap_set_respondfile_actions (void) { return NULL; }
#endif /* DONT_USE_SWAPLIB */
/* Return the name of a temporary file.
(This is not restricted to 2 files, just increase NPIPE.) */
#define NPIPE 2
static void cleanup_pipes (void);
static char *pipe_file[NPIPE] = { NULL, NULL };
static char *tmpdir = NULL;
static int tmpdirlen;
char *
_pipe_file (int n)
{
if (n >= NPIPE || n < 0)
error (1, 0, "no more pipes");
if (!pipe_file[n])
{
if (!tmpdir)
{
/* Initialize. */
atexit (cleanup_pipes);
tmpdir = getenv ("TMP");
if (tmpdir)
{
tmpdirlen = strlen (tmpdir);
if (tmpdir[tmpdirlen - 1] == '/'
|| tmpdir[tmpdirlen - 1] == '\\')
tmpdir[tmpdirlen - 1] = '\0';
}
else
{
tmpdir = ".";
tmpdirlen = 1;
}
}
pipe_file[n] = (char *) xmalloc (tmpdirlen + 14);
sprintf (pipe_file[n], "%s/pipe%04x.%03d", tmpdir, getpid (), n);
}
return pipe_file[n];
}
/* Clean up after we are done. */
void
cleanup_pipes (void)
{
int i;
for (i = 0; i < NPIPE; i++)
unlink (pipe_file[i]);
}
/* Filter the contents of INFILE through COMMAND (with optional
arguments) and place the output in OUTFILE. */
#define IN_MODE (O_RDONLY|O_TEXT)
#define OUT_MODE (O_CREAT|O_TRUNC|O_WRONLY|O_TEXT)
#define OUT_PERM (S_IWRITE|S_IREAD)
int
filter_through_command (char *infile, char *outfile, char *command, ...)
{
int rc;
/* For MS-DOS we know that the stack grows in the right
direction, so we could just say
swap_spawnvp (command, &command);
but we want to write clean code which doesn't make such
assumptions. */
if (command)
{
va_list ap;
char **argv;
int argc = 1;
int i;
int our_stdin;
int our_stdout;
int child_stdin;
int child_stdout;
/* Count the arguments */
va_start (ap, command);
while (va_arg (ap, char *))
argc++;
va_end (ap);
argv = (char **) xmalloc ((argc + 1) * sizeof (char *));
/* Set up the pointers. */
argv[0] = command;
va_start (ap, command);
for (i = 1; i < argc; i++)
argv[i] = va_arg (ap, char *);
va_end (ap);
argv[argc] = NULL;
/* Set up our own pipes,
assuming that the child knows how to setmode (). */
if (infile)
if ((our_stdin = dup (0)) < 0
|| (child_stdin = open (infile, IN_MODE)) < 0
|| dup2 (child_stdin, 0) < 0)
error (1, errno, "can't write to `%s'", command);
if (outfile)
if ((our_stdout = dup (1)) < 0
|| (child_stdout = open (outfile, OUT_MODE, OUT_PERM)) < 0
|| dup2 (child_stdout, 1) < 0)
error (1, errno, "can't read from `%s'", command);
/* Spawn COMMAND (without intervening shell) */
#ifndef DONT_USE_SWAPLIB
rc = swap_spawnvp (command, argv);
#else
rc = spawnvp (P_WAIT, command, argv);
#endif
/* Clean up our pipes. */
if (infile)
{
dup2 (our_stdin, 0);
close (our_stdin);
close (child_stdin);
}
if (outfile)
{
dup2 (our_stdout, 1);
close (our_stdout);
close (child_stdout);
}
free (argv);
}
else
{
/* Invalid arguments. */
rc = -1;
errno = EINVAL;
}
return rc;
}
/*
* Local Variables:
* mode:C
* ChangeLog:ChangeLog
* compile-command:make
* End:
*/