2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
8 * execvms.c - execute a shell script, ala VMS
10 * The approach is this:
12 * If the command is a single line, and shorter than WRTLEN (what we
13 * believe to be the maximum line length), we just system() it.
15 * If the command is multi-line, or longer than WRTLEN, we write the
16 * command block to a temp file, splitting long lines (using "-" at
17 * the end of the line to indicate contiuation), and then source that
18 * temp file. We use special logic to make sure we don't continue in
19 * the middle of a quoted string.
21 * 05/04/94 (seiwald) - async multiprocess interface; noop on VMS
22 * 12/20/96 (seiwald) - rewritten to handle multi-line commands well
23 * 01/14/96 (seiwald) - don't put -'s between "'s
24 * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C
44 #define MIN( a, b ) ((a) < (b) ? (a) : (b))
46 /* 1 for the @ and 4 for the .com */
48 char tempnambuf
[ L_tmpnam
+ 1 + 4 ] = {0};
53 void (*func
)( void *closure
, int status
),
58 int rstat
= EXEC_CMD_OK
;
61 /* See if string is more than one line */
62 /* discounting leading/trailing white space */
64 for( s
= string
; *s
&& isspace( *s
); s
++ )
67 e
= p
= strchr( s
, '\n' );
69 while( p
&& isspace( *p
) )
72 /* If multi line or long, write to com file. */
73 /* Otherwise, exec directly. */
75 if( p
&& *p
|| e
- s
> WRTLEN
)
79 /* Create temp file invocation "@sys$scratch:tempfile.com" */
84 (void)tmpnam( tempnambuf
+ 1 );
85 strcat( tempnambuf
, ".com" );
90 if( !( f
= fopen( tempnambuf
+ 1, "w" ) ) )
92 printf( "can't open command file\n" );
93 (*func
)( closure
, EXEC_CMD_FAIL
);
97 /* For each line of the string */
101 char *s
= strchr( string
, '\n' );
102 int len
= s
? s
+ 1 - string
: strlen( string
);
106 /* For each chunk of a line that needs to be split */
111 char *qe
= string
+ MIN( len
, WRTLEN
);
115 /* Look for matching "'s */
118 if( *q
== '"' && ( quote
= !quote
) )
121 /* Back up to opening quote, if in one */
126 fwrite( string
, ( q
- string
), 1, f
);
128 len
-= ( q
- string
);
141 status
= system( tempnambuf
) & 0x07;
143 unlink( tempnambuf
+ 1 );
147 /* Execute single line command */
148 /* Strip trailing newline before execing */
150 status
= system( s
) & 0x07;
153 /* Fail for error or fatal error */
154 /* OK on OK, warning, or info exit */
156 if( status
== 2 || status
== 4 )
157 rstat
= EXEC_CMD_FAIL
;
159 (*func
)( closure
, rstat
);