Пример #1
0
static int builtin_cd( int line, int argc, char **argv, time_t stoptime )
{
    int result;
    char *dirname;

    if(argc==2) {
        dirname = argv[1];
    } else if(argc==1) {
        struct passwd *p;
        p = getpwuid(getuid());
        if(p) {
            dirname = p->pw_dir;
        } else {
            ftsh_error(FTSH_ERROR_FAILURE,line,"cd: couldn't determine your home directory");
            dirname = 0;
        }
    } else {
        ftsh_error(FTSH_ERROR_SYNTAX,line,"cd: too many arguments");
        result = 0;
    }

    if(dirname) {
        ftsh_error(FTSH_ERROR_COMMAND,line,"CD %s",dirname);
        if(chdir(dirname)==0) {
            result = 1;
        } else {
            ftsh_error(FTSH_ERROR_FAILURE,line,"cd: couldn't move to %s: %s",dirname,strerror(errno));
            result = 0;
        }
    } else {
        result = 0;
    }

    return result;
}
Пример #2
0
static int ast_do_internal( int line, int argc, char **argv, int fds[3], time_t stoptime )
{
	struct ast_function *f;
	builtin_func_t b;
	int oldfds[3];
	int result=0;

	f = hash_table_lookup(ftable,argv[0]);
	b = builtin_lookup(argv[0]);

	if(f) ftsh_error(FTSH_ERROR_STRUCTURE,f->function_line,"FUNCTION %s",f->name->text);

	if(b || variable_frame_push(f->function_line,argc,argv)) {

		if(fds[0]!=0) {
			oldfds[0] = dup(0);
			if(oldfds[0]<0) ftsh_fatal(line,"out of file descriptors");
			dup2(fds[0],0);
		}

		if(fds[1]!=1) {
			oldfds[1] = dup(1);
			if(oldfds[1]<0) ftsh_fatal(line,"out of file descriptors");
			dup2(fds[1],1);
		}

		if(fds[2]!=2) {
			oldfds[2] = dup(2);
			if(oldfds[2]<0) ftsh_fatal(line,"out of file descriptors");
			dup2(fds[2],2);
		}

		if(f) {
			result = ast_group_execute(f->body,stoptime);
		} else {
			result = b(line,argc,argv,stoptime);
		}

		if(fds[2]!=2) {
			dup2(oldfds[2],2);
			close(oldfds[2]);
		}

		if(fds[1]!=1) {
			dup2(oldfds[1],1);
			close(oldfds[1]);
		}

		if(fds[0]!=0) {
			dup2(oldfds[0],0);
			close(oldfds[0]);
		}

		if(f) variable_frame_pop();
	}

	if(f) ftsh_error(FTSH_ERROR_STRUCTURE,f->end_line,"END");

	return result;
}
Пример #3
0
int variable_frame_push( int line, int argc, char **argv )
{
	struct vstack *v;
	int i;

	if(vstackdepth>1000) {
		ftsh_error(FTSH_ERROR_FAILURE,line,"aborting: you have recursed %d times",vstackdepth);
		return 0;
	}

	v = malloc(sizeof(*v));
	if(!v) {
		ftsh_error(FTSH_ERROR_FAILURE,line,"out of memory");
		return 0;
	}

	v->argc = argc;
	v->argv = argv;
	v->rval = 0;
	v->next = head;

	for( i=0; i<argc; i++ ) {
		ftsh_error(FTSH_ERROR_STRUCTURE,line,"${%d} = %s",i,argv[i]);
	}

	head = v;
	vstackdepth++;

	return 1;
}
Пример #4
0
int ast_assign_execute( struct ast_assign *a, time_t stoptime )
{
	int result;

	if(a->expr) {
		char *value;
		char *word;

		value = expr_eval(a->expr,stoptime);
		if(value) {
			word = ast_bareword_execute(a->line,value);
			if(word) {
				ftsh_error(FTSH_ERROR_COMMAND,a->line,"%s=%s",a->name->text,word);
				if(buffer_save(a->name->text,word)) {
					result=1;
				} else {
					ftsh_error(FTSH_ERROR_FAILURE,a->line,"couldn't store variable '%s': %s",a->name->text,strerror(errno));
					result=0;
				}
				free(word);
			} else {
				result = 0;
			}
			free(value);
		} else {
			result=0;
		}
	} else {
		ftsh_error(FTSH_ERROR_COMMAND,a->line,"%s=",a->name->text);
		buffer_delete(a->name->text);
		result = 1;
	}

	return result;
}
Пример #5
0
static void multi_kill( int n, struct multi_fork_status *p, time_t stoptime, int line )
{
	int i;

	for( i=0; i<n; i++ ) {
		if(p[i].state==MULTI_FORK_STATE_CRADLE) {
			p[i].state = MULTI_FORK_STATE_GRAVE;
		} else if(p[i].state==MULTI_FORK_STATE_RUNNING) {
			ftsh_error(FTSH_ERROR_PROCESS,line,"sending SIGTERM to process %d",p[i].pid);
			kill(p[i].pid,SIGTERM);
			kill(-p[i].pid,SIGTERM);
		}
	}

	multi_wait(n,p,time(0)+multi_fork_kill_timeout,line,0);

	while(1) {
		int total=0;
		for( i=0; i<n; i++ ) {
			if(p[i].state==MULTI_FORK_STATE_RUNNING) {
				ftsh_error(FTSH_ERROR_PROCESS,line,"%d: sending SIGKILL to process %d",i,p[i].pid);
				kill(p[i].pid,SIGKILL);
				kill(-p[i].pid,SIGKILL);
				total++;
			}
		}
		if( total==0 ) break;
		if( multi_fork_kill_mode==MULTI_FORK_KILL_MODE_WEAK ) break;
		multi_wait(n,p,time(0)+5,line,0);
	}
}
Пример #6
0
int ast_whileloop_execute( struct ast_whileloop *w, time_t stoptime )
{
	int result=1;
	ftsh_boolean_t b;

	while(1) {
		ftsh_error(FTSH_ERROR_STRUCTURE,w->while_line,"WHILE");

		if(expr_to_boolean(w->expr,&b,stoptime)) {
			if(b) {
				ftsh_error(FTSH_ERROR_STRUCTURE,w->while_line,"WHILE expression is true");

				if(ast_group_execute(w->body,stoptime)) {
					continue;
				} else {
					result = 0;
					break;
				}
			} else {
				ftsh_error(FTSH_ERROR_STRUCTURE,w->while_line,"WHILE expression is false");
				result = 1;
				break;
			}
		} else {
			ftsh_error(FTSH_ERROR_STRUCTURE,w->while_line,"WHILE expression failed");
			result = 0;
			break;
		}
	}

	ftsh_error(FTSH_ERROR_STRUCTURE,w->end_line,"END");

	return result;
}
Пример #7
0
int ast_forloop_execute( struct ast_forloop *f, time_t stoptime )
{
	char *loopname;
	char *name;
	char *line;
	int result=1;

	switch(f->type) {
		case AST_FOR:
			loopname = "FOR";
			break;
		case AST_FORALL:
			loopname = "FORALL";
			break;
		case AST_FORANY:
			loopname = "FORANY";
			break;
	}

	ftsh_error(FTSH_ERROR_STRUCTURE,f->for_line,"%s %s",loopname,f->name->text);

	name = ast_word_execute(f->for_line,f->name);
	if(name) {
		line = ast_expr_list_execute(f->for_line,f->list,stoptime);
		if(line) {
			int argc;
			char **argv;
			if(string_split_quotes( line, &argc, &argv )) {
				switch(f->type) {
					case AST_FOR:
						result = ast_for_execute(f,stoptime,name,argc,argv);
						break;
					case AST_FORANY:
						result = ast_forany_execute(f,stoptime,name,argc,argv);
						break;
					case AST_FORALL:
						result = ast_forall_execute(f,stoptime,name,argc,argv);
						break;
				}
				free(argv);
			} else {
				ftsh_error(FTSH_ERROR_FAILURE,f->for_line,"out of memory!");
				result = 0;
			}
			free(line);		
		}
		free(name);
	} else {
		result = 0;
	}

	ftsh_error(FTSH_ERROR_STRUCTURE,f->end_line,"END");
	return result;
}
Пример #8
0
int ast_try_execute( struct ast_try *t, time_t stoptime )
{
	int result = ast_try_body_execute(t,stoptime);
	if(!result && t->catch_block ) {
		ftsh_error(FTSH_ERROR_STRUCTURE,t->catch_line,"CATCH");
		result = ast_group_execute(t->catch_block,stoptime);
	}

	ftsh_error(FTSH_ERROR_STRUCTURE,t->end_line,"END");

	return result;
}
Пример #9
0
int ast_return_execute( struct ast_return *s, time_t stoptime )
{
	char *value;

	value = expr_eval(s->expr,stoptime);
	if(value) {
		ftsh_error(FTSH_ERROR_STRUCTURE,s->line,"return value is %s",value);
		variable_rval_set(value);
		return 1;
	} else {
		ftsh_error(FTSH_ERROR_FAILURE,s->line,"couldn't compute return value");
		return 0;
	}
}
Пример #10
0
int ast_program_execute( struct ast_group *program, time_t stoptime )
{
	struct ast_group *g;
	struct ast_function *f, *old;

	/*
	First, fill up the function table with all of the functions
	in this entire syntax tree.
	*/

	ftable = hash_table_create(127,hash_string);
	if(!ftable) ftsh_fatal(0,"out of memory");

	for( g=program; g; g=g->next ) {
		if(g->command->type==AST_COMMAND_FUNCTION) {
			f = g->command->u.function;
			old = hash_table_remove(ftable,f->name->text);
			if(old) {
				ftsh_error(FTSH_ERROR_SYNTAX,f->function_line,"function %s is defined twice (first at line %d)",f->name->text,old->function_line);
				return 0;
			}
			if(!hash_table_insert(ftable,f->name->text,f)) {
				ftsh_fatal(f->function_line,"out of memory");
			}
		}
	}

	return ast_group_execute(program,stoptime);
}
Пример #11
0
static int ast_do_simple( int line, int argc, char **argv, int fds[3], time_t stoptime )
{
	char *cmd;
	int length=0;
	int i;

	for( i=0; i<argc; i++ ) {
		length+=strlen(argv[i])+1;
	}

	cmd = xxmalloc(length+1);
	cmd[0] = 0;

	for( i=0; i<argc; i++ ) {
		strcat(cmd,argv[i]);
		strcat(cmd," ");
	}

	ftsh_error(FTSH_ERROR_COMMAND,line,"%s",cmd);

	free(cmd);

	if(hash_table_lookup(ftable,argv[0]) || builtin_lookup(argv[0]) ) {
		return ast_do_internal(line,argc,argv,fds,stoptime);
	} else {
		return ast_do_external(line,argc,argv,fds,stoptime);
	}
}
Пример #12
0
static int ast_redirect_open( struct ast_redirect *r, int line, int fds[3] )
{
	int fd;
	char *target;

	if(!r) return 1;

	target = ast_word_execute( line, r->target );
	if(!target) return 0;

	switch(r->kind) {
		case AST_REDIRECT_FILE:
			switch(r->mode) {
				case AST_REDIRECT_INPUT:
					fd = open(target,O_RDONLY);
					break;
				case AST_REDIRECT_OUTPUT:
					fd = open(target,O_WRONLY|O_CREAT|O_TRUNC,0777);
					break;
				case AST_REDIRECT_APPEND:
					fd = open(target,O_WRONLY|O_CREAT|O_APPEND,0777);
					break;
			}
			break;
		case AST_REDIRECT_BUFFER:
			switch(r->mode) {
				case AST_REDIRECT_INPUT:
					fd = buffer_open_input(target);
					break;
				case AST_REDIRECT_OUTPUT:	
					fd = buffer_open_output(target);
					break;
				case AST_REDIRECT_APPEND:
					fd = buffer_open_append(target);
					break;
			}
			break;
		case AST_REDIRECT_FD:
			fd = fds[atoi(target)];
			break;
	}

	if(fd<0) {
		ftsh_error(FTSH_ERROR_FAILURE,line,"couldn't redirect fd %d to %s: %s",r->source,target,strerror(errno));
		free(target);
		return 0;
	} else {
		r->actual = fd;
		fds[r->source] = fd;
		if(r->next) {
			return ast_redirect_open(r->next,line,fds);
		} else {
			return 1;
		}
	}
}
Пример #13
0
static char * ast_bareword_execute( int linenum, char *line )
{
	int argc;
	char **argv;
	char *result=0;

	if(string_split_quotes(line,&argc,&argv)) {
		if(argc==1) {
			result = xxstrdup(argv[0]);
		} else if(argc>1) {
			ftsh_error(FTSH_ERROR_SYNTAX,linenum,"expected only one word here, but got garbage following '%s'",argv[0]);
		} else {
			ftsh_error(FTSH_ERROR_SYNTAX,linenum,"expected a word here, but found nothing");
		}
		free(argv);
	}

	return result;
}
Пример #14
0
static int ast_do_external( int line, int argc, char **argv, int fds[3], time_t stoptime )
{
	timed_exec_t tresult;
	int status;
	int result;
	pid_t pid;

	tresult = timed_exec(line,argv[0],argv,fds,&pid,&status,stoptime);
	if(tresult==TIMED_EXEC_TIMEOUT) {
		ftsh_error(FTSH_ERROR_FAILURE,line,"%s [%d] ran out of time",argv[0],pid);
		result = 0;
	} else if(tresult==TIMED_EXEC_NOEXEC) {
		ftsh_error(FTSH_ERROR_FAILURE,line,"%s [%d] couldn't be executed: %s",argv[0],pid,strerror(errno));
		result = 0;
	} else {
		result = process_status(argv[0],pid,status,line);
	}

	return result;
}
Пример #15
0
static int builtin_export( int line, int argc, char **argv, time_t stoptime )
{
    char *expr;
    char *name;
    char *value;

    if(argc<2) {
        ftsh_error(FTSH_ERROR_SYNTAX,line,"export: exactly one argument needed");
        return 0;
    } else if(argc>2) {
        ftsh_error(FTSH_ERROR_SYNTAX,line,"export: too many arguments");
        return 0;
    }

    name = argv[1];

    value = buffer_load(name);
    if(!value) value = xxstrdup("");

    expr = malloc(strlen(name)+strlen(value)+3);
    if(!expr) {
        free(name);
        free(value);
        return 0;
    }

    ftsh_error(FTSH_ERROR_COMMAND,line,"EXPORT %s (%s)",name,value);

    sprintf(expr,"%s=%s",name,value);

    /* Depending on the libc, this call may leak memory */
    /* by leaving multiple exprs allocated.  No solution */
    /* except to leak.  Don't export in an infinite loop. */

    putenv(expr);

    free(name);
    free(value);

    return 1;
}
Пример #16
0
int ast_conditional_execute( struct ast_conditional *c, time_t stoptime )
{
	int result;
	ftsh_boolean_t b;

	ftsh_error(FTSH_ERROR_STRUCTURE,c->if_line,"IF");

	if(expr_to_boolean(c->expr,&b,stoptime)) {
		if(b) {
			result = ast_group_execute(c->positive,stoptime);
		} else {
			result = ast_group_execute(c->negative,stoptime);
		}
	} else {
		result = 0;
	}

	ftsh_error(FTSH_ERROR_STRUCTURE,c->end_line,"END");

	return result;
}
Пример #17
0
static int multi_wait( int n, struct multi_fork_status *p, time_t stoptime, int line, int stop_on_failure )
{
	int status;
	int interval;
	int i;
	pid_t pid;
	int total;

	while(1) {
		total=0;

		for(i=0;i<n;i++) {
			if( p[i].state==MULTI_FORK_STATE_GRAVE ) {
				total++;
			}
		}

		if(total>=n) return MULTI_FORK_SUCCESS;
		if(stop_on_failure && cancel_pending()) return MULTI_FORK_FAILURE;

		if(stoptime) {
			interval = stoptime-time(0);
			if(interval<=0) {
				return MULTI_FORK_TIMEOUT;
			} else {
				alarm(interval);
			}
		} else {
			/* Although we hope that this algorithm is correct, there are many ways to get it wrong, so regardless, bail out every 10 seconds and reconsider. */
			alarm(10);
		}

		pid = waitpid(-1,&status,0);
		if(pid>0) {
			ftsh_error(FTSH_ERROR_PROCESS,line,"process %d has completed",pid);
			for(i=0;i<n;i++) {
				if( p[i].state==MULTI_FORK_STATE_RUNNING && p[i].pid==pid ) {
					p[i].status = status;
					p[i].state = MULTI_FORK_STATE_GRAVE;
					if(WIFEXITED(status)&&(WEXITSTATUS(status)==0)) {
						break;
					} else if(stop_on_failure) {
						return MULTI_FORK_FAILURE;
					} else {
						break;
					}
				}
			}
		}
	}
}
Пример #18
0
static int ast_for_execute( struct ast_forloop *f, time_t stoptime, const char *name, int argc, char **argv )
{
	int i=0;
	int result=0;
	for(i=0;i<argc;i++) {
		ftsh_error(FTSH_ERROR_STRUCTURE,f->for_line,"%s=%s",name,argv[i]);
		result = buffer_save(name,argv[i]);
		if(!result) break;
		result = ast_group_execute(f->body,stoptime);
		if(!result) break;
	}

	return result;
}
Пример #19
0
static int multi_start( int n, struct multi_fork_status *p, time_t stoptime, int line )
{
	int i;
	pid_t pid;

	for(i=0;i<n;i++) {
		if(cancel_pending()) return MULTI_FORK_FAILURE;
		if(stoptime && (time(0)>stoptime)) return MULTI_FORK_TIMEOUT;
		pid = fork();
		if(pid==0) {
			return i;
		} else if(pid>0) {
			ftsh_error(FTSH_ERROR_PROCESS,line,"started new process %d",pid);
			p[i].pid = pid;
			p[i].state = MULTI_FORK_STATE_RUNNING;
		} else {
			ftsh_error(FTSH_ERROR_FAILURE,line,"couldn't create new process: %s\n",strerror(errno));
			return MULTI_FORK_FAILURE;
		}
	}

	return MULTI_FORK_SUCCESS;
}
Пример #20
0
static int builtin_exit( int line, int argc, char **argv, time_t stoptime )
{
    int value;

    if(argc<2) {
        value = 0;
    } else {
        if(sscanf(argv[1],"%d",&value)!=1) {
            value = 1;
        }
    }

    ftsh_error(FTSH_ERROR_STRUCTURE,line,"exit: exiting with status %d",value);
    exit(value);
}
Пример #21
0
int variable_shift( int n, int line )
{
	int i;

	if(head->argc>=n) {
		head->argc-=n;
		for(i=0;i<head->argc;i++) {
			head->argv[i] = head->argv[i+n];
		}
		return 1;
	} else {
		ftsh_error(FTSH_ERROR_SYNTAX,line,"cannot shift %d arguments; there are only %d",n,head->argc);
		return 0;
	}
}
Пример #22
0
static int process_status( const char *name, pid_t pid, int status, int line )
{
	int result=0;

	if(WIFEXITED(status)) {
		int code = WEXITSTATUS(status);
		if(code==0) {
			ftsh_error(FTSH_ERROR_PROCESS,line,"%s [%d] exited normally with status %d",name,pid,code);
			result = 1;
		} else {
			ftsh_error(FTSH_ERROR_FAILURE,line,"%s [%d] exited normally status with %d",name,pid,code);
			result = 0;
		}
	} else if(WIFSIGNALED(status)) {
		int sig = WSTOPSIG(status);
		ftsh_error(FTSH_ERROR_FAILURE,line,"%s [%d] exited abnormally with signal %d (%s)",name,pid,sig,string_signal(sig));
		result = 0;
	} else {
		ftsh_error(FTSH_ERROR_FAILURE,line,"%s [%d] exited for unknown reasons (wait status %d)",name,pid,status);
		result = 0;
	}

	return result;
}
Пример #23
0
char * ast_function_execute( int line, int argc, char **argv, time_t stoptime )
{
	struct ast_function *f;
	char *rval = 0;

	if(variable_frame_push(line,argc,argv)) {
		f = hash_table_lookup(ftable,argv[0]);
		if(f) {
			if(ast_group_execute(f->body,stoptime)) {
				if(variable_rval_get()) {
					rval = xxstrdup(variable_rval_get());
					ftsh_error(FTSH_ERROR_STRUCTURE,line,"function %s returns %s",argv[0],rval);
				} else {
					ftsh_error(FTSH_ERROR_FAILURE,line,"function %s did not return a value",argv[0]);
				}
			}
		} else {
			ftsh_error(FTSH_ERROR_FAILURE,line,"function %s is not defined",argv[0]);
		}
		variable_frame_pop();
	}

	return rval;
}
Пример #24
0
char * ast_word_list_execute( int linenum, struct ast_word *w )
{
	char *t, *line = 0;
	int i, len;
	glob_t g;

	while( w ) {
/*
		This isn't correct.
		We need more thought on how to handle wildcards.
		if(strpbrk(w->text,"*[")) {
*/
		if(0) {
			if(glob(w->text,GLOB_FLAGS,0,&g)==0) {
				len=1;
				for(i=0;i<g.gl_pathc;i++) {
					len += strlen(g.gl_pathv[i])+1;
				}
				t = xxmalloc(len);
				t[0]=0;
				for(i=0;i<g.gl_pathc;i++) {
					strcat(t,g.gl_pathv[i]);
					strcat(t," ");
				}
				globfree(&g);
			} else {
				ftsh_error(FTSH_ERROR_FAILURE,linenum,"couldn't expand pattern %s",w->text);
				if(line) free(line);
				return 0;
			}
		} else {
			t=xxstrdup(w->text);
		}

		if(line) {
			line = string_combine_multi( line, " ", t, 0 );
		} else {
			line = t;
		}

		w = w->next;
	}

	return variable_subst(line,linenum);
}
Пример #25
0
static int ast_forall_execute( struct ast_forloop *f, time_t stoptime, const char *name, int argc, char **argv )
{
	int i;
	int pid;
	int result;
	struct multi_fork_status *s;

	s = xxmalloc(sizeof(*s)*argc);

	pid = multi_fork(argc,s,stoptime,f->for_line);
	if(pid>=0) {
		random_init();
		if(stoptime && (time(0)>stoptime)) _exit(1);

		ftsh_error(FTSH_ERROR_STRUCTURE,f->for_line,"%s=%s starting",name,argv[pid]);
		result = buffer_save(name,argv[pid]);
		if(!result) _exit(1);

		result = ast_group_execute(f->body,stoptime);
		if(result) {
			_exit(0);
		} else {
			_exit(1);
		}
	} else {
		for(i=0;i<argc;i++) {
			char str[LINE_MAX];
			if(s[i].state==MULTI_FORK_STATE_GRAVE) {
				snprintf(str,sizeof(str),"%s=%s",name,argv[i]);
				process_status(str,s[i].pid,s[i].status,f->for_line);
			}
		}

		free(s);

		if(pid==MULTI_FORK_SUCCESS) {
			return 1;
		} else {
			return 0;
		}
	}
}
Пример #26
0
static int ast_forany_execute( struct ast_forloop *f, time_t stoptime, const char *name, int argc, char **argv )
{
	int result=0;
	int start = rand()%argc;
	int i = start;

	while(1) {
		ftsh_error(FTSH_ERROR_STRUCTURE,f->for_line,"%s=%s",name,argv[i]);
		result = buffer_save(name,argv[i]);
		if(result) {
			result = ast_group_execute(f->body,stoptime);
			if(result) break;
		}
		i++;
		if(i>=argc) i=0;
		if(i==start) {
			result = 0;
			break;
		}
	}

	return result;
}
Пример #27
0
timed_exec_t timed_exec( int line, const char *path, char **argv, int fds[3], pid_t *pid, int *status, time_t stoptime )
{
	int fresult;
	int pfds[2];
	int child_errno;
	int actual;
	struct multi_fork_status s;

	actual = pipe(pfds);
	if(actual!=0) return TIMED_EXEC_NOEXEC;

	fresult = multi_fork(1,&s,stoptime,line);
	if(fresult>=0) {
		/* Move our standard I/O streams into the expected places. */
		/* It seems that cygwin doesn't like dup2 on the same fd. */

		int i, maxfd;

		for( i=0; i<=2; i++ ) {
			if( fds[i]!=i ) {
				if( dup2(fds[i],i) != i ) {
					ftsh_error(FTSH_ERROR_PROCESS,line,"failure to dup2(%d,%d): %s\n",fds[i],i,strerror(errno));
					goto done;
				}
			}
		}

		/* Close all of the file descriptors that we don't need. */

		maxfd = sysconf( _SC_OPEN_MAX );
		if(maxfd<=0) maxfd = 255;
		for(i=3;i<maxfd;i++) {
			if(i==pfds[1]) continue;
			close(i);
		}

		/* Set the pipe to automatically close after exec. */

		if( fcntl(pfds[1],F_SETFD,FD_CLOEXEC)==0 ) {
			setsid();
			execvp(path,argv);
		}

		/*
		If anything goes wrong, write the errno to the pipe,
		where the parent process can collect and print it.
		*/

		done:
		child_errno = errno;
		full_write(pfds[1],&child_errno,sizeof(child_errno));
		_exit(1);

	} else {

		/*
	        Now clear the pipe.  If it contains an int, then the process
	        forked, but was unable to exec.  Set the reason appropriately.
	        Otherwise, live with what we have.
		*/

		close(pfds[1]);
		actual = full_read(pfds[0],&child_errno,sizeof(int));
		close(pfds[0]);
	
		*status = s.status;
		*pid = s.pid;

		if(actual==sizeof(int)) {
			return TIMED_EXEC_NOEXEC;
		} else if(fresult==MULTI_FORK_SUCCESS) {
			return TIMED_EXEC_SUCCESS;
		} else if(fresult==MULTI_FORK_TIMEOUT) {
			return TIMED_EXEC_TIMEOUT;
		} else {
			return TIMED_EXEC_FAILURE;
		}
	}
}
Пример #28
0
static int builtin_exec( int line, int argc, char **argv, time_t stoptime )
{
    execvp(argv[1],&argv[1]);
    ftsh_error(FTSH_ERROR_FAILURE,line,"exec: %s failed: %s",argv[1],strerror(errno));
    return 0;
}
Пример #29
0
char * variable_subst( char *value, int line )
{
	char *subvalue, *newvalue;
	char *dollar, *start, *end;
	char terminator, oldend;
	int length;
	int withquotes = 0;
	int escape = 0;
 
	while(1) {

		/* Find a non-escaped dollar */

		for( dollar=value; *dollar; dollar++ ) {
			if(escape) {
				escape = 0;
			} else {
				if(*dollar=='\\') {
					escape = 1;
				} else if(*dollar=='$') {
					break;
				}
			}
		}

		/* If we didn't find it, stop. */

		if(!*dollar) return value;

		/* Is the variable name bracketed? */

		if( *(dollar+1)=='{' ) {
			start = dollar+2;
			terminator = '}';
		} else if( *(dollar+1)=='(' ) {
			start = dollar+2;
			terminator = ')';
		} else {
			start = dollar+1;
			terminator = 0;
		}

		if(terminator) {
			end = strchr(start,terminator);
		} else {
			for(end=start;ISVALID(*end);end++) {
				/* nothing */
			}
		}

		if(terminator && !end) {
			ftsh_error(FTSH_ERROR_FAILURE,line,"variable reference began with %c but didn't end",*(dollar+1));
			return 0;
		}

		if((end-start)<1) {
			ftsh_error(FTSH_ERROR_FAILURE,line,"empty variable reference");
			return 0;
		}

		withquotes =
			(dollar>value && *(dollar-1)=='\"') &&
			(*end) &&
			(terminator
				? *(end+1)=='\"'
				: *end=='\"'
			);

		oldend = *end;
		*end = 0;
 
		subvalue = variable_get(start,line,withquotes);
		*end = oldend;

		if(!subvalue) {
			subvalue = xxstrdup("");
		}
 
		length = strlen(value) - (end-dollar) + strlen(subvalue) + 1;

		newvalue = malloc(length);
		if(!newvalue) {
			free(subvalue);
			free(value);
			return 0;
		}

		*dollar = 0;

		strcpy(newvalue,value);
		strcat(newvalue,subvalue);
		if(terminator && *end) {
			strcat(newvalue,end+1);
		} else {
			strcat(newvalue,end);
		}
		free(subvalue);
		free(value);

		value = newvalue;
	}
}
Пример #30
0
static int ast_try_body_execute( struct ast_try *t, time_t stoptime )
{
	int i=0;
	int result=0;
	ftsh_integer_t loops=0;
	int interval = ftsh_expmin;
	int sleeptime;
	time_t starttime, every;

	if(t->time_limit) {
		ftsh_integer_t timeout;
		if(expr_to_integer(t->time_limit->expr,&timeout,stoptime)) {
			timeout *= t->time_limit->units;
			if(stoptime==0) {
				stoptime = timeout+time(0);
			} else {
				stoptime = MIN(stoptime,timeout+time(0));
			}
		} else {
			return 0;
		}
	}

	if(t->every_limit) {
		ftsh_integer_t i;
		if(expr_to_integer(t->every_limit->expr,&i,stoptime)) {
			every = i*t->every_limit->units;
		} else {
			return 0;
		}
	} else {
		every = 0;
	}

	if(t->loop_limit) {
		if(expr_to_integer(t->loop_limit->expr,&loops,stoptime)) {
			/* no problem */
		} else {
			return 0;
		}
	}

	if(!t->time_limit && ! t->loop_limit) {
		loops = 1;
	}

	while(1) {
		ftsh_error(FTSH_ERROR_STRUCTURE,t->try_line,"TRY attempt %d",i);

		starttime = time(0);

		if(ast_group_execute(t->body,stoptime)) {
			result = 1;
			break;
		}

		i++;

		if( stoptime && (time(0) > stoptime) ) {
			ftsh_error(FTSH_ERROR_FAILURE,t->try_line,"TRY time expired");
			result = 0;
			break;
		}
	
		if(loops && (i>=loops)) {
			ftsh_error(FTSH_ERROR_FAILURE,t->try_line,"TRY loop limit reached");
			result = 0;
			break;
		}

		if(every) {
			ftsh_error(FTSH_ERROR_STRUCTURE,t->end_line,"TRY restricted to EVERY %s seconds",every);
			sleeptime = starttime+every-time(0);
			if(sleeptime<0) sleeptime = 0;
			ftsh_error(FTSH_ERROR_STRUCTURE,t->end_line,"TRY sleeping for %d seconds",sleeptime);
		} else {
			if(ftsh_exprand) {
				sleeptime = interval*(1 + 1.0*rand()/RAND_MAX);
			} else {
		       		sleeptime = interval;
			}
			ftsh_error(FTSH_ERROR_STRUCTURE,t->end_line,"TRY sleeping for %d seconds (base %d)",sleeptime,interval);
			interval = MIN(interval*ftsh_expfactor,ftsh_expmax);
		}

		sleep_for(sleeptime);
	}


	return result;
}