diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 11:58:26 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2010-07-16 11:58:26 +0300 |
commit | 765c7494b3dac62207e6cd57fb839997e237f292 (patch) | |
tree | f7da12ffdb85d9f82671cb3122775b2ce73f7ad9 /vms/vms_popen.c | |
parent | cce5115e21db1702e0617afdca36633e7e2c9eae (diff) | |
download | egawk-765c7494b3dac62207e6cd57fb839997e237f292.tar.gz egawk-765c7494b3dac62207e6cd57fb839997e237f292.tar.bz2 egawk-765c7494b3dac62207e6cd57fb839997e237f292.zip |
Moving to 2.13.2.
Diffstat (limited to 'vms/vms_popen.c')
-rw-r--r-- | vms/vms_popen.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/vms/vms_popen.c b/vms/vms_popen.c new file mode 100644 index 00000000..f0eaa037 --- /dev/null +++ b/vms/vms_popen.c @@ -0,0 +1,168 @@ +/* + * [.vms]vms_popen.c -- substitute routines for missing pipe calls. + */ + +/* + * Copyright (C) 1991 the Free Software Foundation, Inc. + * + * This file is part of GAWK, the GNU implementation of the + * AWK Progamming Language. + * + * GAWK 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. + * + * GAWK 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 GAWK; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef NO_VMS_PIPES + +#include "awk.h" /* really "../awk.h" */ +#include <stdio.h> + +#ifndef PIPES_SIMULATED + +FILE * +popen( const char *command, const char *mode ) +{ + fatal(" Cannot open pipe `%s' (not implemented)", command); + /* NOT REACHED */ + return 0; +} + +int +pclose( FILE *current ) +{ + fatal(" Internal error ('pclose' not implemented)"); + /* NOT REACHED */ + return -1; +} + +int +fork() +{ + fatal(" Internal error ('fork' not implemented)"); + /* NOT REACHED */ + return -1; +} + +#else PIPES_SIMULATED + /* + * Simulate pipes using temporary files; hope that the user + * doesn't expect pipe i/o to be interleaved with other i/o ;-}. + * + * This is essentially the same as the MSDOS version. The + * difference is that redirection is handled using LIB$SPAWN + * rather than constructing a command for system() which uses + * '<' or '>'. + */ +#include "vms.h" +#include <errno.h> + +typedef enum { unopened = 0, reading, writing } pipemode; +static +struct { + char *command; + char *name; + pipemode pmode; +} pipes[_NFILE]; + +FILE * +popen( const char *command, const char *mode ) +{ + FILE *current; + char *name, *mktemp(); + int cur, strcmp(); + pipemode curmode; + + if (strcmp(mode, "r") == 0) + curmode = reading; + else if (strcmp(mode, "w") == 0) + curmode = writing; + else + return NULL; + + /* make a name for the temporary file */ + if ((name = mktemp(strdup("sys$scratch:pipe_XXXX.tmp"))) == 0) + return NULL; + + if (curmode == reading) { + /* an input pipe reads a temporary file created by the command */ + vms_execute(command, (char *)0, name); /* 'command >tempfile' */ + } + if ((current = fopen(name, mode)) == NULL) { + free(name); + return NULL; + } + cur = fileno(current); + pipes[cur].name = name; + pipes[cur].pmode = curmode; + pipes[cur].command = strdup(command); + return current; +} + +int +pclose( FILE *current ) +{ + int rval, cur = fileno(current); + + if (pipes[cur].pmode == unopened) + return -1; /* should never happen */ + + rval = fclose(current); /* close temp file; if reading, we're done */ + if (pipes[cur].pmode == writing) { + /* an output pipe feeds the temporary file to the other program */ + rval = vms_execute(pipes[cur].command, pipes[cur].name, (char *)0); + } + /* clean up */ + unlink(pipes[cur].name); /* get rid of the temporary file */ + pipes[cur].pmode = unopened; + free(pipes[cur].name), pipes[cur].name = 0; + free(pipes[cur].command), pipes[cur].command = 0; + return rval; +} + + /* + * Create a process and execute a command in it. This is essentially + * the same as system() but allows us to specify SYS$INPUT (stdin) + * and/or SYS$OUTPUT (stdout) for the process. + * [With more work it could truly simulate a pipe using mailboxes.] + */ +int +vms_execute( const char *command, const char *input, const char *output ) +{ + Dsc cmd, in, out, *in_p, *out_p; + u_long sts, cmpltn_sts, LIB$SPAWN(); + + cmd.len = strlen(cmd.adr = (char *)command); + if (input) + in.len = strlen(in.adr = (char *)input), in_p = ∈ + else + in_p = 0; + if (output) + out.len = strlen(out.adr = (char *)output), out_p = &out; + else + out_p = 0; + + sts = LIB$SPAWN(&cmd, in_p, out_p, (long *)0, + (Dsc *)0, (u_long *)0, &cmpltn_sts); + + if (vmswork(sts) && vmsfail(cmpltn_sts)) sts = cmpltn_sts; + if (vmsfail(sts)) { + errno = EVMSERR, vaxc$errno = sts; + return -1; + } else + return 0; +} + +#endif /* PIPES_SIMULATED */ + +#endif /*!NO_VMS_PIPES*/ |