Initial import of the CDE 2.1.30 sources from the Open Group.

This commit is contained in:
Peter Howkins
2012-03-10 18:21:40 +00:00
commit 83b6996daa
18978 changed files with 3945623 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
XCOMM $XConsortium: Imakefile /main/14 1996/10/09 14:02:22 drk $
#define CplusplusSource YES
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
EXTRA_LOAD_FLAGS = ExtraLoadFlags $(UNSHARED_CXXLIB)
#include <Threads.tmpl>
#include "../../tooltalk.tmpl"
DEFINES =
INCLUDES = -I. -I../../lib
DEPLIBS = TtClientDepLibs
LOCAL_LIBRARIES = TtClientLibs
SYS_LIBRARIES =
#ifdef TtClientExtraLibs
EXTRA_LIBRARIES = TtClientExtraLibs
#endif
SRCS = tttrace.C tttrace_objs.C
OBJS = tttrace.o tttrace_objs.o
NormalCplusplusObjectRule()
ComplexCplusplusProgramTarget(tttrace)

View File

@@ -0,0 +1,11 @@
XCOMM $XConsortium: admindefines /main/2 1996/05/07 19:19:11 drk $
#ifdef sun
/*
* Some tooltalk header files contain inline references to internal
* functions. Attempting to compile with -g fails because these
* inline references expand into unresolved symbols. Until tooltalk
* is fixed force use of -g0. See CDExc20311 for details.
*/
# define DebuggableCplusplusDebugFlags -g0
#endif

View File

@@ -0,0 +1,464 @@
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
//%% (c) Copyright 1993, 1994 Novell, Inc.
//%% $TOG: tttrace.C /main/9 1999/10/14 18:38:47 mgreess $
/*
* @(#)tttrace.C 1.29 95/05/02
*
* Copyright (c) 1993 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#if defined(linux)
# include <sys/poll.h>
#else
# include <poll.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "api/c/tt_c.h"
#include "util/tt_string.h"
#include "util/tt_port.h"
#include "util/tt_gettext.h"
#include "tttrace_objs.h"
#include "tt_options.h"
#define SESSION_TRACE_OP "Session_Trace"
static _Tt_string progname = "tttrace";
pid_t forked_pid = (pid_t) -1;
int makequit = 0;
int poll_timeout = -1;
int exit_status = 0;
int ttfd = 0;
static void install_signal_handler();
static void sig_handler(int);
static pid_t do_fork(_Tt_trace_optobj&);
static void send_session_trace(_Tt_trace_optobj&);
static int tail_pipe(int, _Tt_string&, pid_t, int);
static int open_pipe(_Tt_string&, int*);
static void send_on_exit();
int main(int argc, char **argv)
{
void print_usage_and_exit();
int status = 0;
int pipe_fd = -1;
_Tt_string temp_name; // name of FIFO file
_Tt_trace_optobj myopts; // processes command-line options
setlocale( LC_ALL, "" );
install_signal_handler();
//
// parse command-line options
//
switch(myopts.getopts(argc, argv)) {
case 0:
break;
case 1:
print_usage_and_exit();
break;
case 2:
exit(2);
default:
break;
}
// Open the pipe for reading, if requested
if (myopts.pipe_name().len()) {
status = open_pipe(myopts.pipe_name(), &pipe_fd);
}
if (status == 0) {
// Do fork, or send session_trace requests
pid_t child_pid = 0;
int sink;
switch(myopts.operation_mode()) {
case FORK_COMMAND:
(void) putenv(myopts.envstr());
child_pid = do_fork(myopts);
sink = STDERR_FILENO;
break;
case SESSION_TRACE:
send_session_trace(myopts);
sink = STDOUT_FILENO;
break;
default:
exit(2);
break;
}
_Tt_string outfile;
if (myopts.outfile( outfile ) && (outfile == "-")) {
sink = STDOUT_FILENO;
}
status = tail_pipe(pipe_fd, myopts.pipe_name(), child_pid, sink);
if (pipe_fd > 0) {
if (unlink( myopts.pipe_name()) != 0) {
_Tt_string msg = progname.cat( ": " );
msg = msg.cat( myopts.pipe_name() );
perror( msg );
}
}
}
exit( status );
}
//
// Install sig_handler as the handler for all the signals it handles.
//
static void
install_signal_handler()
{
_Tt_string err;
err = err.cat( ": _tt_sigset(SIG" );
if (_tt_sigset(SIGHUP, &sig_handler) == 0) {
perror( (char *) err.cat("HUP)") );
}
if (_tt_sigset(SIGTERM, &sig_handler) == 0) {
perror( (char *) err.cat("TERM)") );
}
if (_tt_sigset(SIGINT, &sig_handler) == 0) {
perror( (char *) err.cat("INT)") );
}
if (_tt_sigset(SIGUSR1, &sig_handler) == 0) {
perror( (char *) err.cat("USR1)") );
}
if (_tt_sigset(SIGUSR2, &sig_handler) == 0) {
perror( (char *) err.cat("USR2)") );
}
if (_tt_sigset(SIGCHLD, &sig_handler) == 0) {
perror( (char *) err.cat("CHLD)") );
}
if (_tt_sigset(SIGPIPE, &sig_handler) == 0) {
perror( (char *) err.cat("PIPE)") );
}
}
//
// Prints out a usage string and exits.
//
void
print_usage_and_exit()
{
fprintf(stderr,
catgets(_ttcatd, 9, 2,
"Usage: %s [-0FCa][-o outfile] [-S session | command [options]]\n"
" %s [-e script | -f scriptfile][-S session | command [options]]\n"
" -0 Turn off message tracing in session, or run command\n"
" without message tracing (i.e. only API tracing)\n"
" -F Follow all children forked by command or subsequently\n"
" started in session by ttsession(1)\n"
" -C Do not trace ToolTalk API calls\n"
" -a Print all attributes, arguments, and context slots of\n"
" traced messages. Default is single-line summary.\n"
" -e script Read tttracefile(4) settings from script\n"
" -f scriptfile Read tttracefile(4) settings from scriptfile. \"-\": stdin.\n"
" -o outfile Output. \"-\": stdout. default: stdout for session tracing,\n"
" stderr (of tttrace) for command tracing\n"
" -S session Session to trace. default: see tt_default_session()\n"
" command ToolTalk client command to invoke and trace\n"),
(char *) progname, (char *) progname);
exit(1);
}
//
// Global signal handler for tttrace. All signals are handled by this
// function (ie. no signal handlers should be defined in any other files)
//
static void
sig_handler(int sig)
{
int status;
pid_t child;
switch (sig) {
case SIGPIPE:
case SIGHUP:
break;
case SIGCHLD:
child = waitpid( -1, &status, WNOHANG );
if ((child > 0) && (WIFEXITED(status))) {
exit_status = WEXITSTATUS(status);
poll_timeout = 2;
makequit = 1;
}
break;
case SIGTERM:
case SIGINT:
makequit = 1;
break;
}
}
static pid_t do_fork(_Tt_trace_optobj& myopts)
{
int i;
int _tt_getdtablesize(void);
int _tt_restoredtablesize(void);
int maxfds; // max TT fd's
_Tt_string cmd;
switch(forked_pid = fork()) {
case -1:
fprintf(stderr,"%s: fork(): %s\n", (char *)progname,
strerror(errno));
exit(2);
case 0: // child
maxfds = _tt_getdtablesize();
for (i = 3; i < maxfds; i++) {
close(i);
}
_tt_restoredtablesize();
signal(SIGHUP, SIG_IGN);
(void) myopts.command(cmd); // existence of cmd already checked
execvp((char *) cmd, (char * const*)myopts.cargv());
perror((char *) progname);
exit(1);
default: // parent -- wait on child process
break;
}
return forked_pid;
}
static void send_session_trace(_Tt_trace_optobj& myopts)
{
int timeout = 180; // 3-minute timeout
int script_stat;
size_t num_fd = 1;
struct pollfd fds[1];
_Tt_string tmp;
Tt_callback_action tttrace_callback(Tt_message, Tt_pattern);
Tt_message msg;
int mark = tt_mark();
// We must send the message to the specified session. This routine
// is only called when there is an explicit session in the
// options list.
myopts.session(tmp);
ttfd = tt_fd();
tt_session_join((char *) tmp);
msg = tt_prequest_create(TT_SESSION, SESSION_TRACE_OP);
tt_message_arg_add(msg, TT_IN, "string", (char *) 0);
script_stat = myopts.script(tmp);
if (script_stat == 1) { // inline script
tt_message_arg_val_set(msg, 0, (char *) tmp);
}
else if (script_stat == 2) { // script is in filename
tt_message_file_set(msg, (char *) tmp);
}
tt_message_callback_add(msg, tttrace_callback);
Tt_status mstat = tt_message_send(msg);
if (mstat != TT_OK) {
fprintf(stderr, "%s: tt_message_send(): %s\n",
(char *) progname, tt_status_message(mstat));
exit(2);
}
fds[0].fd = ttfd;
fds[0].events = POLLIN | POLLPRI;
fds[0].revents = 0;
int rcode = poll(fds, num_fd, timeout);
if (rcode == -1) {
fprintf(stderr, "%s: Session_Trace: %s\n",
(char *) progname, strerror(ETIMEDOUT));
exit(2);
}
Tt_message inmsg = tt_message_receive();
// Make sure the stop-tracing message is sent upon exit
send_on_exit();
tt_release(mark);
}
Tt_callback_action tttrace_callback(Tt_message msg, Tt_pattern)
{
Tt_status mstat = (Tt_status) tt_message_status(msg);
if (mstat == TT_ERR_NO_MATCH) {
// ttsession does not recognize this message, which
// means an incompatible version of ttsession is being
// used
fprintf(stderr, catgets(_ttcatd, 9, 3,
"%s: session <%s> does not support "
"Session_Trace. Use kill -USR1 instead. "
"See ttsession(1).\n"),
(char *) progname, tt_message_session(msg) );
exit(5);
}
else if (mstat != TT_OK) {
fprintf(stderr, "%s: Session_Trace: %s\n",
(char *) progname, tt_status_message(mstat));
exit(2);
}
return TT_CALLBACK_PROCESSED;
}
static void send_on_exit()
{
Tt_message msg = tt_prequest_create(TT_SESSION, SESSION_TRACE_OP);
tt_message_arg_add(msg, TT_IN, "string",
"version 1; states none; functions none" );
tt_message_send_on_exit(msg);
}
#define MAXLINE 255
static int open_pipe(_Tt_string& pipe_name, int* fd)
{
int quit = 0;
int exit_status = 0;
while ((! quit) && (*fd <= 0)) {
*fd = open((char *) pipe_name, O_RDONLY | O_NDELAY);
if ((*fd < 0) && (errno != EINTR)) {
_Tt_string msg = progname.cat( ": " ).cat(pipe_name);
perror(msg);
exit_status = 2;
}
quit = 1;
}
return exit_status;
}
// No silly cracks about this routine's name, please!
static int tail_pipe(int fd, _Tt_string& pipenm, pid_t child_pid, int sink)
{
int bufsize = MAXLINE;
int nbytes;
int quit = 0;
struct pollfd fds[2];
char buf[MAXLINE];
if (pipenm.len() == 0) {
int done = 0;
while (!done) {
pid_t child_waited_for = waitpid( child_pid, 0, 0 );
if (child_waited_for < 0 && errno == EINTR) continue;
if (child_waited_for < 0 && errno == ECHILD) break;
if (child_waited_for < 0) {
fprintf(stderr, "%s: waitpid(): ",
(char *) progname);
perror(0);
if(errno == ECHILD){
exit(2);
}
}
done = 1;
}
} else {
while (!quit) {
fds[0].fd = fd;
fds[0].events = POLLIN;
fds[0].revents = 0;
fds[1].fd = ttfd;
fds[1].events = POLLIN;
fds[1].revents = 0;
int numfds = poll(fds, ttfd ? 2 : 1, poll_timeout);
if (numfds < 0) {
if (errno != EINTR) {
_Tt_string msg =
progname.cat( ": poll()" );
perror( msg );
exit_status = 2;
quit = 1;
}
else if (makequit) {
quit = 1;
}
continue;
}
else if (numfds == 0) {
quit = 1;
continue;
}
if (fds[ 0 ].revents & POLLHUP) {
if (makequit) {
// Child has exited -- do a last read
while ((nbytes = read(fd,
buf,
bufsize)) > 0) {
write(sink, buf, nbytes);
}
quit = 1;
}
else {
pid_t child_waited_for = waitpid(child_pid,
0, 0 );
if (child_waited_for == child_pid) {
quit = 1;
}
else {
// Tracing is temporarily stopped.
// Periodically wake up to see if it
// has started again.
sleep( 1 );
}
}
}
else if (fds[ 0 ].revents & POLLIN) {
if (makequit) {
quit = 1;
}
else {
nbytes = read(fd, buf, bufsize);
if (nbytes > 0) {
write(sink, buf, nbytes);
}
}
}
if (fds[ 1 ].revents & POLLIN) {
Tt_message msg = tt_message_receive();
if (tt_ptr_error(msg) == TT_ERR_NOMP) {
quit = 1;
}
}
}
if (fd > 0) {
close(fd);
}
}
return exit_status;
}

View File

@@ -0,0 +1,419 @@
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
//%% (c) Copyright 1993, 1994 Novell, Inc.
//%% $XConsortium: tttrace_objs.C /main/3 1995/10/20 17:02:43 rswiston $
/*
* @(#)tttrace_objs.C 1.4 93/11/04
*
* Copyright (c) 1993 by Sun Microsystems, Inc.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "tttrace_objs.h"
#include "util/tt_trace.h"
_Tt_trace_optobj::_Tt_trace_optobj()
{
_msg_tracing = 1; // trace messages and calls by default
_follow = 0; // follow off by default
_api_calls = 1; // trace calls into API by default
_all_attrs = 0; // short form by default
_has_script_inline = 0;
_has_script_filename = 0;
_inline_or_filename = "version 1 ";
_has_outfile = 0;
_has_session = 2; // 1 -> -S option, 2 -> set by default
_has_command = 0;
}
int
_Tt_trace_optobj::getopts(int argc, char** argv)
{
int c; // command-line option char
int i;
extern char* optarg; // command-line option
extern int optind; // option index into argv
extern int opterr; // getopt error value
_Tt_string tmpstr;
_Tt_string tmppath;
_Tt_string _tt_realpath(const _Tt_string&);
_form = NO_FORM;
// needed by the getopt call
opterr = 0;
while ((c = getopt(argc, argv, argstr)) != -1) {
switch (c) {
case '0':
// Turn off msg tracing in <session> or run <command>
// without message tracing
if (_form == SCRIPT_FORM) return 1;
_form = NOSCRIPT_FORM;
_msg_tracing = 0;
break;
case 'F':
// Follow children
if (_form == SCRIPT_FORM) return 1;
_form = NOSCRIPT_FORM;
_follow = 1;
break;
case 'C':
// Do not trace client calls into the TT API
if (_form == SCRIPT_FORM) return 1;
_form = NOSCRIPT_FORM;
_api_calls = 0;
break;
case 'a':
// verbose form
if (_form == SCRIPT_FORM) return 1;
_form = NOSCRIPT_FORM;
_all_attrs = 1;
break;
case 'e':
// command-line script
if (_form == NOSCRIPT_FORM) return 1;
_form = SCRIPT_FORM;
if (!_has_script_filename) {
_inline_or_filename = optarg;
_has_script_inline = 1;
}
else {
return 1;
}
break;
case 'f':
// script file
if (_form == NOSCRIPT_FORM) return 1;
_form = SCRIPT_FORM;
if (!_has_script_inline) {
struct stat sbuf;
tmppath = optarg;
tmpstr = _tt_realpath(tmppath);
_inline_or_filename = tmpstr;
if (stat(_inline_or_filename, &sbuf) != 0) {
fprintf(stderr, "ttrace: %s: %s\n",
(char *)_inline_or_filename,
strerror(errno));
return 2;
}
_has_script_filename = 1;
}
else {
return 1;
}
break;
case 'o':
// outfile
if (_form == SCRIPT_FORM) return 1;
_form = NOSCRIPT_FORM;
_outfile = optarg;
_has_outfile = 1;
break;
case 'S':
// XXX: Note that a Session_Trace message *always*
// gets sent when this option is given, so we have
// to do a tt_open somewhere, and it may as well be
// here, so we can do a tt_default_session if
// necessary.
Tt_status tts;
char* procid;
_session = optarg;
tts = tt_default_session_set(_session);
if (tts != TT_OK) {
fprintf(stderr, "tttrace: "
"tt_default_session_set:\n%s\n",
tt_status_message(tts));
exit(1);
}
procid = tt_open();
tts = tt_ptr_error(procid);
if (tts != TT_OK) {
fprintf(stderr, "tttrace: tt_open:\n%s\n",
tt_status_message(tts));
exit(1);
}
_has_session = 1;
break;
case '?':
default:
// error or help request.
return 1;
}
}
if (optind < argc) {
// Command given after options
if (_has_session == 2) {
// Override the default
_has_session = 0;
}
else if (_has_session == 1) {
// Can't give session and command together
return 1;
}
// command given after options
_command = argv[optind++];
_cargv[0] = (char *) _command;
for (i = 1; optind < argc; ++i, ++optind) {
_cargv[i] = argv[optind];
}
_cargv[i] = (char *) 0;
_has_command = 1;
} else if (_has_session == 2) {
// default -- tttrace with no session or command args
(void) tt_open();
_session = tt_default_session();
}
if ((! _has_outfile) || (_outfile == "-")) {
// We need to set up a FIFO to stuff the output
// into, and give the FIFO name to the command/session
_pipenm = tempnam(NULL, "trace");
if (mkfifo(_pipenm, S_IWUSR|S_IRUSR) == -1) {
fprintf(stderr, "tttrace: mkfifo(\"%s\"): %s\n",
(char *)_pipenm, strerror(errno));
exit(2);
}
}
mkenvstr();
if (_form == NO_FORM) {
_has_script_inline = 1;
_form = SCRIPT_FORM;
}
return 0;
}
int
_Tt_trace_optobj::msg_tracing()
{
return _msg_tracing;
}
int
_Tt_trace_optobj::follow()
{
return _follow;
}
int
_Tt_trace_optobj::api_calls()
{
return _api_calls;
}
int
_Tt_trace_optobj::all_attrs()
{
return _all_attrs;
}
int
_Tt_trace_optobj::script(_Tt_string& script_string)
{
int ret = 0;
if (!_msg_tracing) {
// _msg_tracing is 1 by default, so if it's zero here, it
// means the -0 option was given, so whatever else was
// specified by the command line is overridden by this
script_string = "states none";
return 1;
}
if (_has_script_inline) {
ret = 1;
}
else if (_has_script_filename) {
ret = 2;
}
script_string = _inline_or_filename;
return ret;
}
int
_Tt_trace_optobj::outfile(_Tt_string& filename)
{
filename = _outfile;
if (_has_outfile) {
return 1;
}
else {
return 0;
}
}
int
_Tt_trace_optobj::session(_Tt_string& session_string)
{
session_string = _session;
if (_has_session) {
return 1;
}
else {
return 0;
}
}
int
_Tt_trace_optobj::command(_Tt_string& command_string)
{
command_string = _command;
if (_has_command) {
return 1;
}
else {
return 0;
}
}
char**
_Tt_trace_optobj::cargv()
{
return _cargv;
}
int
_Tt_trace_optobj::mkenvstr()
{
char *val = getenv(TRACE_SCRIPT);
if ((val != 0) && (_form == NO_FORM)) {
_envstr = val;
if (_inline_or_filename[0] == '/' ||
_inline_or_filename[0] == '.') {
_form = NOSCRIPT_FORM; // filename
}
else {
_form = SCRIPT_FORM; // inline script
}
return 1;
}
_envstr = TRACE_SCRIPT;
_envstr = _envstr.cat("=");
if (! _has_script_filename) {
//
// The script will be inline, instead of in a file
//
if ((! _has_outfile) || (_outfile == "-")) {
//
// No -o, so prepend "> pipe; " onto script
//
if (_pipenm.len() > 0) {
_Tt_string output_cmd = "> ";
output_cmd = output_cmd.cat(_pipenm).cat("; ");
_inline_or_filename =
output_cmd.cat( _inline_or_filename );
}
} else {
//
// -o option overrides ">" in script, so
// append "; > outfile" to script
//
if (_outfile.len() > 0) {
_Tt_string output_cmd = "> ";
output_cmd = output_cmd.cat(_outfile);
if (_inline_or_filename.len() > 0) {
_inline_or_filename =
_inline_or_filename.cat("; ");
}
_inline_or_filename =
_inline_or_filename.cat( output_cmd );
}
}
//
} else {
// XXX if both -o and -f, we need to read the file!
}
if (!_has_script_inline && !_has_script_filename) {
if (! _msg_tracing) {
_inline_or_filename =
_inline_or_filename.cat("; states none");
}
if (_follow) {
_inline_or_filename =
_inline_or_filename.cat("; follow on");
}
if (!_api_calls) {
_inline_or_filename =
_inline_or_filename.cat("; functions none");
}
if (_all_attrs) {
_inline_or_filename =
_inline_or_filename.cat("; attributes all");
}
_has_script_inline = 1;
}
_envstr = _envstr.cat(_inline_or_filename);
return 1;
}
int
_Tt_trace_optobj::operation_mode()
{
if (_has_session)
return SESSION_TRACE;
else if (_has_command) // _has_command
return FORK_COMMAND;
else
return -1; // error
}
_Tt_string
_Tt_trace_optobj::envstr()
{
return _envstr;
}
_Tt_string&
_Tt_trace_optobj::pipe_name()
{
return _pipenm;
}

View File

@@ -0,0 +1,120 @@
/*%% (c) Copyright 1993, 1994 Hewlett-Packard Company */
/*%% (c) Copyright 1993, 1994 International Business Machines Corp. */
/*%% (c) Copyright 1993, 1994 Sun Microsystems, Inc. */
/*%% (c) Copyright 1993, 1994 Novell, Inc. */
/*%% $XConsortium: tttrace_objs.h /main/3 1995/10/20 17:02:51 rswiston $ */
/*
* @(#)tttrace_objs.h 1.2 93/11/04
*
* Copyright (c) 1993 by Sun Microsystems, Inc.
*/
#include "util/tt_string.h"
#define NO_FORM 0
#define NOSCRIPT_FORM 1
#define SCRIPT_FORM 2
#define FORK_COMMAND 0
#define SESSION_TRACE 1
#define MAXARGS 256
#define argstr "0FCao:e:f:S:"
class _Tt_trace_optobj : public _Tt_object {
public:
// If msg_tracing is 0, only do client tracing. If 1, then
// do message and client tracing
int msg_tracing();
// If follow is 1, then trace all children forked
int follow();
// If api_calls is 1, trace client calls into the TT API
int api_calls();
// if all_attrs is 1, use long form
int all_attrs();
// if script returns 1, there is a script specified, and
// the text of the script will be in script_string.
// if script returns 2, the script is a filename
int script(_Tt_string& script_string);
// if outfile returns 1, there is an outfile specified, and
// its value will be in filename
int outfile(_Tt_string& filename);
// if session returns 1, there is a session specified, and
// its value will be in session_string
int session(_Tt_string& session_string);
// if command returns 1, there is a command specified, and
// its value will be in command_string
int command(_Tt_string& command_string);
// argv for command
char** cargv();
// envstr returns a string suitable for putenv(), which is
// used if a command is forked
_Tt_string envstr();
// Name of named pipe returned by tempnam
_Tt_string& pipe_name();
// constructor
_Tt_trace_optobj();
// do command-line processing
int getopts(int argc, char** argv);
// tttrace operates in two rundamental modes:
// - fork command, using specified script or script file,
// or command-line args as the script
// - send session_trace requests, using specified script or script file
int operation_mode();
private:
int _form; // discriminates allowed options
int _msg_tracing;
int _follow;
int _api_calls;
int _all_attrs;
int _has_script_inline;
int _has_script_filename;
_Tt_string _inline_or_filename;
int _has_outfile;
_Tt_string _outfile;
int _has_session;
_Tt_string _session;
int _has_command;
_Tt_string _command;
char* _cargv[MAXARGS];
_Tt_string _envstr;
_Tt_string _pipenm;
int mkenvstr(); // makes string for putenv();
};