blob: 729917d356e08587085fa1a16bd988cb5c7b6095 [file] [log] [blame]
/*
* Copyright 1993, 1995 Christopher Seiwald.
*
* This file is part of Jam - see jam.c for Copyright information.
*/
#include "jam.h"
#include "lists.h"
#include "execcmd.h"
#ifdef OS_VMS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iodef.h>
#include <ssdef.h>
#include <descrip.h>
#include <dvidef.h>
#include <clidef.h>
/*
* execvms.c - execute a shell script, ala VMS.
*
* The approach is this:
*
* If the command is a single line, and shorter than WRTLEN (what we believe to
* be the maximum line length), we just system() it.
*
* If the command is multi-line, or longer than WRTLEN, we write the command
* block to a temp file, splitting long lines (using "-" at the end of the line
* to indicate contiuation), and then source that temp file. We use special
* logic to make sure we do not continue in the middle of a quoted string.
*
* 05/04/94 (seiwald) - async multiprocess interface; noop on VMS
* 12/20/96 (seiwald) - rewritten to handle multi-line commands well
* 01/14/96 (seiwald) - do not put -'s between "'s
*/
#define WRTLEN 240
#define MIN( a, b ) ((a) < (b) ? (a) : (b))
/* 1 for the @ and 4 for the .com */
char tempnambuf[ L_tmpnam + 1 + 4 ] = { 0 };
void exec_cmd
(
char * string,
void (* func)( void * closure, int status, timing_info *, char *, char * ),
void * closure,
LIST * shell,
char * rule_name,
char * target
)
{
char * s;
char * e;
cahr * p;
int rstat = EXEC_CMD_OK;
int status;
/* See if string is more than one line discounting leading/trailing white
* space.
*/
for ( s = string; *s && isspace( *s ); ++s );
e = p = strchr( s, '\n' );
while ( p && isspace( *p ) )
++p;
/* If multi line or long, write to com file. Otherwise, exec directly. */
if ( ( p && *p ) || ( e - s > WRTLEN ) )
{
FILE * f;
/* Create temp file invocation "@sys$scratch:tempfile.com". */
if ( !*tempnambuf )
{
tempnambuf[0] = '@';
(void)tmpnam( tempnambuf + 1 );
strcat( tempnambuf, ".com" );
}
/* Open tempfile. */
if ( !( f = fopen( tempnambuf + 1, "w" ) ) )
{
printf( "can't open command file\n" );
(*func)( closure, EXEC_CMD_FAIL );
return;
}
/* For each line of the string. */
while ( *string )
{
char * s = strchr( string, '\n' );
int len = s ? s + 1 - string : strlen( string );
fputc( '$', f );
/* For each chunk of a line that needs to be split. */
while ( len > 0 )
{
char * q = string;
char * qe = string + MIN( len, WRTLEN );
char * qq = q;
int quote = 0;
/* Look for matching "s. */
for ( ; q < qe; ++q )
if ( ( *q == '"' ) && ( quote = !quote ) )
qq = q;
/* Back up to opening quote, if in one. */
if ( quote )
q = qq;
fwrite( string, ( q - string ), 1, f );
len -= ( q - string );
string = q;
if ( len )
{
fputc( '-', f );
fputc( '\n', f );
}
}
}
fclose( f );
status = system( tempnambuf ) & 0x07;
unlink( tempnambuf + 1 );
}
else
{
/* Execute single line command. Strip trailing newline before execing.
*/
if ( e ) *e = 0;
status = system( s ) & 0x07;
}
/* Fail for error or fatal error. OK on OK, warning or info exit. */
if ( ( status == 2 ) || ( status == 4 ) )
rstat = EXEC_CMD_FAIL;
(*func)( closure, rstat );
}
int exec_wait()
{
return 0;
}
# endif /* VMS */