⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task.cc

📁 This Source-Navigator, an IDE for C/C++/Fortran/Java/Tcl/PHP/Python and a host of other languages.
💻 CC
📖 第 1 页 / 共 2 页
字号:
			int n = arg->Length();			for ( int k = 0; k < n; ++k )				{				if ( saw_name )					argv[argp++] = strdup( words[k] );				else					// Skip over name.					saw_name = 1;				}			}		else			{			if ( saw_name )				argv[argp++] = arg->StringVal();			else				// Skip over name.				saw_name = 1;			}		}	argv[argp] = 0;	if ( attrs->async_flag )		CreateAsyncClient( argv );	else		Exec( argv );	for ( argp = first_arg_pos; argp < first_arg_pos + num_args; ++argp )		delete ((char**) argv)[argp];	delete argv;	}void ClientTask::CreateAsyncClient( const char** argv )	{	no_such_program = 0;	task_error = 0;	sequencer->NewClientStarted();	for ( int argc = 0; argv[argc]; ++argc )		;	(void) CreateEvent( "activate", new Value( argv, argc, COPY_ARRAY ) );	}TaskAttr::TaskAttr( char* arg_ID, char* arg_hostname,		    Channel* arg_daemon_channel, int arg_async_flag,		    int arg_ping_flag, int arg_suspend_flag )	{	task_var_ID = arg_ID;	hostname = arg_hostname;	daemon_channel = arg_daemon_channel;	async_flag = arg_async_flag;	ping_flag = arg_ping_flag;	suspend_flag = arg_suspend_flag;	}TaskAttr::~TaskAttr()	{	delete task_var_ID;	delete hostname;	}Value* CreateTaskBuiltIn::DoCall( const_args_list* args_val )	{	// Arguments are:	//	//	var-ID hostname client async ping suspend args...	//	// where "var-ID" and "hostname" are string values, and	// client/async/ping/suspend are boolean flags.	const_args_list& args = *args_val;	int task_args_start = 7;	if ( args.length() <= task_args_start )		{		error->Report( "too few arguments given to create_task" );		return error_value();		}	char* var_ID = GetString( args[0] );	char* hostname = GetString( args[1] );	// If the following values are changed, be sure to also change	// them in CreateTaskBuiltIn::DoSideEffectsCall().	int client_flag = args[2]->IntVal();	int async_flag = args[3]->IntVal();	int ping_flag = args[4]->IntVal();	int suspend_flag = args[5]->IntVal();	Value* input = 0;	if ( args[6]->Type() != TYPE_BOOL || args[6]->BoolVal() )		input = new Value( (Value*) args[6], VAL_CONST );	Channel* channel = sequencer->GetHostDaemon( hostname );	attrs = new TaskAttr( var_ID, hostname, channel, async_flag, ping_flag,				suspend_flag );	// Collect the arguments to the task.	const_args_list task_args;	for ( int i = task_args_start; i < args.length(); ++i )		task_args.append( args[i] );	Value* result;	if ( client_flag )		result = CreateClient( &task_args );	else		{ // Shell client.		if ( async_flag )			result = CreateAsyncShell( &task_args );		else			{			char* command = paste( &task_args );			if ( hostname )				result = RemoteSynchronousShell( command,								input );			else				{				char* input_str;				if ( ! input || (input->Type() == TYPE_BOOL &&						 ! input->BoolVal()) )					input_str = 0;				else					input_str = input->StringVal( '\n' );				result = SynchronousShell( command, input_str );				delete input_str;				}			delete attrs;			delete command;			}		}	Unref( input );	return result;	}void CreateTaskBuiltIn::DoSideEffectsCall( const_args_list* args_val,						int& side_effects_okay )	{	// Check for synchronous shell call; we allow those to be	// for side-effects only.  The corresponding arguments are	// numbers 2 (client/shell flag) and 3 (async flag).	const_args_list& args = *args_val;	if ( args.length() > 3 )		{		int client_flag = args[2]->IntVal();		int async_flag = args[3]->IntVal();		if ( ! client_flag && ! async_flag )			side_effects_okay = 1;		}	Unref( DoCall( args_val ) );	}char* CreateTaskBuiltIn::GetString( const Value* val )	{	if ( val->Type() == TYPE_BOOL && ! val->BoolVal() )		// False means "default".		return 0;	else		return val->StringVal();	}Value* CreateTaskBuiltIn::SynchronousShell( const char* command,						const char* input )	{	FILE* shell = popen_with_input( command, input );	if ( ! shell )		{		warn->Report( "could not execute shell command \"", command,				"\"" );		return error_value();		}	Value* result = GetShellCmdOutput( command, shell, 0 );	int status = pclose_with_input( shell );	if ( status )		{		char status_buf[128];		sprintf( status_buf, "0x%x", status >> 8 );		warn->Report( "shell command \"", command,				"\" terminated with status = ", status_buf );		}	return result;	}Value* CreateTaskBuiltIn::RemoteSynchronousShell( const char* command,							Value* input )	{	int fd = attrs->daemon_channel->WriteFD();	Value* r = create_record();	r->SetField( "command", command );	if ( input )		r->SetField( "input", input );	send_event( fd, "shell", r );	Unref( r );	GlishEvent* e = recv_event( attrs->daemon_channel->ReadFD() );	if ( ! e )		{		warn->Report( "remote daemon died" );		return error_value();		}	int was_okay = e->value->IntVal();	delete e;	if ( ! was_okay )		{		warn->Report( "could not execute shell command \"", command,				"\" on host ", attrs->hostname );		return error_value();		}	Value* result = GetShellCmdOutput( command, 0, 1 );	e = recv_event( attrs->daemon_channel->ReadFD() );	if ( ! e )		{		warn->Report( "remote daemon died" );		return error_value();		}	int status = e->value->IntVal();	delete e;	if ( status )		{		char status_buf[128];		sprintf( status_buf, "0x%x", status >> 8 );		warn->Report( "shell command \"", command,				"\" on host ", attrs->hostname,				" terminated with status = ", status_buf );		}	return result;	}Value* CreateTaskBuiltIn::GetShellCmdOutput( const char* command, FILE* shell,						int is_remote )	{#define MAX_CMD_OUTPUT_LINES 8192	charptr event_values[MAX_CMD_OUTPUT_LINES];#define MAX_SHELL_LINE_LEN 8192	char line_buf[MAX_SHELL_LINE_LEN];	int line_num = 0;#define NEXT_CMD_LINE							\	(is_remote ? NextRemoteShellCmdLine( line_buf ) :		\			NextLocalShellCmdLine( shell, line_buf ))	while ( NEXT_CMD_LINE )		{		int len = strlen( line_buf );		// Remove trailing newline.		if ( len > 0 && line_buf[len - 1] == '\n' )			line_buf[len - 1] = '\0';		if ( ++line_num >= MAX_CMD_OUTPUT_LINES )			{			warn->Report(			"too much data generated by shell command \"",					command, "\"" );			// throw away the remainder of the input			while ( NEXT_CMD_LINE )				;			break;			}		event_values[line_num - 1] = strdup( line_buf );		}	charptr* event_values_copy = new charptr[line_num];	copy_array( event_values, event_values_copy, line_num, charptr );	return new Value( event_values_copy, line_num );	}char* CreateTaskBuiltIn::NextLocalShellCmdLine( FILE* shell, char* line_buf )	{	return fgets( line_buf, MAX_SHELL_LINE_LEN, shell );	}char* CreateTaskBuiltIn::NextRemoteShellCmdLine( char* line_buf )	{	GlishEvent* e = recv_event( attrs->daemon_channel->ReadFD() );	if ( ! e )		{		warn->Report( "remote daemon died" );		return 0;		}	Value* v = e->value;	if ( v->Type() != TYPE_STRING )		{		// This is the "done" event, with a boolean true as value.		delete e;		return 0;		}	char* next_line = v->StringVal();	strcpy( line_buf, next_line );	delete next_line;	delete e;	return line_buf;	}Value* CreateTaskBuiltIn::CreateAsyncShell( const_args_list* args )	{	Task* task = new ShellTask( args, attrs, sequencer );	CheckTaskStatus( task );	return task->AgentRecord();	}Value* CreateTaskBuiltIn::CreateClient( const_args_list* args )	{	if ( attrs->async_flag )		{		if ( attrs->hostname && strcmp( attrs->hostname, "localhost" ) )			error->Report(		"hostname option is incompatible with asynchronous client" );		if ( attrs->suspend_flag )			warn->Report(		"suspend option is not supported for asynchronous clients" );		}	Task* task = new ClientTask( args, attrs, sequencer );	CheckTaskStatus( task );	return task->AgentRecord();	}void CreateTaskBuiltIn::CheckTaskStatus( Task* task )	{	if ( task->NoSuchProgram() )		warn->Report( "no such program, \"", task->Name(), "\"" );	else if ( task->Exec() && task->Exec()->ExecError() )		warn->Report( "could not exec program, \"",				task->Name(), "\"" );	}int same_host( Task* t1, Task* t2 )	{	const char* t1_host = t1->Host();	const char* t2_host = t2->Host();	if ( ! t1_host )		t1_host = "localhost";	if ( ! t2_host )		t2_host = "localhost";	return ! strcmp( t1_host, t2_host );	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -