home *** CD-ROM | disk | FTP | other *** search
- /* 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:
- */
-