Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!lll-lcc!styx!ames!ucbcad!ucbvax!edison.ge.COM!uucp From: uucp@edison.ge.COM (UNIX-to-UNIX Copy) Newsgroups: comp.os.vms Subject: Submission for mod-computers-vax Message-ID: <8704291104.AA29539@edison.GE.COM> Date: Wed, 29-Apr-87 07:04:44 EDT Article-I.D.: edison.8704291104.AA29539 Posted: Wed Apr 29 07:04:44 1987 Date-Received: Sat, 2-May-87 06:44:26 EDT Sender: daemon@ucbvax.BERKELEY.EDU Distribution: world Organization: The ARPA Internet Lines: 112 Path: edison!uvacs!virginia!umd5!cvl!mimsy!oddjob!uwvax!rutgers!ames!ucbcad!ucbvax!CITHEX.CALTECH.EDU!carl From: carl@CITHEX.CALTECH.EDU (Carl J Lydick) Newsgroups: mod.computers.vax Subject: Re: redirection of stdio, et al. Message-ID: <870426221913.011@CitHex.Caltech.Edu> Date: 27 Apr 87 05:19:41 GMT References: <224@unc.cs.unc.edu> Sender: daemon@ucbvax.BERKELEY.EDU Distribution: world Organization: The ARPA Internet Lines: 100 > Does anyone know of any tools that allow command line redirection of > stdio under VMS. Something similar to the way unix and msdos does it is > preferable to some of the methods that have previously been proposed. The following is C code to do at least more or less what you want. First a short rationale for using the technique I did, rather than something else: The C run time library does things like setting up the array of io blocks and parsing the command line for you; while I could have written code to do this, and then linked this code with everything I wrote, I decided to use the default startup routines, and then to do any I/O redirection later. The end result is a routine called ioinit that is used as follows: main(nargs, args) int nargs; char **args; { ... ioinit(&nargs, args); ... } It redirects any or all of stdin, stdout, or stderr, using the same syntax as under UNIX* (with the exception of "here documents"); /******************************************************************************/ /* IOINIT.C -- I/O redirection subroutine. Redirects stdin (< or <<); * stdout (> or >>); or stderr ( 2>, 2>>) * Usage: * main(nargs, args) * { ... * ioinit(&nargs, args); * ... * } */ #include #include typedef char *STR; ioinit(nargs, args) int *nargs; STR *args; { int argnum; for (argnum = 1; argnum < *nargs; ++argnum) { if (strncmp(args[argnum], "<", 1) == 0) { args[argnum] += 1; *nargs = u_reopen(*nargs, args, argnum, "r", stdin); argnum--; } else if (strncmp(args[argnum], ">>", 2) == 0) { args[argnum] += 2; *nargs = u_reopen(*nargs, args, argnum, "a", stdout); argnum--; } else if (strncmp(args[argnum], ">", 1) == 0) { args[argnum] += 1; *nargs = u_reopen(*nargs, args, argnum, "w", stdout); argnum--; } else if (strncmp(args[argnum], "2>>", 3) == 0) { args[argnum] += 3; *nargs = u_reopen(*nargs, args, argnum, "a", stderr); argnum--; } else if (strncmp(args[argnum], "2>", 2) == 0) { args[argnum] += 2; *nargs = u_reopen(*nargs, args, argnum, "w", stderr); argnum--; } } } u_reopen(nargs, args, argnum, acmod, chan) int nargs, argnum; STR *args, acmod; FILE *chan; { char *file; int offset, i, errornum; if (args[argnum][0] != '\0') { offset = 1; file = args[argnum]; } else if ((argnum + 1) < nargs) { offset = 2; file = args[argnum+1]; } else { fprintf(stderr, "Illegal redirection on command line.\n"); exit(1); } for (i = argnum; i < nargs - offset; ++i) args[i] = args[i + offset]; if (((*acmod == ' ' || strcmp(acmod,"a+") == 0) && freopen(file, acmod, chan ,"rfm=stm") != chan) || freopen(file, acmod, chan) != chan) { if (errno == EVMSERR) { errornum = vaxc$errno; fprintf(stderr, "Failure opening redirected stream.\n"); exit(errornum); } else { perror("Failure opening redirected stream."); exit(1); } } return(nargs - offset); } /******************************************************************************/ Using this as a starting point, you should be able to tailor it to your needs.