mirror of
https://github.com/boostorg/build.git
synced 2026-02-15 13:02:11 +00:00
167 lines
3.9 KiB
C
167 lines
3.9 KiB
C
/*
|
|
* 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;
|
|
}
|
|
|
|
|
|
void exec_done( void )
|
|
{
|
|
}
|
|
|
|
# endif /* VMS */
|