//Function for executing all the basic shell commands
void execs(char *arr[],int rlflag,int rgflag)
{
	int sin=dup(STDIN_FILENO);
	int sout=dup(STDOUT_FILENO);
	pp=fork();
	if(flag==0)
	{
		if(pp<0)
		{
			perror("Error");
			exit(0);
		}
		else if (pp==0)
		{
			if(rlflag==1)
			{
				FILE *fp=fopen(in1,"r");
				dup2(fileno(fp),0);
				fclose(fp);
			}
			if(rgflag==1)
			{
				FILE *fp=fopen(out1,"w+");
				dup2(fileno(fp),1);
				fclose(fp);
			}
			int val=execvp(arr[0],arr);
			if(val<0)
			{
				perror("Command not found");
				exit(0);
			}
		}
		else
		{	int s;
			waitpid(pp,&s,WUNTRACED);
			if(WIFSTOPPED(s))
			{
				strcpy(procs[counters].name,arr[0]);
				procs[counters].pid=pp;
				procs[counters++].status=1;
			}

		}

	}
	else if (flag==1)
	{
		if(pp<0)
		{
			perror("Error");
			exit(0);
		}
		else if (pp==0)
		{	if(rlflag==1)
			{
				FILE *fp=fopen(in1,"r");
				dup2(fileno(fp),0);
			}
			if(rgflag==1)
			{
				FILE *fp=fopen(out1,"w+");
				dup2(fileno(fp),1);
			}

			int val=execvp(arr[0],arr);
			if(val<0)
			{
				perror("Command Not Found");
				exit(0);
			}
		}
		else
		{
			strcpy(procs[counters].name,arr[0]);
			if((strcmp(arr[0],"gedit")==0||strcmp(arr[0],"emacs")==0)&&arr[1]!=NULL)
				strcpy(procs[counters].name2,arr[1]);
			procs[counters].pid=pp;
			procs[counters++].status=1;
		}
	}
	dup2(sout,1);
	dup2(sin,0);
	close(sout);
	close(sin);
}
Пример #2
0
static void summarize (FILE *fp, const char *fmt, char **command, resource_t *resp)
{
    unsigned long r;		/* Elapsed real milliseconds.  */
    unsigned long v;		/* Elapsed virtual (CPU) milliseconds.  */

    if (WIFSTOPPED (resp->waitstatus))
	fprintf (fp, "Command stopped by signal %d\n", WSTOPSIG (resp->waitstatus));
    else if (WIFSIGNALED (resp->waitstatus))
	fprintf (fp, "Command terminated by signal %d\n", WTERMSIG (resp->waitstatus));
    else if (WIFEXITED (resp->waitstatus) && WEXITSTATUS (resp->waitstatus))
	fprintf (fp, "Command exited with non-zero status %d\n", WEXITSTATUS (resp->waitstatus));

    /* Convert all times to milliseconds.  Occasionally, one of these values
       comes out as zero.  Dividing by zero causes problems, so we first
       check the time value.  If it is zero, then we take `evasive action'
       instead of calculating a value.  */

    r = resp->elapsed.tv_sec * 1000 + resp->elapsed.tv_usec / 1000;

    v = resp->ru.ru_utime.tv_sec * 1000 + resp->ru.ru_utime.TV_MSEC +
	resp->ru.ru_stime.tv_sec * 1000 + resp->ru.ru_stime.TV_MSEC;

    while (*fmt)
    {
	switch (*fmt)
	{
	    case '%':
		switch (*++fmt)
		{
		    case '%':		/* Literal '%'.  */
			putc ('%', fp);
			break;
		    case 'C':		/* The command that got timed.  */
			fprintargv (fp, command, " ");
			break;
		    case 'D':		/* Average unshared data size.  */
			fprintf (fp, "%lu",
				MSEC_TO_TICKS (v) == 0 ? 0 :
				ptok ((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS (v) +
				ptok ((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS (v));
			break;
		    case 'E':		/* Elapsed real (wall clock) time.  */
			if (resp->elapsed.tv_sec >= 3600)	/* One hour -> h:m:s.  */
			    fprintf (fp, "%ldh %ldm %02lds",
				    resp->elapsed.tv_sec / 3600,
				    (resp->elapsed.tv_sec % 3600) / 60,
				    resp->elapsed.tv_sec % 60);
			else
			    fprintf (fp, "%ldm %ld.%02lds",	/* -> m:s.  */
				    resp->elapsed.tv_sec / 60,
				    resp->elapsed.tv_sec % 60,
				    resp->elapsed.tv_usec / 10000);
			break;
		    case 'F':		/* Major page faults.  */
			fprintf (fp, "%ld", resp->ru.ru_majflt);
			break;
		    case 'I':		/* Inputs.  */
			fprintf (fp, "%ld", resp->ru.ru_inblock);
			break;
		    case 'K':		/* Average mem usage == data+stack+text.  */
			fprintf (fp, "%lu",
				MSEC_TO_TICKS (v) == 0 ? 0 :
				ptok ((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS (v) +
				ptok ((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS (v) +
				ptok ((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS (v));
			break;
		    case 'M':		/* Maximum resident set size.  */
			fprintf (fp, "%lu", ptok ((UL) resp->ru.ru_maxrss));
			break;
		    case 'O':		/* Outputs.  */
			fprintf (fp, "%ld", resp->ru.ru_oublock);
			break;
		    case 'P':		/* Percent of CPU this job got.  */
			/* % cpu is (total cpu time)/(elapsed time).  */
			if (r > 0)
			    fprintf (fp, "%lu%%", (v * 100 / r));
			else
			    fprintf (fp, "?%%");
			break;
		    case 'R':		/* Minor page faults (reclaims).  */
			fprintf (fp, "%ld", resp->ru.ru_minflt);
			break;
		    case 'S':		/* System time.  */
			fprintf (fp, "%ld.%02ld",
				resp->ru.ru_stime.tv_sec,
				resp->ru.ru_stime.TV_MSEC / 10);
			break;
		    case 'T':		/* System time.  */
			if (resp->ru.ru_stime.tv_sec >= 3600)	/* One hour -> h:m:s.  */
			    fprintf (fp, "%ldh %ldm %02lds",
				    resp->ru.ru_stime.tv_sec / 3600,
				    (resp->ru.ru_stime.tv_sec % 3600) / 60,
				    resp->ru.ru_stime.tv_sec % 60);
			else
			    fprintf (fp, "%ldm %ld.%02lds",	/* -> m:s.  */
				    resp->ru.ru_stime.tv_sec / 60,
				    resp->ru.ru_stime.tv_sec % 60,
				    resp->ru.ru_stime.tv_usec / 10000);
			break;
		    case 'U':		/* User time.  */
			fprintf (fp, "%ld.%02ld",
				resp->ru.ru_utime.tv_sec,
				resp->ru.ru_utime.TV_MSEC / 10);
			break;
		    case 'u':		/* User time.  */
			if (resp->ru.ru_utime.tv_sec >= 3600)	/* One hour -> h:m:s.  */
			    fprintf (fp, "%ldh %ldm %02lds",
				    resp->ru.ru_utime.tv_sec / 3600,
				    (resp->ru.ru_utime.tv_sec % 3600) / 60,
				    resp->ru.ru_utime.tv_sec % 60);
			else
			    fprintf (fp, "%ldm %ld.%02lds",	/* -> m:s.  */
				    resp->ru.ru_utime.tv_sec / 60,
				    resp->ru.ru_utime.tv_sec % 60,
				    resp->ru.ru_utime.tv_usec / 10000);
			break;
		    case 'W':		/* Times swapped out.  */
			fprintf (fp, "%ld", resp->ru.ru_nswap);
			break;
		    case 'X':		/* Average shared text size.  */
			fprintf (fp, "%lu",
				MSEC_TO_TICKS (v) == 0 ? 0 :
				ptok ((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS (v));
			break;
		    case 'Z':		/* Page size.  */
			fprintf (fp, "%d", getpagesize ());
			break;
		    case 'c':		/* Involuntary context switches.  */
			fprintf (fp, "%ld", resp->ru.ru_nivcsw);
			break;
		    case 'e':		/* Elapsed real time in seconds.  */
			fprintf (fp, "%ld.%02ld",
				resp->elapsed.tv_sec,
				resp->elapsed.tv_usec / 10000);
			break;
		    case 'k':		/* Signals delivered.  */
			fprintf (fp, "%ld", resp->ru.ru_nsignals);
			break;
		    case 'p':		/* Average stack segment.  */
			fprintf (fp, "%lu",
				MSEC_TO_TICKS (v) == 0 ? 0 :
				ptok ((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS (v));
			break;
		    case 'r':		/* Incoming socket messages received.  */
			fprintf (fp, "%ld", resp->ru.ru_msgrcv);
			break;
		    case 's':		/* Outgoing socket messages sent.  */
			fprintf (fp, "%ld", resp->ru.ru_msgsnd);
			break;
		    case 't':		/* Average resident set size.  */
			fprintf (fp, "%lu",
				MSEC_TO_TICKS (v) == 0 ? 0 :
				ptok ((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS (v));
			break;
		    case 'w':		/* Voluntary context switches.  */
			fprintf (fp, "%ld", resp->ru.ru_nvcsw);
			break;
		    case 'x':		/* Exit status.  */
			fprintf (fp, "%d", WEXITSTATUS (resp->waitstatus));
			break;
		    case '\0':
			putc ('?', fp);
			return;
		    default:
			putc ('?', fp);
			putc (*fmt, fp);
		}
		++fmt;
		break;

	    case '\\':		/* Format escape.  */
		switch (*++fmt)
		{
		    case 't':
			putc ('\t', fp);
			break;
		    case 'n':
			putc ('\n', fp);
			break;
		    case '\\':
			putc ('\\', fp);
			break;
		    default:
			putc ('?', fp);
			putc ('\\', fp);
			putc (*fmt, fp);
		}
		++fmt;
		break;

	    default:
		putc (*fmt++, fp);
	}

	if (ferror (fp))
	    bb_error_msg_and_die("write error");
    }
    putc ('\n', fp);

    if (ferror (fp))
	bb_error_msg_and_die("write error");
}
Пример #3
0
int printYAMLJobInfo(FILE *out, int indent, const char* tag, const JobInfo* job) {
    /* purpose: format the job information into the given stream as YAML.
     * paramtr: out (IO): the stream
     *          indent (IN): indentation level
     *          tag (IN): name to use for element tags.
     *          job (IN): job info to print.
     * returns: number of characters put into buffer (buffer length)
     */

    /* sanity check */
    if (!job->isValid) {
        return 0;
    }

    /* start tag with indentation */
    fprintf(out, "%*s%s:\n", indent, "", tag);
    fprintf(out, "%*s  start: %s\n", indent, "", 
            fmtisodate(job->start.tv_sec, job->start.tv_usec));
    fprintf(out, "%*s  duration: %.3f\n", indent, "", 
            doubletime(job->finish) - doubletime(job->start));

    /* optional attribute: application process id */
    if (job->child != 0) {
        fprintf(out, "%*s  pid: %d\n", indent, "", job->child);
    }

    /* <usage> */
    printYAMLUseInfo(out, indent+2, "usage", &job->use);

    int status = (int) job->status;

    /* <status>: open tag */
    fprintf(out, "%*sstatus:\n%*sraw: %d\n",
                 indent+2, "", indent+4, "", status);

    /* <status>: cases of completion */
    if (status < 0) {
        /* <failure> */
        fprintf(out, "%*sfailure_error: %d   %s%s\n", indent+4, "",
                     job->saverr,
                     job->prefix && job->prefix[0] ? job->prefix : "",
                     strerror(job->saverr));
    } else if (WIFEXITED(status)) {
        fprintf(out, "%*sregular_exitcode: %d\n", indent+4, "",
                     WEXITSTATUS(status));
    } else if (WIFSIGNALED(status)) {
        /* result = 128 + WTERMSIG(status); */
        fprintf(out, "%*ssignalled_signal: %u\n", indent+4, "",
                     WTERMSIG(status));
        fprintf(out, "%*ssingalled_name: %s\n", indent+4, "",
                     sys_siglist[WTERMSIG(status)]);
#ifdef WCOREDUMP
        fprintf(out, "%*scorefile: %s\n", indent+4, "",
                     WCOREDUMP(status) ? "true" : "false");
#endif
    } else if (WIFSTOPPED(status)) {
        fprintf(out, "%*ssuspended_signal: %u\n", indent+4, "",
                     WSTOPSIG(status));
        fprintf(out, "%*ssuspended_name: %s\n", indent+4, "",
                sys_siglist[WSTOPSIG(status)]);
    } /* FIXME: else? */

    /* <executable> */
    printYAMLStatInfo(out, indent+2, "executable", &job->executable, 1, 0, 1);

    /* alternative 1: new-style <argument-vector> */
    fprintf(out, "%*sargument_vector:\n", indent+2, "");
    if (job->argc > 1) {
        /* content are the CLI args */
        int i;
        for (i=1; i<job->argc; ++i) {
            fprintf(out, "%*s- %s\n", indent+4, "", job->argv[i]);
        }
    }

    /* <proc>s */
    printYAMLProcInfo(out, indent+2, job->children);

    return 0;
}
Пример #4
0
static void handle_child(pid_t childpid, int childstatus)
{
	unsigned int i;
	int slot;

	switch (childpid) {
	case 0:
		//debugf("Nothing changed. children:%d\n", shm->running_childs);
		break;

	case -1:
		if (shm->exit_reason != STILL_RUNNING)
			return;

		if (errno == ECHILD) {
			debugf("All children exited!\n");
			for_each_pidslot(i) {
				if (shm->pids[i] != EMPTY_PIDSLOT) {
					if (pid_alive(shm->pids[i]) == -1) {
						debugf("Removing %d from pidmap\n", shm->pids[i]);
						shm->pids[i] = EMPTY_PIDSLOT;
						shm->running_childs--;
					} else {
						debugf("%d looks still alive! ignoring.\n", shm->pids[i]);
					}
				}
			}
			break;
		}
		output(0, "error! (%s)\n", strerror(errno));
		break;

	default:
		debugf("Something happened to pid %d\n", childpid);

		if (WIFEXITED(childstatus)) {

			slot = find_pid_slot(childpid);
			if (slot == PIDSLOT_NOT_FOUND) {
				/* If we reaped it, it wouldn't show up, so check that. */
				if (shm->last_reaped != childpid) {
					outputerr("## Couldn't find pid slot for %d\n", childpid);
					shm->exit_reason = EXIT_LOST_PID_SLOT;
					dump_pid_slots();
				}
			} else {
				debugf("Child %d exited after %ld syscalls.\n", childpid, shm->child_syscall_count[slot]);
				reap_child(childpid);
			}
			break;

		} else if (WIFSIGNALED(childstatus)) {

			switch (WTERMSIG(childstatus)) {
			case SIGALRM:
				debugf("got a alarm signal from pid %d\n", childpid);
				break;
			case SIGFPE:
			case SIGSEGV:
			case SIGKILL:
			case SIGPIPE:
			case SIGABRT:
				debugf("got a signal from pid %d (%s)\n", childpid, strsignal(WTERMSIG(childstatus)));
				reap_child(childpid);
				break;
			default:
				debugf("** Child got an unhandled signal (%d)\n", WTERMSIG(childstatus));
				break;
			}
			break;

		} else if (WIFSTOPPED(childstatus)) {

			switch (WSTOPSIG(childstatus)) {
			case SIGALRM:
				debugf("got an alarm signal from pid %d\n", childpid);
				break;
			case SIGSTOP:
				debugf("Sending PTRACE_DETACH (and then KILL)\n");
				//ptrace(PTRACE_DETACH, childpid, NULL, NULL);
				kill(childpid, SIGKILL);
				reap_child(childpid);
				break;
			case SIGFPE:
			case SIGSEGV:
			case SIGKILL:
			case SIGPIPE:
			case SIGABRT:
				debugf("Child %d was stopped by %s\n", childpid, strsignal(WTERMSIG(childstatus)));
				reap_child(childpid);
				break;
			default:
				debugf("Child %d was stopped by unhandled signal (%s).\n", childpid, strsignal(WSTOPSIG(childstatus)));
				break;
			}
			break;

		} else if (WIFCONTINUED(childstatus)) {
			break;
		} else {
			output(0, "erk, wtf\n");
		}
	}
Пример #5
0
/* exec another program, putting result in output.
 * This is simple version of full run_phase. */
void
run_simple_program (char *name, char **argv, char *output)
{
	int forkpid;
	int fdout;
	int waitpid;
	int waitstatus;
	int termsig;

	/* fork a process */
	forkpid = fork();
	if (forkpid == -1) {
		error("no more processes");
		cleanup ();
		do_exit (RC_SYSTEM_ERROR);
		/* NOTREACHED */
	}

	if (forkpid == 0) {
		/* child */
		if ((fdout = creat (output, 0666)) == -1) {
			error ("cannot create output file %s", output);
			cleanup ();
			do_exit (RC_SYSTEM_ERROR);
			/* NOTREACHED */
		}
	    	dup2 (fdout, fileno(stdout));

		my_execv(name, argv);
	} else {
		/* parent */
		int procid;	/* id of the /proc file */
		while ((waitpid = wait (&waitstatus)) != forkpid) {
			if (waitpid == -1) {
				error("bad return from wait");
				cleanup();
				do_exit(RC_SYSTEM_ERROR);
				/* NOTREACHED */
			}
		}
		if (WIFSTOPPED(waitstatus)) {
			termsig = WSTOPSIG(waitstatus);
			error("STOPPED signal received from %s", name);
			cleanup();
			do_exit(RC_SYSTEM_ERROR);
			/* NOTREACHED */
		} else if (WIFEXITED(waitstatus)) {
		        int status = WEXITSTATUS(waitstatus);
			if (status != RC_OKAY) {
				/* internal error */
				/* most internal errors use exit code of 1 */
				internal_error("%s returned non-zero status %d",
					name, status);
			} 
			return;
		} else if(WIFSIGNALED(waitstatus)){
			termsig = WTERMSIG(waitstatus);
			switch (termsig) {
			case SIGHUP:
			case SIGINT:
			case SIGQUIT:
			case SIGKILL:
			case SIGTERM:
				error("%s died due to signal %d", name, termsig);
				break;
			default:
				internal_error("%s died due to signal %d",
					       name, termsig);
				break;
			}
#ifndef __CYGWIN__
			if(waitstatus & WCOREFLAG) {
				error("core dumped");
			}
#endif
			if (termsig == SIGKILL) {
				error("Probably caused by running out of swap space -- check %s", LOGFILE);
			}
			cleanup();
			do_exit(RC_SYSTEM_ERROR);
		} else {
			/* cannot happen, I think! */
			internal_error("driver exec'ing is confused");
			return;
		}
	}
}
Пример #6
0
void userspace(union uml_pt_regs *regs)
{
	int err, status, op, pt_syscall_parm, pid = userspace_pid[0];
	int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/

	restore_registers(regs);
		
	local_using_sysemu = get_using_sysemu();

	pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
	err = ptrace(pt_syscall_parm, pid, 0, 0);

	if(err)
		panic("userspace - PTRACE_%s failed, errno = %d\n",
		       local_using_sysemu ? "SYSEMU" : "SYSCALL", errno);
	while(1){
		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
		if(err < 0)
			panic("userspace - waitpid failed, errno = %d\n", 
			      errno);

		regs->skas.is_user = 1;
		save_registers(regs);

		if(WIFSTOPPED(status)){
		  	switch(WSTOPSIG(status)){
			case SIGSEGV:
				handle_segv(pid);
				break;
			case SIGTRAP:
			        handle_trap(pid, regs, local_using_sysemu);
				break;
			case SIGIO:
			case SIGVTALRM:
			case SIGILL:
			case SIGBUS:
			case SIGFPE:
			case SIGWINCH:
				user_signal(WSTOPSIG(status), regs);
				break;
			default:
			        printk("userspace - child stopped with signal "
				       "%d\n", WSTOPSIG(status));
			}
			interrupt_end();
		}

		restore_registers(regs);

		/*Now we ended the syscall, so re-read local_using_sysemu.*/
		local_using_sysemu = get_using_sysemu();
		pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;

		op = singlestepping(NULL) ? PTRACE_SINGLESTEP :
			pt_syscall_parm;

		err = ptrace(op, pid, 0, 0);
		if(err)
			panic("userspace - PTRACE_%s failed, "
			      "errno = %d\n",
			      local_using_sysemu ? "SYSEMU" : "SYSCALL", errno);
	}
}
Пример #7
0
static void parent(pid_t child_pid)
{
	int status;
	bool exec_done = 0;

	while (1)
	{
		/* Wait for child status to change: */
		wait(&status);

		if (WIFEXITED(status)) {
//			printf("Child exit with status %d\n", WEXITSTATUS(status));
			exit(WEXITSTATUS(status));
		}
		if (WIFSIGNALED(status)) {
			fprintf(stderr, "Child exit due to signal %d\n", WTERMSIG(status));
			exit(0);
		}
		if (!WIFSTOPPED(status)) {
			fprintf(stderr, "wait() returned unhandled status 0x%x\n", status);
			exit(0);
		}
		if (WSTOPSIG(status) == SIGTRAP) {
			/* Note that there are *three* reasons why the child might stop
			 * with SIGTRAP:
			 *  1) syscall entry
			 *  2) syscall exit
			 *  3) child calls exec
			 */
			siginfo_t info;
			ptrace(PTRACE_GETSIGINFO, child_pid, 0, &info);
			if (info.si_code != SIGTRAP) {
				if (exec_done) {
					fprintf(stderr, "CHILD PERFORMED EXEC\n");
					kill(child_pid, SIGKILL);
					abort();
				} else {
					exec_done = 1;
				}
			} else {
#if 0
				sc_number = ptrace(PTRACE_PEEKUSER, child_pid, SC_NUMBER, NULL);
//				sc_retcode = ptrace(PTRACE_PEEKUSER, child_pid, SC_RETCODE, NULL);
//				printf("SIGTRAP: syscall %ld, rc = %ld\n", sc_number, sc_retcode);
				if (sc_number<0 || sc_number>512 || !is_allowed_syscall[sc_number]) {
					fprintf(stderr, "BLOCKED SYSCALL %ld\n", sc_number);
					kill(child_pid, SIGKILL);
					abort();
				}
#endif
			}
		} else if (WSTOPSIG(status) == 31) {
			long sc_number = ptrace(PTRACE_PEEKUSER, child_pid, SC_NUMBER, NULL);
			fprintf(stderr, "BLOCKED SYSCALL %ld\n", sc_number);
			kill(child_pid, SIGKILL);
			exit(1);
		} else {
			if (WSTOPSIG(status) != 19) {
				fprintf(stderr, "Child stopped due to signal %d\n", WSTOPSIG(status));
				kill(child_pid, SIGKILL);
				exit(1);
			}
		}
//		fflush(stdout);

		/* Resume child, requesting that it stops again on syscall enter/exit
		 * (in addition to any other reason why it might stop):
		 */
//		ptrace(PTRACE_SYSCALL, child_pid, NULL, NULL);
		ptrace(PTRACE_CONT, child_pid, NULL, NULL);
	}
}
int VectorMatch::computVectorMatch(std::string cmpFile, int k, int p,std::chrono::duration<double>* time_elapse){


    //get all that shared mem stuff set up
    int shmId;          // ID of shared memory segment
    key_t shmKey = 123460;      // key to pass to shmget(), key_t is an IPC key type defined in sys/types
    int shmFlag = IPC_CREAT | 0666; // Flag to create with rw permissions
    pid_t pid;
    unsigned long * sharedIndexPtr = NULL;

    //store the pids for the procs
    std::set<pid_t> minvan;


    //start and end for times the proc work
    std::chrono::time_point<std::chrono::system_clock> start, end;


    long cmpVecPos = 0;

    try{
        cmpVecPos = nameMap->at(cmpFile);
    }
    catch(...){
        std::cerr<<"File not found in the database for comapring\n";
        return 0;
    }



    //get the number of lines each proc gets to process
    int divNum = nameMap->size() / p;


    //create the shared memeory
    if ((shmId = shmget(shmKey, (p * k * sizeof(shmKeyPair)) , shmFlag)) < 0){
        std::cerr << "Init: Failed to initialize shared memory (" << shmId << ")" << std::endl;
        return -1;
    }

    shmKeyPair* shm;
    //get the shared memory in the right address space
    if ((shm = (shmKeyPair *)shmat(shmId, NULL, 0)) == (shmKeyPair *) -1){
        std::cerr << "Init: Failed to attach shared memory (" << shmId << ")" << std::endl;
        return -1;
    }



    start = std::chrono::system_clock::now();
    //this loops through and forks enough procs to process each file
    // 1 proc per file
    for(int i = 0; i < p; i++){
        pid = fork();

        if ( pid < 0 ){
            std::cerr << "Could not fork!!! ("<< pid <<")" << std::endl;
            return -1;
        }

        //this is the child taking over
        else if (pid == 0){


            long lineStatus = 0;
            int procNum = i;
            //store the results of the vector
            std::map<float,int> results;


            int topBound = ((procNum * divNum) + divNum);
            if(i == (p-1)){
                topBound += nameMap->size() % p;
            }


            //get the distances and store them into a map that auto sorts by distance
            for(long j = procNum * divNum; j < topBound -1; j++){
                //add the distance to the results map
                results.insert(std::pair<float,long>(findDist(cmpVecPos,j),j*lineLength));


            }



            //add the results to the proper segment of the shared memory
            int count = procNum * k;
            int kcount = 0;

            for(auto& pair : results){
                if(kcount >= k){
                    break;
                }
                shm[count].dist = pair.first;
                shm[count].lineNum = pair.second;
                count++;
                kcount++;
            }


            //not usre if this is going to work but lets try
            //zero out the contents
            for(;count <= ((procNum*k)+k); count++){
                shm[count].dist = FLT_MAX;
            }


            exit(1);

        }
        //parent
        else{
            minvan.insert(pid);
        }
    }

//for making sure the chilren exite good
#if 0
    int status; // catch the status of the child

    do  // in reality, mulptiple signals or exit status could come from the child
    {

        pid_t w = waitpid(pid, &status, WUNTRACED | WCONTINUED);
        if (w == -1)
        {
            std::cerr << "Error waiting for child process ("<< pid <<")" << std::endl;
            break;
        }

        if (WIFEXITED(status))
        {
            if (status > 0)
            {
                std::cerr << "Child process ("<< pid <<") exited with non-zero status of " << WEXITSTATUS(status) << std::endl;
                continue;
            }
            else
            {
                std::cout << "Child process ("<< pid <<") exited with status of " << WEXITSTATUS(status) << std::endl;
                continue;
            }
        }
        else if (WIFSIGNALED(status))
        {
            std::cout << "Child process ("<< pid <<") killed by signal (" << WTERMSIG(status) << ")" << std::endl;
            continue;
        }
        else if (WIFSTOPPED(status))
        {
            std::cout << "Child process ("<< pid <<") stopped by signal (" << WSTOPSIG(status) << ")" << std::endl;
            continue;
        }
        else if (WIFCONTINUED(status))
        {
            std::cout << "Child process ("<< pid <<") continued" << std::endl;
            continue;
        }
    }
    while (!WIFEXITED(status) && !WIFSIGNALED(status));

#endif




    int status;
    pid_t testingProc = 0;
    //wait for all the child procs to finish
    while(!minvan.empty()){
        //probably not enough checks for the procs waiting but
        // i'll come back later and fix it
        do{
            testingProc = wait(&status);

        }while (!WIFEXITED(status) && !WIFSIGNALED(status));

        minvan.erase(testingProc);
    }


    //store the final results with line numbers
    std::vector<shmKeyPair> finalResultsNum(shm,shm+(k*p));

    //hold the final filname matches
    std::vector<nameKeyPair> finalResultsName(k);

    //sort the final results
    std::sort(finalResultsNum.begin(),finalResultsNum.end(),shmKeyPairSort);

    //cut them off at the knees
    finalResultsNum.resize(k);




    int indexer = 0;
    for(auto elem : finalResultsNum){
        // std::cout<<elem.lineNum<<" ";
        finalResultsName.push_back(nameKeyPair());
        finalResultsName.at(indexer).filename = (*lineNumMap).at(elem.lineNum);
        finalResultsName.at(indexer).dist = elem.dist;
        indexer++;
    }


    //final cut off at the knees
    finalResultsName.resize(k);

    end = std::chrono::system_clock::now();

    //get the output out to that csv, yea


    output_vector_to_file("results.csv",&finalResultsName);

    *time_elapse = end - start;

    std::cout<<"Time for parent processing: "<<(*time_elapse).count()<<std::endl;


    //delete the shrared mem, that stuff is scary
    //but its actually working great this time around
    if ((shmctl(shmId,IPC_RMID,0))==-1){
        std::cerr<<"shared mem couldn't be deleted"<<std::endl;
        return -1;
    }

    return 1;

}
Пример #9
0
ATF_TC_BODY(wait6_stop_and_go, tc)
{
	siginfo_t si;
	struct wrusage wru;
	int st;
	pid_t pid;
	static const struct rlimit rl = { 0, 0 };

	ATF_REQUIRE(setrlimit(RLIMIT_CORE, &rl) == 0);
	switch (pid = fork()) {
	case 0:
		sleep(100);
		/*FALLTHROUGH*/
	case -1:
		ATF_REQUIRE(pid > 0);
	default:
		ATF_REQUIRE(kill(pid, SIGSTOP) == 0);
		ATF_REQUIRE(wait6(P_PID, pid, &st, WSTOPPED, &wru, &si) == pid);
		ATF_REQUIRE(!WIFEXITED(st));
		ATF_REQUIRE(!WIFSIGNALED(st));
		ATF_REQUIRE(WIFSTOPPED(st) && WSTOPSIG(st) == SIGSTOP);
		ATF_REQUIRE(!WIFCONTINUED(st));
		ATF_REQUIRE(si.si_status == SIGSTOP);
		ATF_REQUIRE(si.si_pid == pid);
		ATF_REQUIRE(si.si_uid == getuid());
		ATF_REQUIRE(si.si_code == CLD_STOPPED);
#ifdef __NetBSD__
		printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime,
		    (uintmax_t)si.si_utime);
#endif

		ATF_REQUIRE(kill(pid, SIGCONT) == 0);
		ATF_REQUIRE(wait6(P_PID, pid, &st, WCONTINUED, &wru, &si) == pid);
		ATF_REQUIRE(!WIFEXITED(st));
		ATF_REQUIRE(!WIFSIGNALED(st));
		ATF_REQUIRE(WIFCONTINUED(st));
		ATF_REQUIRE(!WIFSTOPPED(st));
		ATF_REQUIRE(si.si_status == SIGCONT);
		ATF_REQUIRE(si.si_pid == pid);
		ATF_REQUIRE(si.si_uid == getuid());
		ATF_REQUIRE(si.si_code == CLD_CONTINUED);
#ifdef __NetBSD__
		printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime,
		    (uintmax_t)si.si_utime);
#endif

		ATF_REQUIRE(kill(pid, SIGQUIT) == 0);
		ATF_REQUIRE(wait6(P_PID, pid, &st, WEXITED, &wru, &si) == pid);
		ATF_REQUIRE(!WIFEXITED(st));
		ATF_REQUIRE(WIFSIGNALED(st) && WTERMSIG(st) == SIGQUIT);
		ATF_REQUIRE(!WIFSTOPPED(st));
		ATF_REQUIRE(!WIFCONTINUED(st));
		ATF_REQUIRE(si.si_status == SIGQUIT);
		ATF_REQUIRE(si.si_pid == pid);
		ATF_REQUIRE(si.si_uid == getuid());
		ATF_REQUIRE(si.si_code == CLD_KILLED);
#ifdef __NetBSD__
		printf("user: %ju system: %ju\n", (uintmax_t)si.si_utime,
		    (uintmax_t)si.si_utime);
#endif
		break;
	}
}
Пример #10
0
int main(int argc, char *argv[])
{
	int tdcount, tlimit, mlimit;
	char exename[1024], inputfile[1024];
	struct rlimit r;

	if (argc < 6)
	{
		printf("Usage: [id] [probid] [input] [time limit] [memory limit]\n");
		exit(RET_SE);
	}

	tlimit = atoi(argv[4]);
	mlimit = atoi(argv[5]);

	sprintf(exename, "./%s", argv[1]);
	strcpy(inputfile, argv[3]);


	if ((pid = fork()) == 0)
	{
		freopen("input.txt", "r", stdin);
		chdir("sandbox");
		chroot(".");
		freopen("output.txt", "w", stdout);
		setregid(99, 99);
		setreuid(99, 99);
		ptrace(PTRACE_TRACEME, 0, NULL, NULL);
		execl(exename, exename, NULL);
		exit(0);
	}
	
	signal(SIGALRM, timer);
	alarm(1);

	int stat, tmpmem, sig;
	for (;;)
	{
		wait4(pid, &stat, 0, &rinfo);
		if (WIFEXITED(stat))
		{
			puts("exited!\n");
			break;
		}
		else if (WIFSTOPPED(stat))
		{
			sig = WSTOPSIG(stat);
			if (sig == SIGTRAP)
			{
					if (checkSyscall() == RET_RF)
					{
						ptrace(PTRACE_KILL, pid, NULL, NULL);
						final_result(RET_RF);
					}
			}
			else if (sig == SIGUSR1)
			{
			}
			else
				printf("Stopped due to signal: %d\n", sig);
		}
		else if (WIFSIGNALED(stat))
		{
			//Runtime Error
			printf("Runtime Error. Received signal: %d\n", WTERMSIG(stat));
			final_result(RET_RE);
			break;
		}
		tmpmem = getMemory();
		if (tmpmem > maxmem) maxmem = tmpmem;

		if (maxmem > mlimit)
			final_result(RET_MLE);
		if (getRuntime() > tlimit)
		{
			ptrace(PTRACE_KILL, pid, NULL, NULL);
			final_result(RET_TLE);
		}
		ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
	}
	final_result(RET_AC);
	
	return 0;
}
Пример #11
0
bool f_pcntl_wifstopped(int status) { return WIFSTOPPED(status);}
Пример #12
0
int
_stub (void *ep)
{
  void                     *bp_ip;
  long                    ip1, op1, op2;
  struct user_regs_struct regs;
  int                     status, cnt;

  printf ("%s", "0x00pf IbI Crypter Stub\n");

  // Start debugging!!!
  if ((_pid = fork ()) < 0) PERROR("fork:");

  if (_pid == 0) return 0;  // Child process just keeps running
  else
    {
      // Father starts debugging child
      if ((ptrace (PTRACE_ATTACH, _pid, NULL, NULL)) < 0) PERROR ("ptrace_attach:");
      printf ("%s", "+ Waiting for process...\n");
      wait (&status);

      bp_ip = ep;

      // Set breakpoint at get there...
      op1 = ptrace (PTRACE_PEEKTEXT, _pid, bp_ip);
      DPRINTF("BP: %p 1 Opcode: %lx\n", bp_ip, op1);
      if (ptrace (PTRACE_POKETEXT, _pid, bp_ip, 
		  (op1 & 0xFFFFFFFFFFFFFF00) | 0xcc) < 0) PERROR ("ptrace_poke:");

      // Run until breakpoint is reached.
      if (ptrace (PTRACE_CONT, _pid, 0, 0) < 0) PERROR("ptrace_cont:");
      wait (&status);
      
      ptrace (PTRACE_GETREGS, _pid, 0, &regs);
      DPRINTF ("Breakpoint reached: RIP: %llx\n", regs.rip);
      regs.rip--;
      ptrace (PTRACE_SETREGS, _pid, 0, &regs);

      // REstore opcode
      ptrace (PTRACE_POKETEXT, _pid, bp_ip, op1);

      // Start step by step debugging
      ip1 = (long) ep;
      cnt = 0;
      while (WIFSTOPPED (status))
	{
	  cnt ++;
	  // Read up to 16 bytes to get the longest instruction possible
	  // Decode and write back the decoded code to execute it
	  op1 = ptrace (PTRACE_PEEKTEXT, _pid, ip1);
	  op2 = ptrace (PTRACE_PEEKTEXT, _pid, ip1 + 8);
	  DPRINTF ("%lx :: OPCODES : %lx %lx\n", ip1, op1, op2);
	  
	  XOR(op1);
	  XOR(op2);

	  DPRINTF ("%lx :: DOPCODES: %lx %lx\n", ip1, op1, op2);

	  ptrace (PTRACE_POKETEXT, _pid, ip1, op1);
	  ptrace (PTRACE_POKETEXT, _pid, ip1 + 8, op2);

	  /* Make the child execute another instruction */
	  if (ptrace(PTRACE_SINGLESTEP, _pid, 0, 0) < 0) PERROR ("ptrace_singlestep:");
	  wait(&status);
	  
	  // Re-encode the instruction just executed so we do not have
	  // to count how many bytes got executed
	  XOR(op1);
	  XOR(op2);

	  ptrace (PTRACE_POKETEXT, _pid, ip1, op1);
	  ptrace (PTRACE_POKETEXT, _pid, ip1 + 8, op2);

	  // Get the new IP
	  ptrace (PTRACE_GETREGS, _pid, 0, &regs);
	  ip1 = regs.rip;

	  // If code is outside .secure section we stop debugging 
	  if ((void*)ip1 < secure_ptr || (void*)ip1 > secure_ptr + secure_len)
	    {
	      printf ("Leaving .secure section... %d instructions executed\n", cnt);
	      break;
	    }
	}

      ptrace (PTRACE_CONT, _pid, 0, 0);
      wait (&status);      
    }

  printf ("DONE\n");
  exit (1);
}
Пример #13
0
static void
showjob(struct output *out, struct job *jp, int mode)
{
	int procno;
	int st;
	struct procstat *ps;
	int col;
	char s[64];

#if JOBS
	if (mode & SHOW_PGID) {
		/* just output process (group) id of pipeline */
		outfmt(out, "%ld\n", (long)jp->ps->pid);
		return;
	}
#endif

	procno = jp->nprocs;
	if (!procno)
		return;

	if (mode & SHOW_PID)
		mode |= SHOW_MULTILINE;

	if ((procno > 1 && !(mode & SHOW_MULTILINE))
	    || (mode & SHOW_SIGNALLED)) {
		/* See if we have more than one status to report */
		ps = jp->ps;
		st = ps->status;
		do {
			int st1 = ps->status;
			if (st1 != st)
				/* yes - need multi-line output */
				mode |= SHOW_MULTILINE;
			if (st1 == -1 || !(mode & SHOW_SIGNALLED) || WIFEXITED(st1))
				continue;
			if (WIFSTOPPED(st1) || ((st1 = WTERMSIG(st1) & 0x7f)
			    && st1 != SIGINT && st1 != SIGPIPE))
				mode |= SHOW_ISSIG;

		} while (ps++, --procno);
		procno = jp->nprocs;
	}

	if (mode & SHOW_SIGNALLED && !(mode & SHOW_ISSIG)) {
		if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE)) {
			TRACE(("showjob: freeing job %d\n", jp - jobtab + 1));
			freejob(jp);
		}
		return;
	}

	for (ps = jp->ps; --procno >= 0; ps++) {	/* for each process */
		if (ps == jp->ps)
			fmtstr(s, 16, "[%ld] %c ",
				(long)(jp - jobtab + 1),
#if JOBS
				jp == jobtab + curjob ? '+' :
				curjob != -1 && jp == jobtab +
					    jobtab[curjob].prev_job ? '-' :
#endif
				' ');
		else
			fmtstr(s, 16, "      " );
		col = strlen(s);
		if (mode & SHOW_PID) {
			fmtstr(s + col, 16, "%ld ", (long)ps->pid);
			     col += strlen(s + col);
		}
		if (ps->status == -1) {
			scopy("Running", s + col);
		} else if (WIFEXITED(ps->status)) {
			st = WEXITSTATUS(ps->status);
			if (st)
				fmtstr(s + col, 16, "Done(%d)", st);
			else
				fmtstr(s + col, 16, "Done");
		} else {
#if JOBS
			if (WIFSTOPPED(ps->status)) 
				st = WSTOPSIG(ps->status);
			else /* WIFSIGNALED(ps->status) */
#endif
				st = WTERMSIG(ps->status);
			st &= 0x7f;
			if (st < NSIG && sys_siglist[st])
				scopyn(sys_siglist[st], s + col, 32);
			else
				fmtstr(s + col, 16, "Signal %d", st);
			if (WCOREDUMP(ps->status)) {
				col += strlen(s + col);
				scopyn(" (core dumped)", s + col,  64 - col);
			}
		}
		col += strlen(s + col);
		outstr(s, out);
		do {
			outc(' ', out);
			col++;
		} while (col < 30);
		outstr(ps->cmd, out);
		if (mode & SHOW_MULTILINE) {
			if (procno > 0) {
				outc(' ', out);
				outc('|', out);
			}
		} else {
			while (--procno >= 0)
				outfmt(out, " | %s", (++ps)->cmd );
		}
		outc('\n', out);
	}
	flushout(out);
	jp->changed = 0;
	if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE))
		freejob(jp);
}
Пример #14
0
STATIC int
dowait(int flags, struct job *job)
{
	int pid;
	int status;
	struct procstat *sp;
	struct job *jp;
	struct job *thisjob;
	int done;
	int stopped;

	TRACE(("dowait(%x) called\n", flags));
	do {
		pid = waitproc(flags & WBLOCK, job, &status);
		TRACE(("wait returns pid %d, status %d\n", pid, status));
	} while (pid == -1 && errno == EINTR && pendingsigs == 0);
	if (pid <= 0)
		return pid;
	INTOFF;
	thisjob = NULL;
	for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
		if (jp->used) {
			done = 1;
			stopped = 1;
			for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
				if (sp->pid == -1)
					continue;
				if (sp->pid == pid) {
					TRACE(("Job %d: changing status of proc %d from 0x%x to 0x%x\n", jp - jobtab + 1, pid, sp->status, status));
					sp->status = status;
					thisjob = jp;
				}
				if (sp->status == -1)
					stopped = 0;
				else if (WIFSTOPPED(sp->status))
					done = 0;
			}
			if (stopped) {		/* stopped or done */
				int state = done ? JOBDONE : JOBSTOPPED;
				if (jp->state != state) {
					TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state));
					jp->state = state;
#if JOBS
					if (done)
						set_curjob(jp, 0);
#endif
				}
			}
		}
	}

	if (thisjob && thisjob->state != JOBRUNNING) {
		int mode = 0;
		if (!rootshell || !iflag)
			mode = SHOW_SIGNALLED;
		if ((job == thisjob && (flags & WNOFREE) == 0) ||
		    (job != thisjob && (flags & WNOFREE) != 0))
			mode = SHOW_SIGNALLED | SHOW_NO_FREE;
		if (mode)
			showjob(out2, thisjob, mode);
		else {
			TRACE(("Not printing status, rootshell=%d, job=%p\n",
				rootshell, job));
			thisjob->changed = 1;
		}
	}

	INTON;
	return pid;
}
Пример #15
0
void create_same_memory(int size, int num, int unit)
{
	char buf[BUFSIZ], buf2[BUFSIZ];
	int i, j, k;
	int status, fd;
	int *child;
	long ps, pages;

	ps = sysconf(_SC_PAGE_SIZE);
	pages = 1024 * 1024 / ps;

	child = malloc(num);
	if (child == NULL)
		tst_brkm(TBROK|TERRNO, cleanup, "malloc");

	memory = malloc(num * sizeof(**memory));
	if (memory == NULL)
		tst_brkm(TBROK|TERRNO, cleanup, "malloc");

	/* Don't call cleanup in those children. Instead, do a cleanup from the
	   parent after fetched children's status.*/
	switch (child[0] = fork()) {
	case -1:
		tst_brkm(TBROK|TERRNO, cleanup, "fork");
	case 0:
		tst_resm(TINFO, "child 0 stops.");
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");

		tst_resm(TINFO, "child 0 continues...");
		tst_resm(TINFO, "child 0 allocates %d MB filled with 'c'.",
			size);
		memory[0] = malloc(size / unit * sizeof(*memory));
		if (memory[0] == NULL)
			tst_brkm(TBROK|TERRNO, tst_exit, "malloc");
		for (j = 0; j * unit < size; j++) {
			memory[0][j] = mmap(NULL, unit * MB,
					PROT_READ|PROT_WRITE,
					MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
			if (memory[0][j] == MAP_FAILED)
				tst_brkm(TBROK|TERRNO, tst_exit, "mmap");

#ifdef HAVE_MADV_MERGEABLE
			if (madvise(memory[0][j], unit * MB, MADV_MERGEABLE)
				== -1)
				tst_brkm(TBROK|TERRNO, tst_exit, "madvise");
#endif
			for (i = 0; i < unit * MB; i++)
				memory[0][j][i] = 'c';
		}
		tst_resm(TINFO, "child 0 stops.");
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");

		tst_resm(TINFO, "child 0 continues...");
		verify('c', 0, 0, size / unit, 0, unit * MB);
		tst_resm(TINFO, "child 0 changes memory content to 'd'.");
		for (j = 0; j < size / unit; j++) {
			for (i = 0; i < unit * MB; i++)
				memory[0][j][i] = 'd';
		}
		/* Unmerge. */
		tst_resm(TINFO, "child 0 stops.");
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");

		tst_resm(TINFO, "child 0 continues...");
		verify('d', 0, 0, size / unit, 0, unit * MB);
		/* Stop. */
		tst_resm(TINFO, "child 0 stops.");
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");
		tst_resm(TINFO, "child 0 continues...");
		exit(0);
	}
	switch (child[1] = fork()) {
	case -1:
		tst_brkm(TBROK|TERRNO, cleanup, "fork");
	case 0:
		tst_resm(TINFO, "child 1 stops.");
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");
		tst_resm(TINFO, "child 1 continues...");
		tst_resm(TINFO, "child 1 allocates %d MB filled with 'a'.",
			size);
		memory[1] = malloc(size / unit * sizeof(*memory));
		if (memory[1] == NULL)
			tst_brkm(TBROK|TERRNO, tst_exit, "malloc");
		for (j = 0; j < size / unit; j++) {
			memory[1][j] = mmap(NULL, unit * MB,
					PROT_READ|PROT_WRITE,
					MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
			if (memory[1][j] == MAP_FAILED)
				tst_brkm(TBROK|TERRNO, tst_exit, "mmap");
#ifdef HAVE_MADV_MERGEABLE
			if (madvise(memory[1][j], unit * MB, MADV_MERGEABLE)
				== -1)
				tst_brkm(TBROK|TERRNO, tst_exit, "madvise");
#endif
			for (i = 0; i < unit * MB; i++)
				memory[1][j][i] = 'a';
		}
		tst_resm(TINFO, "child 1 stops.");
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");
		tst_resm(TINFO, "child 1 continues...");
		verify('a', 1, 0, size / unit, 0, unit * MB);
		tst_resm(TINFO, "child 1 changes memory content to 'b'.");
		for (j = 0; j < size / unit; j++) {
			for (i = 0; i < unit * MB; i++)
				memory[1][j][i] = 'b';
		}
		tst_resm(TINFO, "child 1 stops.");
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");
		tst_resm(TINFO, "child 1 continues...");
		verify('b', 1, 0, size / unit, 0, unit * MB);
		tst_resm(TINFO, "child 1 changes memory content to 'd'");
		for (j = 0; j < size / unit; j++) {
			for (i = 0; i < unit * MB; i++)
				memory[1][j][i] = 'd';
		}
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");

		tst_resm(TINFO, "child 1 continues...");
		verify('d', 1, 0, size / unit, 0, unit * MB);
		tst_resm(TINFO, "child 1 changes one page to 'e'.");
		memory[1][size / unit - 1][unit * MB - 1] = 'e';

		/* Unmerge. */
		tst_resm(TINFO, "child 1 stops.");
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");
		tst_resm(TINFO, "child 1 continues...");
		verify('e', 1, size / unit - 1, size / unit,
			unit * MB - 1, unit * MB);
		verify('d', 1, 0, size / unit - 1, 0, unit * MB - 1);

		/* Stop. */
		tst_resm(TINFO, "child 1 stops.");
		if (raise(SIGSTOP) == -1)
			tst_brkm(TBROK|TERRNO, tst_exit, "kill");
		tst_resm(TINFO, "child 1 continues...");
		exit(0);
	}
	for (k = 2; k < num; k++) {
		switch (child[k] = fork()) {
		case -1:
			tst_brkm(TBROK|TERRNO, cleanup, "fork");
		case 0:
			tst_resm(TINFO, "child %d stops.", k);
			if (raise(SIGSTOP) == -1)
				tst_brkm(TBROK|TERRNO, tst_exit, "kill");
			tst_resm(TINFO, "child %d continues...", k);
			tst_resm(TINFO, "child %d allocates %d "
				"MB filled with 'a'.", k, size);
			memory[k] = malloc(size / unit * sizeof(*memory));
			if (memory[k] == NULL)
				tst_brkm(TBROK|TERRNO, tst_exit, "malloc");
			for (j = 0; j < size / unit; j++) {
				memory[k][j] = mmap(NULL, unit * MB,
						PROT_READ|PROT_WRITE,
						MAP_ANONYMOUS
						|MAP_PRIVATE, -1, 0);
				if (memory[k][j] == MAP_FAILED)
					tst_brkm(TBROK|TERRNO, cleanup,
						"mmap");
#ifdef HAVE_MADV_MERGEABLE
				if (madvise(memory[k][j], unit * MB,
						MADV_MERGEABLE) == -1)
					tst_brkm(TBROK|TERRNO, cleanup,
						"madvise");
#endif
				for (i = 0; i < unit * MB; i++)
					memory[k][j][i] = 'a';
			}
			tst_resm(TINFO, "child %d stops.", k);
			if (raise(SIGSTOP) == -1)
				tst_brkm(TBROK|TERRNO, tst_exit, "kill");
			tst_resm(TINFO, "child %d continues...", k);
			tst_resm(TINFO, "child %d changes memory content to "
				"'d'", k);
			for (j = 0; j < size / unit; j++) {
				for (i = 0; i < unit * MB; i++)
					memory[k][j][i] = 'd';
		        }
			/* Unmerge. */
			tst_resm(TINFO, "child %d stops.", k);
			if (raise(SIGSTOP) == -1)
				tst_brkm(TBROK|TERRNO, tst_exit, "kill");
			tst_resm(TINFO, "child %d continues...", k);

			/* Stop. */
			tst_resm(TINFO, "child %d stops.", k);
			if (raise(SIGSTOP) == -1)
				tst_brkm(TBROK|TERRNO, tst_exit, "kill");
			tst_resm(TINFO, "child %d continues...", k);
			exit(0);
		}
	}
	tst_resm(TINFO, "KSM merging...");
	snprintf(buf, BUFSIZ, "%s%s", PATH_KSM, "run");
	fd = open(buf, O_WRONLY);
	if (fd == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "open");
	if (write(fd, "1", 1) != 1)
		tst_brkm(TBROK|TERRNO, cleanup, "write");
	close(fd);
	snprintf(buf, BUFSIZ, "%s%s", PATH_KSM, "pages_to_scan");
	snprintf(buf2, BUFSIZ, "%ld", size * pages * num);
	fd = open(buf, O_WRONLY);
	if (fd == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "open");
	if (write(fd, buf2, strlen(buf2)) != strlen(buf2))
		tst_brkm(TBROK|TERRNO, cleanup, "write");
	close(fd);

	snprintf(buf, BUFSIZ, "%s%s", PATH_KSM, "sleep_millisecs");
	fd = open(buf, O_WRONLY);
	if (fd == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "open");
	if (write(fd, "0", 1) != 1)
		tst_brkm(TBROK|TERRNO, cleanup, "write");
	close(fd);

	tst_resm(TINFO, "wait for all children to stop.");
	for (k = 0; k < num; k++) {
		if (waitpid(child[k], &status, WUNTRACED) == -1)
			tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
		if (!WIFSTOPPED(status))
			tst_brkm(TBROK, cleanup, "child %d was not stopped.",
				k);
	}
	tst_resm(TINFO, "resume all children.");
	for (k = 0; k < num; k++) {
		if (kill(child[k], SIGCONT) == -1)
			tst_brkm(TBROK|TERRNO, cleanup, "kill child[%d]", k);
	}
	group_check(1, 2, size * num * pages - 2, 0, 0, 0, size * pages * num);

	tst_resm(TINFO, "wait for child 1 to stop.");
	if (waitpid(child[1], &status, WUNTRACED) == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
	if (!WIFSTOPPED(status))
		tst_brkm(TBROK, cleanup, "child 1 was not stopped.");

	/* Child 1 changes all pages to 'b'. */
	tst_resm(TINFO, "resume child 1.");
	if (kill(child[1], SIGCONT) == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "kill");
	group_check(1, 3, size * num * pages - 3, 0, 0, 0, size * pages * num);

	tst_resm(TINFO, "wait for child 1 to stop.");
	if (waitpid(child[1], &status, WUNTRACED) == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
	if (!WIFSTOPPED(status))
		tst_brkm(TBROK, cleanup, "child 1 was not stopped.");

	/* All children change pages to 'd'. */
	tst_resm(TINFO, "resume all children.");
	for (k = 0; k < num; k++) {
		if (kill(child[k], SIGCONT) == -1)
			tst_brkm(TBROK|TERRNO, cleanup, "kill child[%d]", k);
	}
	group_check(1, 1, size * num * pages - 1, 0, 0, 0, size * pages * num);

	tst_resm(TINFO, "wait for all children to stop.");
	for (k = 0; k < num; k++) {
		if (waitpid(child[k], &status, WUNTRACED) == -1)
			tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
		if (!WIFSTOPPED(status))
			tst_brkm(TBROK, cleanup, "child %d was not stopped.",
				k);
	}
	/* Child 1 changes pages to 'e'. */
	tst_resm(TINFO, "resume child 1.");
	if (kill(child[1], SIGCONT) == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "kill");
	group_check(1, 1, size * num * pages - 2, 0, 1, 0, size * pages * num);

	tst_resm(TINFO, "wait for child 1 to stop.");
	if (waitpid(child[1], &status, WUNTRACED) == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
	if (!WIFSTOPPED(status))
		tst_brkm(TBROK, cleanup, "child 1 was not stopped.");

	tst_resm(TINFO, "resume all children.");
	for (k = 0; k < num; k++) {
		if (kill(child[k], SIGCONT) == -1)
			tst_brkm(TBROK|TERRNO, cleanup, "kill child[%d]", k);
	}
	tst_resm(TINFO, "KSM unmerging...");
	snprintf(buf, BUFSIZ, "%s%s", PATH_KSM, "run");
	fd = open(buf, O_WRONLY);
	if (fd == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "open");
	if (write(fd, "2", 1) != 1)
		tst_brkm(TBROK|TERRNO, cleanup, "write");
	group_check(2, 0, 0, 0, 0, 0, size * pages * num);

	tst_resm(TINFO, "wait for all children to stop.");
	for (k = 0; k < num; k++) {
		if (waitpid(child[k], &status, WUNTRACED) == -1)
			tst_brkm(TBROK|TERRNO, cleanup, "waitpid");
		if (!WIFSTOPPED(status))
			tst_brkm(TBROK, cleanup, "child %d was not stopped.",
				k);
	}
	tst_resm(TINFO, "resume all children.");
	for (k = 0; k < num; k++) {
		if (kill(child[k], SIGCONT) == -1)
			tst_brkm(TBROK|TERRNO, cleanup, "kill child[%d]", k);
	}
	tst_resm(TINFO, "stop KSM.");
	if (lseek(fd, 0, SEEK_SET) == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "lseek");
	if (write(fd, "0", 1) != 1)
		tst_brkm(TBROK|TERRNO, cleanup, "write");
	close(fd);
	group_check(0, 0, 0, 0, 0, 0, size * pages * num);
	while (waitpid(-1, &status, WUNTRACED | WCONTINUED) > 0)
		if (WEXITSTATUS(status) != 0)
			tst_resm(TFAIL, "child exit status is %d",
				WEXITSTATUS(status));
}
Пример #16
0
int main(int argc, char **argv)
{
	sigset_t oldmask, newmask;
	pid_t pid;
	int   status;
	int   exitcode;
	char *valid_users;
	char *ptr;
	char *path;
	char  cwd[MAXPATHLEN+3];
	int   opt;
	
	struct rlimit lim;
		
	progname = argv[0];

	/* Clear environment to prevent all kinds of security holes, save PATH */
	path = getenv("PATH");
	environ[0] = NULL;
	/* FIXME: Clean path before setting it again? */
	if ( path!=NULL ) setenv("PATH",path,1);

	/* Parse command-line options */
	use_root = use_time = use_user = use_output = no_coredump = 0;
	memsize = filesize = nproc = RLIM_INFINITY;
	be_verbose = be_quiet = 0;
	show_help = show_version = 0;
	opterr = 0;
	while ( (opt = getopt_long(argc,argv,"+r:t:u:m:f:p:co:vq",long_opts,(int *) 0))!=-1 ) {
		switch ( opt ) {
		case 0:   /* long-only option */
			break;
		case 'r': /* rootdir option */
			use_root = 1;
			rootdir = (char *) malloc(strlen(optarg)+2);
			strcpy(rootdir,optarg);
			break;
		case 't': /* time option */
			use_time = 1;
			runtime = strtol(optarg,&ptr,10);
			if ( *ptr!=0 || runtime<=0 ) {
				error(0,"invalid time specified: `%s'",optarg);
			}
			break;
		case 'u': /* user option */
			use_user = 1;
			runuid = strtol(optarg,&ptr,10);
			if ( *ptr!=0 ) runuid = userid(optarg);
			if ( runuid<0 ) error(0,"invalid username or ID specified: `%s'",optarg);
			break;
		case 'm': /* memsize option */
			memsize = (rlim_t) strtol(optarg,&ptr,10);
			if ( *ptr!=0 || memsize<=0 ) {
				error(0,"invalid memory limit specified: `%s'",optarg);
			}
			/* Convert limit from kB to bytes and check for overflow */
			if ( memsize!=(memsize*1024)/1024 ) {
				memsize = RLIM_INFINITY;
			} else {
				memsize *= 1024;
			}
			break;
		case 'f': /* filesize option */
			filesize = (rlim_t) strtol(optarg,&ptr,10);
			if ( *ptr!=0 || filesize<=0 ) {
				error(0,"invalid filesize limit specified: `%s'",optarg);
			}
			/* Convert limit from kB to bytes and check for overflow */
			if ( filesize!=(filesize*1024)/1024 ) {
				filesize = RLIM_INFINITY;
			} else {
				filesize *= 1024;
			}
			break;
		case 'p': /* nproc option */
			nproc = (rlim_t) strtol(optarg,&ptr,10);
			if ( *ptr!=0 || nproc<=0 ) {
				error(0,"invalid process limit specified: `%s'",optarg);
			}
			break;
		case 'c': /* no-core option */
			no_coredump = 1;
			break;
		case 'o': /* output option */
			use_output = 1;
			outputfilename = (char *) malloc(strlen(optarg)+2);
			strcpy(outputfilename,optarg);
			break;
		case 'v': /* verbose option */
			be_verbose = 1;
			break;
		case 'q': /* quiet option */
			be_quiet = 1;
			break;
		case ':': /* getopt error */
		case '?':
			error(0,"unknown option or missing argument `%c'",optopt);
			break;
		default:
			error(0,"getopt returned character code `%c' ??",(char)opt);
		}
	}

	if ( show_help ) usage();
	if ( show_version ) version();
	
	if ( argc<=optind ) error(0,"no command specified");

	/* Command to be executed */
	cmdname = argv[optind];
	cmdargs = argv+optind;

	/* Check that new uid is in list of valid uid's.
	   This must be done before chroot for /etc/passwd lookup. */
	if ( use_user ) {
		valid_users = strdup(VALID_USERS);
		for(ptr=strtok(valid_users,","); ptr!=NULL; ptr=strtok(NULL,",")) {
			if ( runuid==userid(ptr) ) break;
		}
		if ( ptr==NULL || runuid<=0 ) error(0,"illegal user specified: %d",runuid);
	}

	/* Set resource limits: must be root to raise hard limits.
	   Note that limits can thus be raised from the systems defaults! */
	
	/* First define shorthand macro function */
#define setlim(type) \
	if ( setrlimit(RLIMIT_ ## type, &lim)!=0 ) { \
		if ( errno==EPERM ) { \
			warning("no permission to set resource RLIMIT_" #type); \
		} else { \
			error(errno,"setting resource RLIMIT_" #type); \
		} \
	}

	if ( memsize!=RLIM_INFINITY ) {
		verbose("setting memory limits to %d bytes",(int)memsize);
	}
	lim.rlim_cur = lim.rlim_max = memsize;
	setlim(AS);
	setlim(DATA);
	setlim(STACK);
	setlim(MEMLOCK);
	
	if ( filesize!=RLIM_INFINITY ) {
		verbose("setting filesize limit to %d bytes",(int)filesize);
	}
	lim.rlim_cur = lim.rlim_max = filesize;
	setlim(FSIZE);
	
	if ( nproc!=RLIM_INFINITY ) {
		verbose("setting process limit to %d",(int)nproc);
	}
	lim.rlim_cur = lim.rlim_max = nproc;
	setlim(NPROC);

#undef setlim
	
	if ( no_coredump ) {
		verbose("disabling core dumps");
		lim.rlim_cur = lim.rlim_max = 0;
		if ( setrlimit(RLIMIT_CORE,&lim)!=0 ) error(errno,"disabling core dumps");
	}
	
	/* Set root-directory and change directory to there. */
	if ( use_root ) {
		/* Small security issue: when running setuid-root, people can find
		   out which directories exist from error message. */
		if ( chdir(rootdir) ) error(errno,"cannot chdir to `%s'",rootdir);

		/* Get absolute pathname of rootdir, by reading it. */
		if ( getcwd(cwd,MAXPATHLEN)==NULL ) error(errno,"cannot get directory");
		if ( cwd[strlen(cwd)-1]!='/' ) strcat(cwd,"/");

		/* Canonicalize CHROOT_PREFIX: the use of NULL below is a GNU
		   extension, recommended for security */
		if ( (path = realpath(CHROOT_PREFIX,NULL))==NULL ) {
			error(errno,"cannot canonicalize path '%s'",CHROOT_PREFIX);
		}
		
		/* Check that we are within prescribed path. */
		if ( strncmp(cwd,path,strlen(path))!=0 ) {
			error(0,"invalid root: must be within `%s'",path);
		}
		free(path);
		
		if ( chroot(".") ) error(errno,"cannot change root to `%s'",cwd);
		verbose("using root-directory `%s'",cwd);
	}
	
	/* Set user-id (must be root for this). */
	if ( use_user ) {
		if ( setuid(runuid) ) error(errno,"cannot set user ID to `%d'",runuid);
		verbose("using user ID `%d'",runuid);
	} else {
		/* Reset effective uid to real uid, to increase security
		   when program is run setuid */
		if ( setuid(getuid()) ) error(errno,"cannot set real user ID");
		verbose("using real uid `%d' as effective uid",getuid());
	}
	if ( geteuid()==0 || getuid()==0 ) error(0,"root privileges not dropped");

	/* Open output file for writing running time to */
	if ( use_output ) {
		outputfile = fopen(outputfilename,"w");
		if ( outputfile==NULL ) error(errno,"cannot open `%s'",outputfilename);
		verbose("using file `%s' to write runtime to",outputfilename);
	}
	
	switch ( child_pid = fork() ) {
	case -1: /* error */
		error(errno,"cannot fork");
		
	case  0: /* run controlled command */
		/* Run the command in a separate process group so that the command
		   and all its children can be killed off with one signal. */
		setsid();
		execvp(cmdname,cmdargs);
		error(errno,"cannot start `%s'",cmdname);
		
	default: /* become watchdog */
		if ( gettimeofday(&starttime,NULL) ) error(errno,"getting time");

		/* unmask all signals */
		memset(&newmask, 0, sizeof(newmask));
		if ( sigprocmask(SIG_SETMASK, &newmask, &oldmask)!=0 ) {
			error(errno,"unmasking signals");
		}

		signal(SIGTERM,terminate);
		
		if ( use_time ) {
			signal(SIGALRM,terminate);
			alarm(runtime);
			verbose("using timelimit of %d seconds",runtime);
		}

		/* Wait for the child command to finish */
		while ( (pid = wait(&status))!=-1 && pid!=child_pid );
		if ( pid!=child_pid ) error(errno,"waiting on child");

		outputtime();

		/* Test whether command has finished abnormally */
		if ( ! WIFEXITED(status) ) {
			if ( WIFSIGNALED(status) ) {
				warning("command terminated with signal %d",WTERMSIG(status));
				return 128+WTERMSIG(status);
			}
			if ( WIFSTOPPED(status) ) {
				warning("command stopped with signal %d",WSTOPSIG(status));
				return 128+WSTOPSIG(status);
			}
			error(0,"command exit status unknown: %d",status);
		}
		
		/* Return the exitstatus of the command */
		exitcode = WEXITSTATUS(status);
		if ( exitcode!=0 ) verbose("command exited with exitcode %d",exitcode);
		return exitcode; 
	}

	/* This should never be reached */
	error(0,"unexpected end of program");
}
Пример #17
0
int
main(int argc, char *argv[])
{
    int exit_status = 0, ret, flags = 0, i;
    int exec_argc = 0, user_argc = 0;
    char **exec_argv = NULL, **user_argv = NULL;
    char *exec_command, *base_argv0 = NULL;
    bool disable_flags = true;
    bool real_flag = false;

    if (OPAL_SUCCESS != (ret = opal_init_util(&argc, &argv))) {
        return ret;
    }

    /****************************************************
     *
     * Setup compiler information
     *
     ****************************************************/

    base_argv0 = opal_basename(argv[0]);
#if defined(EXEEXT)
    if( 0 != strlen(EXEEXT) ) {
        char extension[] = EXEEXT;
        char* temp = strstr( base_argv0, extension );
        char* old_match = temp;
        while( NULL != temp ) {
            old_match = temp;
            temp = strstr( temp + 1, extension );
        }
        /* Only if there was a match of .exe, erase the last occurence of .exe */
        if ( NULL != old_match ) {
            *old_match = '\0';
        }
    }
#endif  /* defined(EXEEXT) */

    if (OPAL_SUCCESS != (ret = data_init(base_argv0))) {
        fprintf(stderr, "Error parsing data file %s: %s\n", base_argv0, opal_strerror(ret));
        return ret;
    }

    for (i = 1 ; i < argc && user_data_idx < 0 ; ++i) {
        user_data_idx = find_options_index(argv[i]);
    }
    /* if we didn't find a match, look for the NULL (base case) options */
    if (user_data_idx < 0) {
        user_data_idx = default_data_idx;
    }
    /* if we still didn't find a match, abort */
    if (user_data_idx < 0) {
        char *flat = opal_argv_join(argv, ' ');
        opal_show_help("help-opal-wrapper.txt", "no-options-support", true,
                       base_argv0, flat, NULL);
        free(flat);
        exit(1);
    }

    /* compiler */
    load_env_data(options_data[user_data_idx].project_short, options_data[user_data_idx].compiler_env, &options_data[user_data_idx].compiler);

    /* preprocessor flags */
    load_env_data_argv(options_data[user_data_idx].project_short, "CPPFLAGS", &options_data[user_data_idx].preproc_flags);

    /* compiler flags */
    load_env_data_argv(options_data[user_data_idx].project_short, options_data[user_data_idx].compiler_flags_env,
                       &options_data[user_data_idx].comp_flags);

    /* linker flags */
    load_env_data_argv(options_data[user_data_idx].project_short, "LDFLAGS", &options_data[user_data_idx].link_flags);

    /* libs */
    load_env_data_argv(options_data[user_data_idx].project_short, "LIBS", &options_data[user_data_idx].libs);


    /****************************************************
     *
     * Sanity Checks
     *
     ****************************************************/
    
    if (NULL != options_data[user_data_idx].req_file) {
        /* make sure the language is supported */
        if (0 == strcmp(options_data[user_data_idx].req_file, "not supported")) {
            opal_show_help("help-opal-wrapper.txt", "no-language-support", true,
                           options_data[user_data_idx].language, base_argv0, NULL);
            exit_status = 1;
            goto cleanup;
        }

        if (options_data[user_data_idx].req_file[0] != '\0') {
            char *filename;
            struct stat buf;
            filename = opal_os_path( false, options_data[user_data_idx].path_libdir, options_data[user_data_idx].req_file, NULL );
            if (0 != stat(filename, &buf)) {
                opal_show_help("help-opal-wrapper.txt", "file-not-found", true,
                               base_argv0, options_data[user_data_idx].req_file, options_data[user_data_idx].language, NULL);
            }
        }
    }

    /****************************************************
     *
     * Parse user flags
     *
     ****************************************************/
    flags = COMP_WANT_COMMAND|COMP_WANT_PREPROC|
        COMP_WANT_COMPILE|COMP_WANT_LINK;

    user_argv = opal_argv_copy(argv + 1);
    user_argc = opal_argv_count(user_argv);

    for (i = 0 ; i < user_argc ; ++i) {
        if (0 == strncmp(user_argv[i], "-showme", strlen("-showme")) ||
            0 == strncmp(user_argv[i], "--showme", strlen("--showme")) ||
            0 == strncmp(user_argv[i], "-show", strlen("-show")) ||
            0 == strncmp(user_argv[i], "--show", strlen("--show"))) {
            bool done_now = false;

            /* check for specific things we want to see.  First three
               still invoke all the building routines.  Last set want
               to parse out certain flags, so we don't go through the
               normal build routine - skip to cleanup. */
            if (0 == strncmp(user_argv[i], "-showme:command", strlen("-showme:command")) ||
                0 == strncmp(user_argv[i], "--showme:command", strlen("--showme:command"))) {
                flags = COMP_WANT_COMMAND;
                /* we know what we want, so don't process any more args */
                done_now = true;
            } else if (0 == strncmp(user_argv[i], "-showme:compile", strlen("-showme:compile")) ||
                0 == strncmp(user_argv[i], "--showme:compile", strlen("--showme:compile"))) {
                flags = COMP_WANT_PREPROC|COMP_WANT_COMPILE;
                /* we know what we want, so don't process any more args */
                done_now = true;
            } else if (0 == strncmp(user_argv[i], "-showme:link", strlen("-showme:link")) ||
                       0 == strncmp(user_argv[i], "--showme:link", strlen("--showme:link"))) {
                flags = COMP_WANT_COMPILE|COMP_WANT_LINK;
                /* we know what we want, so don't process any more args */
                done_now = true;
            } else if (0 == strncmp(user_argv[i], "-showme:incdirs", strlen("-showme:incdirs")) ||
                       0 == strncmp(user_argv[i], "--showme:incdirs", strlen("--showme:incdirs"))) {
                print_flags(options_data[user_data_idx].preproc_flags, OPAL_INCLUDE_FLAG);
                goto cleanup;
            } else if (0 == strncmp(user_argv[i], "-showme:libdirs", strlen("-showme:libdirs")) ||
                       0 == strncmp(user_argv[i], "--showme:libdirs", strlen("--showme:libdirs"))) {
                print_flags(options_data[user_data_idx].link_flags, OPAL_LIBDIR_FLAG);
                goto cleanup;
            } else if (0 == strncmp(user_argv[i], "-showme:libs", strlen("-showme:libs")) ||
                       0 == strncmp(user_argv[i], "--showme:libs", strlen("--showme:libs"))) {
                print_flags(options_data[user_data_idx].libs, "-l");
                goto cleanup;
            } else if (0 == strncmp(user_argv[i], "-showme:version", strlen("-showme:version")) ||
                       0 == strncmp(user_argv[i], "--showme:version", strlen("--showme:version"))) {
                char * str;
                str = opal_show_help_string("help-opal-wrapper.txt",
                                            "version", false,
                                            argv[0], options_data[user_data_idx].project, options_data[user_data_idx].version, options_data[user_data_idx].language, NULL);
                if (NULL != str) {
                    printf("%s", str);
                    free(str);
                }
                goto cleanup;
            } else if (0 == strncmp(user_argv[i], "-showme:help", strlen("-showme:help")) ||
                       0 == strncmp(user_argv[i], "--showme:help", strlen("--showme:help"))) {
                char *str;
                str = opal_show_help_string("help-opal-wrapper.txt", "usage", 
                                            false, argv[0],
                                            options_data[user_data_idx].project, 
                                            NULL);
                if (NULL != str) {
                    printf("%s", str);
                    free(str);
                }

                exit_status = 0;
                goto cleanup;
            } else if (0 == strncmp(user_argv[i], "-showme:", strlen("-showme:")) ||
                       0 == strncmp(user_argv[i], "--showme:", strlen("--showme:"))) {
                fprintf(stderr, "%s: unrecognized option: %s\n", argv[0],
                        user_argv[i]);
                fprintf(stderr, "Type '%s --showme:help' for usage.\n",
                        argv[0]);
                exit_status = 1;
                goto cleanup;
            }

            flags |= (COMP_DRY_RUN|COMP_SHOW_ERROR);
            /* remove element from user_argv */
            opal_argv_delete(&user_argc, &user_argv, i, 1);
            --i;

            if (done_now) {
                disable_flags = false;
                break;
            }

        } else if (0 == strcmp(user_argv[i], "-c")) {
            flags &= ~COMP_WANT_LINK;
            real_flag = true;
        } else if (0 == strcmp(user_argv[i], "-E") || 
                   0 == strcmp(user_argv[i], "-M")) {
            flags &= ~(COMP_WANT_COMPILE | COMP_WANT_LINK);
            real_flag = true;
        } else if (0 == strcmp(user_argv[i], "-S")) {
            flags &= ~COMP_WANT_LINK;
            real_flag = true;
        } else if (0 == strcmp(user_argv[i], "-lpmpi")) {
            flags |= COMP_WANT_PMPI;

            /* remove element from user_argv */
            opal_argv_delete(&user_argc, &user_argv, i, 1);
            --i;
        } else if (0 == strcmp(user_argv[i], "-static") ||
                   0 == strcmp(user_argv[i], "--static") ||
                   0 == strcmp(user_argv[i], "-Bstatic") ||
                   0 == strcmp(user_argv[i], "-Wl,-static") ||
                   0 == strcmp(user_argv[i], "-Wl,--static") ||
                   0 == strcmp(user_argv[i], "-Wl,-Bstatic")) {
            flags |= COMP_WANT_STATIC;
        } else if (0 == strcmp(user_argv[i], "-dynamic") ||
                   0 == strcmp(user_argv[i], "--dynamic") ||
                   0 == strcmp(user_argv[i], "-Bdynamic") ||
                   0 == strcmp(user_argv[i], "-Wl,-dynamic") ||
                   0 == strcmp(user_argv[i], "-Wl,--dynamic") ||
                   0 == strcmp(user_argv[i], "-Wl,-Bdynamic")) {
            flags &= ~COMP_WANT_STATIC;
        } else if (0 == strcmp(user_argv[i], "--openmpi:linkall")) {
            /* This is an intentionally undocummented wrapper compiler
               switch.  It should only be used by Open MPI developers
               -- not end users.  It will cause mpicc to use the
               static library list, even if we're compiling
               dynamically (i.e., it'll specifically -lopen-rte and
               -lopen-pal (and all their dependent libs)).  We provide
               this flag for test MPI applications that also invoke
               ORTE and/or OPAL function calls.

               On some systems (e.g., OS X), if the top-level
               application calls ORTE/OPAL functions and you don't -l
               ORTE and OPAL, then the functions won't be resolved at
               link time (i.e., the implicit library dependencies of
               libmpi won't be pulled in at link time), and therefore
               the link will fail.  This flag will cause the wrapper
               to explicitly list the ORTE and OPAL libs on the
               underlying compiler command line, so the application
               will therefore link properly. */
            flags |= COMP_WANT_LINKALL;

            /* remove element from user_argv */
            opal_argv_delete(&user_argc, &user_argv, i, 1);
        } else if ('-' != user_argv[i][0]) {
            disable_flags = false;
            flags |= COMP_SHOW_ERROR;
            real_flag = true;
        } else { 
            /* if the option flag is one that we use to determine
               which set of compiler data to use, don't count it as a
               real option */
            if (find_options_index(user_argv[i]) < 0) {
                real_flag = true;
            }
        }
    }

    /* clear out the want_flags if we got no arguments not starting
       with a - (dash) and -showme wasn't given OR -showme was given
       and we had at least one more non-showme argument that started
       with a - (dash) and no other non-dash arguments.  Some examples:

       opal_wrapper                : clear our flags
       opal_wrapper -v             : clear our flags
       opal_wrapper -E a.c         : don't clear our flags
       opal_wrapper a.c            : don't clear our flags
       opal_wrapper -showme        : don't clear our flags
       opal_wrapper -showme -v     : clear our flags
       opal_wrapper -showme -E a.c : don't clear our flags
       opal_wrapper -showme a.c    : don't clear our flags
    */
    if (disable_flags && !((flags & COMP_DRY_RUN) && !real_flag)) {
        flags &= ~(COMP_WANT_PREPROC|COMP_WANT_COMPILE|COMP_WANT_LINK);
    }

    /****************************************************
     *
     * Assemble the command line
     *
     ****************************************************/

    /* compiler (may be multiple arguments, so split) */
    if (flags & COMP_WANT_COMMAND) {
        exec_argv = opal_argv_split(options_data[user_data_idx].compiler, ' ');
        exec_argc = opal_argv_count(exec_argv);
    } else {
        exec_argv = (char **) malloc(sizeof(char*));
        exec_argv[0] = NULL;
        exec_argc = 0;
    }

    /* This error would normally not happen unless the user edits the 
       wrapper data files manually */
    if (NULL == exec_argv) {
        opal_show_help("help-opal-wrapper.txt", "no-compiler-specified", true);
        return 1;
    }

    if (flags & COMP_WANT_COMPILE) {
        opal_argv_insert(&exec_argv, exec_argc,
                         options_data[user_data_idx].comp_flags_prefix);
        exec_argc = opal_argv_count(exec_argv);
    }

    /* Per https://svn.open-mpi.org/trac/ompi/ticket/2201, add all the
       user arguments before anything else. */
    opal_argv_insert(&exec_argv, exec_argc, user_argv);
    exec_argc = opal_argv_count(exec_argv);

    /* preproc flags */
    if (flags & COMP_WANT_PREPROC) {
        opal_argv_insert(&exec_argv, exec_argc, options_data[user_data_idx].preproc_flags);
        exec_argc = opal_argv_count(exec_argv);
    }

    /* compiler flags */
    if (flags & COMP_WANT_COMPILE) {
        opal_argv_insert(&exec_argv, exec_argc, options_data[user_data_idx].comp_flags);
        exec_argc = opal_argv_count(exec_argv);
    }

    /* link flags and libs */
    if (flags & COMP_WANT_LINK) {
        bool have_static_lib;
        bool have_dyn_lib;
        bool use_static_libs;
        char *filename1, *filename2;
        struct stat buf;

        opal_argv_insert(&exec_argv, exec_argc, options_data[user_data_idx].link_flags);
        exec_argc = opal_argv_count(exec_argv);

        /* Are we linking statically?  If so, decide what libraries to
           list.  It depends on two factors:

           1. Was --static (etc.) specified?
           2. Does OMPI have static, dynamic, or both libraries installed?

           Here's a matrix showing what we'll do in all 6 cases:

           What's installed    --static    no --static
           ----------------    ----------  -----------
           ompi .so libs       -lmpi       -lmpi
           ompi .a libs        all         all
           ompi both libs      all         -lmpi

        */

        filename1 = opal_os_path( false, options_data[user_data_idx].path_libdir, options_data[user_data_idx].static_lib_file, NULL );
        if (0 == stat(filename1, &buf)) {
            have_static_lib = true;
        } else {
            have_static_lib = false;
        }

        filename2 = opal_os_path( false, options_data[user_data_idx].path_libdir, options_data[user_data_idx].dyn_lib_file, NULL );
        if (0 == stat(filename2, &buf)) {
            have_dyn_lib = true;
        } else {
            have_dyn_lib = false;
        }

        /* Determine which set of libs to use: dynamic or static.  Be
           pedantic to make the code easy to read. */
        if (flags & COMP_WANT_LINKALL) {
            /* If --openmpi:linkall was specified, list all the libs
               (i.e., the static libs) if they're available, either in
               static or dynamic form. */
            if (have_static_lib || have_dyn_lib) {
                use_static_libs = true;
            } else {
                fprintf(stderr, "The linkall option has failed as we were unable to find either static or dynamic libs\n"
                        "Files looked for:\n  Static: %s\n  Dynamic: %s\n",
                        filename1, filename2);
                free(filename1);
                free(filename2);
                exit(1);
            }
        } else if (flags & COMP_WANT_STATIC) {
            /* If --static (or something like it) was specified, if we
               have the static libs, then use them.  Otherwise, use
               the dynamic libs. */
            if (have_static_lib) {
                use_static_libs = true;
            } else {
                use_static_libs = false;
            }
        } else {
            /* If --static (or something like it) was NOT specified
               (or if --dyanic, or something like it, was specified),
               if we have the dynamic libs, then use them.  Otherwise,
               use the static libs. */
            if (have_dyn_lib) {
                use_static_libs = false;
            } else {
                use_static_libs = true;
            }
        }
        free(filename1);
        free(filename2);

        if (use_static_libs) {
            opal_argv_insert(&exec_argv, exec_argc, options_data[user_data_idx].libs_static);
        } else {
            opal_argv_insert(&exec_argv, exec_argc, options_data[user_data_idx].libs);
        }
        exec_argc = opal_argv_count(exec_argv);
    }


    /****************************************************
     *
     * Execute the command
     *
     ****************************************************/

    if (flags & COMP_DRY_RUN) {
        exec_command = opal_argv_join(exec_argv, ' ');
        printf("%s\n", exec_command);
    } else {
        char *tmp;

#if 0
        exec_command = opal_argv_join(exec_argv, ' ');
        printf("command: %s\n", exec_command);
#endif

        tmp = opal_path_findv(exec_argv[0], 0, environ, NULL);
        if (NULL == tmp) {
            opal_show_help("help-opal-wrapper.txt", "no-compiler-found", true,
                           exec_argv[0], NULL);
            errno = 0;
            exit_status = 1;
        }  else {
            int status;

            free(exec_argv[0]);
            exec_argv[0] = tmp;
            ret = opal_few(exec_argv, &status);
            exit_status = WIFEXITED(status) ? WEXITSTATUS(status) :
                              (WIFSIGNALED(status) ? WTERMSIG(status) :
                                  (WIFSTOPPED(status) ? WSTOPSIG(status) : 255));
            if( (OPAL_SUCCESS != ret) || ((0 != exit_status) && (flags & COMP_SHOW_ERROR)) ) {
                char* exec_command = opal_argv_join(exec_argv, ' ');
                if( OPAL_SUCCESS != ret ) {
                    opal_show_help("help-opal-wrapper.txt", "spawn-failed", true,
                                   exec_argv[0], strerror(status), exec_command, NULL);
                } else {
#if 0
                    opal_show_help("help-opal-wrapper.txt", "compiler-failed", true,
                                   exec_argv[0], exit_status, exec_command, NULL);
#endif
                }
                free(exec_command);
            }
        }
    }

    /****************************************************
     *
     * Cleanup
     *
     ****************************************************/
 cleanup:

    opal_argv_free(exec_argv);
    opal_argv_free(user_argv);
    if (NULL != base_argv0) free(base_argv0);

    if (OPAL_SUCCESS != (ret = data_finalize())) {
        return ret;
    }

    if (OPAL_SUCCESS != (ret = opal_finalize_util())) {
        return ret;
    }

    return exit_status;
}
Пример #18
0
int tracer(int (*init_proc)(void *), void *sp)
{
	void *task = NULL;
	unsigned long eip = 0;
	int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
	int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0;

	capture_signal_stack();
	signal(SIGPIPE, SIG_IGN);
	setup_tracer_winch();
	tracing_pid = os_getpid();
	printf("tracing thread pid = %d\n", tracing_pid);

	pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
	CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
	if(n < 0){
		printf("waitpid on idle thread failed, errno = %d\n", errno);
		exit(1);
	}
	if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
		printf("Failed to continue idle thread, errno = %d\n", errno);
		exit(1);
	}

	signal(SIGSEGV, (sighandler_t) tracer_segv);
	signal(SIGUSR1, signal_usr1);
	if(debug_trace){
		printf("Tracing thread pausing to be attached\n");
		stop();
	}
	if(debug){
		if(gdb_pid != -1) 
			debugger_pid = attach_debugger(pid, gdb_pid, 1);
		else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
		if(debug_parent){
			debugger_parent = os_process_parent(debugger_pid);
			init_parent_proxy(debugger_parent);
			err = attach(debugger_parent);
			if(err){
				printf("Failed to attach debugger parent %d, "
				       "errno = %d\n", debugger_parent, -err);
				debugger_parent = -1;
			}
			else {
				if(ptrace(PTRACE_SYSCALL, debugger_parent, 
					  0, 0) < 0){
					printf("Failed to continue debugger "
					       "parent, errno = %d\n", errno);
					debugger_parent = -1;
				}
			}
		}
	}
	set_cmdline("(tracing thread)");
	while(1){
		CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
		if(pid <= 0){
			if(errno != ECHILD){
				printf("wait failed - errno = %d\n", errno);
			}
			continue;
		}
		if(pid == debugger_pid){
			int cont = 0;

			if(WIFEXITED(status) || WIFSIGNALED(status))
				debugger_pid = -1;
			/* XXX Figure out how to deal with gdb and SMP */
			else cont = debugger_signal(status, cpu_tasks[0].pid);
			if(cont == PTRACE_SYSCALL) strace = 1;
			continue;
		}
		else if(pid == debugger_parent){
			debugger_parent_signal(status, pid);
			continue;
		}
		nsignals++;
		if(WIFEXITED(status)) ;
#ifdef notdef
		{
			printf("Child %d exited with status %d\n", pid, 
			       WEXITSTATUS(status));
		}
#endif
		else if(WIFSIGNALED(status)){
			sig = WTERMSIG(status);
			if(sig != 9){
				printf("Child %d exited with signal %d\n", pid,
				       sig);
			}
		}
		else if(WIFSTOPPED(status)){
			proc_id = pid_to_processor_id(pid);
			sig = WSTOPSIG(status);
			if(signal_index[proc_id] == 1024){
				signal_index[proc_id] = 0;
				last_index = 1023;
			}
			else last_index = signal_index[proc_id] - 1;
			if(((sig == SIGPROF) || (sig == SIGVTALRM) || 
			    (sig == SIGALRM)) &&
			   (signal_record[proc_id][last_index].signal == sig)&&
			   (signal_record[proc_id][last_index].pid == pid))
				signal_index[proc_id] = last_index;
			signal_record[proc_id][signal_index[proc_id]].pid = pid;
			gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL);
			eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
			signal_record[proc_id][signal_index[proc_id]].addr = eip;
			signal_record[proc_id][signal_index[proc_id]++].signal = sig;
			
			if(proc_id == -1){
				sleeping_process_signal(pid, sig);
				continue;
			}

			task = cpu_tasks[proc_id].task;
			tracing = is_tracing(task);
			old_tracing = tracing;

			switch(sig){
			case SIGUSR1:
				sig = 0;
				op = do_proc_op(task, proc_id);
				switch(op){
				case OP_TRACE_ON:
					arch_leave_kernel(task, pid);
					tracing = 1;
					break;
				case OP_REBOOT:
				case OP_HALT:
					unmap_physmem();
					kmalloc_ok = 0;
					ptrace(PTRACE_KILL, pid, 0, 0);
					return(op == OP_REBOOT);
				case OP_NONE:
					printf("Detaching pid %d\n", pid);
					detach(pid, SIGSTOP);
					continue;
				default:
					break;
				}
				/* OP_EXEC switches host processes on us,
				 * we want to continue the new one.
				 */
				pid = cpu_tasks[proc_id].pid;
				break;
			case SIGTRAP:
				if(!tracing && (debugger_pid != -1)){
					child_signal(pid, status);
					continue;
				}
				tracing = 0;
				if(do_syscall(task, pid))
					sig = SIGUSR2;
				else clear_singlestep(task);
				break;
			case SIGPROF:
				if(tracing) sig = 0;
				break;
			case SIGCHLD:
			case SIGHUP:
				sig = 0;
				break;
			case SIGSEGV:
			case SIGIO:
			case SIGALRM:
			case SIGVTALRM:
			case SIGFPE:
			case SIGBUS:
			case SIGILL:
			case SIGWINCH:
			default:
				tracing = 0;
				break;
			}
			set_tracing(task, tracing);

			if(!tracing && old_tracing)
				arch_enter_kernel(task, pid);

			if(!tracing && (debugger_pid != -1) && (sig != 0) &&
				(sig != SIGALRM) && (sig != SIGVTALRM) &&
				(sig != SIGSEGV) && (sig != SIGTRAP) &&
				(sig != SIGUSR2) && (sig != SIGIO) &&
				(sig != SIGFPE)){
				child_signal(pid, status);
				continue;
			}

			if(tracing){
				if(singlestepping_tt(task))
					cont_type = PTRACE_SINGLESTEP;
				else cont_type = PTRACE_SYSCALL;
			}
			else cont_type = PTRACE_CONT;

			if((cont_type == PTRACE_CONT) && 
			   (debugger_pid != -1) && strace)
				cont_type = PTRACE_SYSCALL;

			if(ptrace(cont_type, pid, 0, sig) != 0){
				tracer_panic("ptrace failed to continue "
					     "process - errno = %d\n", 
					     errno);
			}
		}
	}
Пример #19
0
/* some of this code is based on /usr/bin/time source code */
void
print_stats(struct timeval *start, struct timeval *end,
            struct rusage *ru, int status)
{
    unsigned long r;            /* Elapsed real milliseconds.  */
    unsigned long v;            /* Elapsed virtual (CPU) milliseconds.  */
    end->tv_sec -= start->tv_sec;
    if (end->tv_usec < start->tv_usec) {
        /* Manually carry a one from the seconds field.  */
        end->tv_usec += 1000000;
        --end->tv_sec;
    }
    end->tv_usec -= start->tv_usec;

    if (WIFSTOPPED (status)) {
        fprintf(FP, "Command stopped by signal %d\n",
                WSTOPSIG (status));
    } else if (WIFSIGNALED (status)) {
        fprintf(FP, "Command terminated by signal %d\n",
                WTERMSIG (status));
    } else if (WIFEXITED (status) && WEXITSTATUS (status)) {
        fprintf(FP, "Command exited with non-zero status %d\n",
                WEXITSTATUS (status));
    }

    /* Convert all times to milliseconds.  Occasionally, one of these values
       comes out as zero.  Dividing by zero causes problems, so we first
       check the time value.  If it is zero, then we take `evasive action'
       instead of calculating a value.  */
    
    r = end->tv_sec * 1000 + end->tv_usec / 1000;
    
    v = ru->ru_utime.tv_sec * 1000 + ru->ru_utime.TV_MSEC +
        ru->ru_stime.tv_sec * 1000 + ru->ru_stime.TV_MSEC;

    /* Elapsed real (wall clock) time.  */
    if (end->tv_sec >= 3600) {  /* One hour -> h:m:s.  */
        fprintf(FP, "%ld:%02ld:%02ldelapsed ",
                 end->tv_sec / 3600,
                 (end->tv_sec % 3600) / 60,
                 end->tv_sec % 60);
    } else {
        fprintf(FP, "%ld:%02ld.%02ldelapsed ",  /* -> m:s.  */
                 end->tv_sec / 60,
                 end->tv_sec % 60,
                 end->tv_usec / 10000);
    }
    /* % cpu is (total cpu time)/(elapsed time).  */
    if (r > 0)
        fprintf(FP, "%lu%%CPU ", (v * 100 / r));
    else
        fprintf(FP, "?%%CPU ");
    fprintf(FP, "%ld.%02lduser ",
            ru->ru_utime.tv_sec, ru->ru_utime.TV_MSEC / 10);
    fprintf(FP, "%ld.%02ldsystem ",
            ru->ru_stime.tv_sec, ru->ru_stime.TV_MSEC / 10);
    fprintf(FP, "(%ldmajor+%ldminor)pagefaults %ldswaps\n",
            ru->ru_majflt,/* Major page faults.  */
            ru->ru_minflt,/* Minor page faults.  */
            ru->ru_nswap); /* times swapped out */
    fprintf(FP, "(%lu tot, %lu RSS, %lu data, %lu stk, %lu exe, %lu lib)k\n",
            vmstats.VmSize, vmstats.VmRSS, vmstats.VmData,
            vmstats.VmStk, vmstats.VmExe, vmstats.VmLib);

#if VERBOSE
    fprintf(FP, "Memory usage:\n");
    fprintf(FP, "\tVmSize: %d kB\n", vmstats.VmSize);
    fprintf(FP, "\tVmLck: %d kB\n", vmstats.VmLck);
    fprintf(FP, "\tVmRSS: %d kB\n", vmstats.VmRSS);
    fprintf(FP, "\tVmData: %d kB\n", vmstats.VmData);
    fprintf(FP, "\tVmStk: %d kB\n", vmstats.VmStk);
    fprintf(FP, "\tVmExe: %d kB\n", vmstats.VmExe);
    fprintf(FP, "\tVmLib: %d kB\n", vmstats.VmLib);
#endif
}
/* Wait for a subprocess to finish.  Return its exit code.
   If it didn't terminate correctly, exit if exit_on_error is true, otherwise
   return 127.  */
int
wait_subprocess (pid_t child, const char *progname,
		 bool null_stderr,
		 bool slave_process, bool exit_on_error)
{
#if HAVE_WAITID && defined WNOWAIT && 0
  /* Commented out because waitid() with WNOWAIT doesn't work: On Solaris 7
     and OSF/1 4.0, it returns -1 and sets errno = ECHILD, and on HP-UX 10.20
     it just hangs.  */
  /* Use of waitid() with WNOWAIT avoids a race condition: If slave_process is
     true, and this process sleeps a very long time between the return from
     waitpid() and the execution of unregister_slave_subprocess(), and
     meanwhile another process acquires the same PID as child, and then - still
     before unregister_slave_subprocess() - this process gets a fatal signal,
     it would kill the other totally unrelated process.  */
  siginfo_t info;
  for (;;)
    {
      if (waitid (P_PID, child, &info, slave_process ? WNOWAIT : 0) < 0)
	{
# ifdef EINTR
	  if (errno == EINTR)
	    continue;
# endif
	  if (exit_on_error || !null_stderr)
	    error (exit_on_error ? EXIT_FAILURE : 0, errno,
		   _("%s subprocess"), progname);
	  return 127;
	}

      /* info.si_code is set to one of CLD_EXITED, CLD_KILLED, CLD_DUMPED,
	 CLD_TRAPPED, CLD_STOPPED, CLD_CONTINUED.  Loop until the program
	 terminates.  */
      if (info.si_code == CLD_EXITED
	  || info.si_code == CLD_KILLED || info.si_code == CLD_DUMPED)
	break;
    }

  /* The child process has exited or was signalled.  */

  if (slave_process)
    {
      /* Unregister the child from the list of slave subprocesses, so that
	 later, when we exit, we don't kill a totally unrelated process which
	 may have acquired the same pid.  */
      unregister_slave_subprocess (child);

      /* Now remove the zombie from the process list.  */
      for (;;)
	{
	  if (waitid (P_PID, child, &info, 0) < 0)
	    {
# ifdef EINTR
	      if (errno == EINTR)
		continue;
# endif
	      if (exit_on_error || !null_stderr)
		error (exit_on_error ? EXIT_FAILURE : 0, errno,
		       _("%s subprocess"), progname);
	      return 127;
	    }
	  break;
	}
    }

  switch (info.si_code)
    {
    case CLD_KILLED:
    case CLD_DUMPED:
      if (exit_on_error || !null_stderr)
	error (exit_on_error ? EXIT_FAILURE : 0, 0,
	       _("%s subprocess got fatal signal %d"),
	       progname, info.si_status);
      return 127;
    case CLD_EXITED:
      if (info.si_status == 127)
	{
	  if (exit_on_error || !null_stderr)
	    error (exit_on_error ? EXIT_FAILURE : 0, 0,
		   _("%s subprocess failed"), progname);
	  return 127;
	}
      return info.si_status;
    default:
      abort ();
    }
#else
  /* waitpid() is just as portable as wait() nowadays.  */
  WAIT_T status;

  *(int *) &status = 0;
  for (;;)
    {
      int result = waitpid (child, &status, 0);

      if (result != child)
	{
# ifdef EINTR
	  if (errno == EINTR)
	    continue;
# endif
# if 0 /* defined ECHILD */
	  if (errno == ECHILD)
	    {
	      /* Child process nonexistent?! Assume it terminated
		 successfully.  */
	      *(int *) &status = 0;
	      break;
	    }
# endif
	  if (exit_on_error || !null_stderr)
	    error (exit_on_error ? EXIT_FAILURE : 0, errno,
		   _("%s subprocess"), progname);
	  return 127;
	}

      /* One of WIFSIGNALED (status), WIFEXITED (status), WIFSTOPPED (status)
	 must always be true.  Loop until the program terminates.  */
      if (!WIFSTOPPED (status))
	break;
    }

  /* The child process has exited or was signalled.  */

  if (slave_process)
    /* Unregister the child from the list of slave subprocesses, so that
       later, when we exit, we don't kill a totally unrelated process which
       may have acquired the same pid.  */
    unregister_slave_subprocess (child);

  if (WIFSIGNALED (status))
    {
      if (exit_on_error || !null_stderr)
	error (exit_on_error ? EXIT_FAILURE : 0, 0,
	       _("%s subprocess got fatal signal %d"),
	       progname, (int) WTERMSIG (status));
      return 127;
    }
  if (WEXITSTATUS (status) == 127)
    {
      if (exit_on_error || !null_stderr)
	error (exit_on_error ? EXIT_FAILURE : 0, 0,
	       _("%s subprocess failed"), progname);
      return 127;
    }
  return WEXITSTATUS (status);
#endif
}
Пример #21
0
/******************************************************************************
 *                                                                            *
 * Function: zbx_waitpid                                                      *
 *                                                                            *
 * Purpose: this function waits for process to change state                   *
 *                                                                            *
 * Parameters: pid     - [IN] child process PID                               *
 *                                                                            *
 * Return value: on success, PID is returned. On error,                       *
 *               -1 is returned, and errno is set appropriately               *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static int	zbx_waitpid(pid_t pid)
{
	const char	*__function_name = "zbx_waitpid";
	int		rc, status;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	do
	{
#ifdef WCONTINUED
		static int	wcontinued = WCONTINUED;
retry:
		if (-1 == (rc = waitpid(pid, &status, WUNTRACED | wcontinued)))
		{
			if (EINVAL == errno && 0 != wcontinued)
			{
				wcontinued = 0;
				goto retry;
			}
#else
		if (-1 == (rc = waitpid(pid, &status, WUNTRACED)))
		{
#endif
			zabbix_log(LOG_LEVEL_DEBUG, "%s() waitpid failure: %s", __function_name, zbx_strerror(errno));
			goto exit;
		}

		if (WIFEXITED(status))
			zabbix_log(LOG_LEVEL_DEBUG, "%s() exited, status:%d", __function_name, WEXITSTATUS(status));
		else if (WIFSIGNALED(status))
			zabbix_log(LOG_LEVEL_DEBUG, "%s() killed by signal %d", __function_name, WTERMSIG(status));
		else if (WIFSTOPPED(status))
			zabbix_log(LOG_LEVEL_DEBUG, "%s() stopped by signal %d", __function_name, WSTOPSIG(status));
#ifdef WIFCONTINUED
		else if (WIFCONTINUED(status))
			zabbix_log(LOG_LEVEL_DEBUG, "%s() continued", __function_name);
#endif
	}
	while (!WIFEXITED(status) && !WIFSIGNALED(status));
exit:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, rc);

	return rc;
}

#endif	/* _WINDOWS */

/******************************************************************************
 *                                                                            *
 * Function: zbx_execute                                                      *
 *                                                                            *
 * Purpose: this function executes a script and returns result from stdout    *
 *                                                                            *
 * Parameters: command       - [IN] command for execution                     *
 *             buffer        - [OUT] buffer for output, if NULL - ignored     *
 *             error         - [OUT] error string if function fails           *
 *             max_error_len - [IN] length of error buffer                    *
 *                                                                            *
 * Return value: SUCCEED if processed successfully, TIMEOUT_ERROR if          *
 *               timeout occurred or FAIL otherwise                           *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
int	zbx_execute(const char *command, char **buffer, char *error, size_t max_error_len, int timeout)
{
	size_t			buf_size = PIPE_BUFFER_SIZE, offset = 0;
	int			ret = FAIL;
#ifdef _WINDOWS
	STARTUPINFO		si;
	PROCESS_INFORMATION	pi;
	SECURITY_ATTRIBUTES	sa;
	HANDLE			job = NULL, hWrite = NULL, hRead = NULL;
	char			*cmd = NULL;
	wchar_t			*wcmd = NULL;
	struct _timeb		start_time, current_time;
#else
	pid_t			pid;
	int			fd;
#endif

	*error = '\0';

	if (NULL != buffer)
	{
		*buffer = zbx_realloc(*buffer, buf_size);
		**buffer = '\0';
	}

#ifdef _WINDOWS

	/* set the bInheritHandle flag so pipe handles are inherited */
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	/* create a pipe for the child process's STDOUT */
	if (0 == CreatePipe(&hRead, &hWrite, &sa, 0))
	{
		zbx_snprintf(error, max_error_len, "unable to create a pipe: %s", strerror_from_system(GetLastError()));
		goto close;
	}

	/* create a new job where the script will be executed */
	if (0 == (job = CreateJobObject(&sa, NULL)))
	{
		zbx_snprintf(error, max_error_len, "unable to create a job: %s", strerror_from_system(GetLastError()));
		goto close;
	}

	/* fill in process startup info structure */
	memset(&si, 0, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	si.dwFlags = STARTF_USESTDHANDLES;
	si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
	si.hStdOutput = hWrite;
	si.hStdError = hWrite;

	/* use cmd command to support scripts */
	cmd = zbx_dsprintf(cmd, "cmd /C \"%s\"", command);
	wcmd = zbx_utf8_to_unicode(cmd);

	/* create the new process */
	if (0 == CreateProcess(NULL, wcmd, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
	{
		zbx_snprintf(error, max_error_len, "unable to create process [%s]: %s",
				cmd, strerror_from_system(GetLastError()));
		goto close;
	}

	CloseHandle(hWrite);
	hWrite = NULL;

	/* assign the new process to the created job */
	if (0 == AssignProcessToJobObject(job, pi.hProcess))
	{
		zbx_snprintf(error, max_error_len, "unable to assign process [%s] to a job: %s",
				cmd, strerror_from_system(GetLastError()));
		if (0 == TerminateProcess(pi.hProcess, 0))
		{
			zabbix_log(LOG_LEVEL_ERR, "failed to terminate [%s]: %s",
					cmd, strerror_from_system(GetLastError()));
		}
	}
	else if (-1 == ResumeThread(pi.hThread))
	{
		zbx_snprintf(error, max_error_len, "unable to assign process [%s] to a job: %s",
				cmd, strerror_from_system(GetLastError()));
	}
	else
		ret = SUCCEED;

	if (FAIL == ret)
		goto close;

	_ftime(&start_time);
	timeout *= 1000;

	ret = zbx_read_from_pipe(hRead, buffer, &buf_size, &offset, timeout);

	if (TIMEOUT_ERROR != ret)
	{
		_ftime(&current_time);
		if (0 < (timeout -= zbx_get_timediff_ms(&start_time, &current_time)) &&
				WAIT_TIMEOUT == WaitForSingleObject(pi.hProcess, timeout))
		{
			ret = TIMEOUT_ERROR;
		}
	}

	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);
close:
	if (NULL != job)
	{
		/* terminate the child process and it's childs */
		if (0 == TerminateJobObject(job, 0))
			zabbix_log(LOG_LEVEL_ERR, "failed to terminate job [%s]: %s", cmd, strerror_from_system(GetLastError()));
		CloseHandle(job);
	}

	if (NULL != hWrite)
		CloseHandle(hWrite);

	if (NULL != hRead)
		CloseHandle(hRead);

	zbx_free(cmd);
	zbx_free(wcmd);

#else	/* not _WINDOWS */

	alarm(timeout);

	if (-1 != (fd = zbx_popen(&pid, command)))
	{
		int	rc;
		char	tmp_buf[PIPE_BUFFER_SIZE];

		while (0 < (rc = read(fd, tmp_buf, sizeof(tmp_buf) - 1)) && MAX_EXECUTE_OUTPUT_LEN > offset + rc)
		{
			if (NULL != buffer)
			{
				tmp_buf[rc] = '\0';
				zbx_strcpy_alloc(buffer, &buf_size, &offset, tmp_buf);
			}
		}

		close(fd);

		if (-1 == rc || -1 == zbx_waitpid(pid))
		{
			if (EINTR == errno)
				ret = TIMEOUT_ERROR;
			else
				zbx_snprintf(error, max_error_len, "zbx_waitpid() failed: %s", zbx_strerror(errno));

			/* kill the whole process group, pid must be the leader */
			if (-1 == kill(-pid, SIGTERM))
				zabbix_log(LOG_LEVEL_ERR, "failed to kill [%s]: %s", command, zbx_strerror(errno));

			zbx_waitpid(pid);
		}
		else if (MAX_EXECUTE_OUTPUT_LEN <= offset + rc)
		{
			zabbix_log(LOG_LEVEL_ERR, "command output exceeded limit of %d KB",
					MAX_EXECUTE_OUTPUT_LEN / ZBX_KIBIBYTE);
		}
		else
			ret = SUCCEED;
	}
	else
		zbx_strlcpy(error, zbx_strerror(errno), max_error_len);

	alarm(0);

#endif	/* _WINDOWS */

	if (TIMEOUT_ERROR == ret)
		zbx_strlcpy(error, "Timeout while executing a shell script.", max_error_len);
	else if ('\0' != *error)
		zabbix_log(LOG_LEVEL_WARNING, "%s", error);

	if (SUCCEED != ret && NULL != buffer)
		zbx_free(*buffer);

	return ret;
}
Пример #22
0
/* exit codes: 0 = ok, 1 = invocation error, 3 = internal error */
int main(int argc, char *argv[])
{
    int envIdx = ArgEnv;
    int errNo;
    int chldPid;
    int chldStatus;
    int chldPipe[2];
    struct sockaddr_un sau;

    if (argc < ArgEnv) {
        fprintf(stderr, "This is an internal helper of Qt Creator. Do not run it manually.\n");
        return 1;
    }
    sleepMsg = argv[ArgMsg];

    /* Connect to the master, i.e. Creator. */
    if ((qtcFd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
        perror("Cannot create creator comm socket");
        doExit(3);
    }
    sau.sun_family = AF_UNIX;
    strcpy(sau.sun_path, argv[ArgSocket]);
    if (connect(qtcFd, (struct sockaddr *)&sau, sizeof(sau))) {
        fprintf(stderr, "Cannot connect creator comm socket %s: %s\n", sau.sun_path, strerror(errno));
        doExit(1);
    }

    if (*argv[ArgDir] && chdir(argv[ArgDir])) {
        /* Only expected error: no such file or direcotry */
        sendMsg("err:chdir %d\n", errno);
        return 1;
    }

    /* Create execution result notification pipe. */
    if (pipe(chldPipe)) {
        perror("Cannot create status pipe");
        doExit(3);
    }
    /* The debugged program is not supposed to inherit these handles. But we cannot
     * close the writing end before calling exec(). Just handle both ends the same way ... */
    fcntl(chldPipe[0], F_SETFD, FD_CLOEXEC);
    fcntl(chldPipe[1], F_SETFD, FD_CLOEXEC);
    switch ((chldPid = fork())) {
        case -1:
            perror("Cannot fork child process failed");
            doExit(3);
        case 0:
            close(qtcFd);

            /* Put the process into an own process group and make it the foregroud
             * group on this terminal, so it will receive ctrl-c events, etc.
             * This is the main reason for *all* this stub magic in the first place. */
            /* If one of these calls fails, the world is about to end anyway, so
             * don't bother checking the return values. */
            setpgid(0, 0);
            tcsetpgrp(0, getpid());

            /* Get a SIGTRAP after exec() has loaded the new program. */
#ifdef __linux__
            ptrace(PTRACE_TRACEME);
#else
            ptrace(PT_TRACE_ME, 0, 0, 0);
#endif

            for (envIdx = ArgEnv; *argv[envIdx]; ++envIdx) ;
            if (envIdx != ArgEnv) {
                argv[envIdx] = 0;
                environ = argv + ArgEnv;
            }
            ++envIdx;

            execvp(argv[envIdx], argv + envIdx);
            /* Only expected error: no such file or direcotry, i.e. executable not found */
            errNo = errno;
            write(chldPipe[1], &errNo, sizeof(errNo)); /* Only realistic error case is SIGPIPE */
            _exit(0);
        default:
            for (;;) {
                if (wait(&chldStatus) < 0) {
                    perror("Cannot obtain exit status of child process");
                    doExit(3);
                }
                if (WIFSTOPPED(chldStatus)) {
                    /* The child stopped. This can be only the result of ptrace(TRACE_ME). */
                    /* We won't need the notification pipe any more, as we know that
                     * the exec() succeeded. */
                    close(chldPipe[0]);
                    close(chldPipe[1]);
                    chldPipe[0] = -1;
                    /* If we are not debugging, just skip the "handover enabler".
                     * This is suboptimal, as it makes us ignore setuid/-gid bits. */
                    if (!strcmp(argv[ArgAction], "debug")) {
                        /* Stop the child after we detach from it, so we can hand it over to gdb.
                         * If the signal delivery is not queued, things will go awry. It works on
                         * Linux and MacOSX ... */
                        kill(chldPid, SIGSTOP);
                    }
#ifdef __linux__
                    ptrace(PTRACE_DETACH, chldPid, 0, 0);
#else
                    ptrace(PT_DETACH, chldPid, 0, 0);
#endif
                    sendMsg("pid %d\n", chldPid);
                } else if (WIFEXITED(chldStatus)) {
                    /* The child exited normally. */
                    if (chldPipe[0] >= 0) {
                        /* The child exited before being stopped by ptrace(). That can only
                         * mean that the exec() failed. */
                        switch (read(chldPipe[0], &errNo, sizeof(errNo))) {
                            default:
                                /* Read of unknown length. Should never happen ... */
                                errno = EPROTO;
                            case -1:
                                /* Read failed. Should never happen, either ... */
                                perror("Cannot read status from child process");
                                doExit(3);
                            case sizeof(errNo):
                                /* Child telling us the errno from exec(). */
                                sendMsg("err:exec %d\n", errNo);
                                return 3;
                        }
                    }
                    sendMsg("exit %d\n", WEXITSTATUS(chldStatus));
                    doExit(0);
                } else {
                    sendMsg("crash %d\n", WTERMSIG(chldStatus));
                    doExit(0);
                }
            }
            break;
    }
}
Пример #23
0
static void
l2tpd_watch_cb (GPid pid, gint status, gpointer user_data)
{
	NML2tpPlugin *plugin = NM_L2TP_PLUGIN (user_data);
	NML2tpPluginPrivate *priv = NM_L2TP_PLUGIN_GET_PRIVATE (plugin);
	guint error = 0;
	pid_t my_pid = getpid ();
	char *filename;

	if (WIFEXITED (status)) {
		error = WEXITSTATUS (status);
		if (error != 0)
			g_warning (_("xl2tpd exited with error code %d"), error);
	}
	else if (WIFSTOPPED (status))
		g_warning (_("xl2tpd stopped unexpectedly with signal %d"), WSTOPSIG (status));
	else if (WIFSIGNALED (status))
		g_warning (_("xl2tpd died with signal %d"), WTERMSIG (status));
	else
		g_warning (_("xl2tpd died from an unknown cause"));

	/* Reap child if needed. */
	waitpid (priv->pid_l2tpd, NULL, WNOHANG);
	priv->pid_l2tpd = 0;

	if(priv->ipsec_up) {
		nm_l2tp_stop_ipsec();
	}

	/* Cleaning up config files */
	filename = g_strdup_printf ("/var/run/nm-xl2tpd.conf.%d", my_pid);
	unlink(filename);
	g_free(filename);

	filename = g_strdup_printf ("/var/run/nm-ppp-options.xl2tpd.%d", my_pid);
	unlink(filename);
	g_free(filename);

	filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d/ipsec.conf", my_pid);
//	unlink(filename);
	g_free(filename);

	filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d/ipsec.secrets", my_pid);
//	unlink(filename);
	g_free(filename);

	filename = g_strdup_printf ("/var/run/nm-ipsec-l2tp.%d", my_pid);
	rmdir(filename);
	g_free(filename);

	/* Must be after data->state is set since signals use data->state */
	switch (error) {
	case 16:
		/* hangup */
		// FIXME: better failure reason
		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
		break;
	case 2:
		/* Couldn't log in due to bad user/pass */
		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
		break;
	case 1:
		/* Other error (couldn't bind to address, etc) */
		nm_vpn_plugin_failure (NM_VPN_PLUGIN (plugin), NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
		break;
	default:
		break;
	}

	nm_vpn_plugin_set_state (NM_VPN_PLUGIN (plugin), NM_VPN_SERVICE_STATE_STOPPED);
}
Пример #24
0
//--------------------------------------------------------------------------
void linux_debmod_t::tdb_update_threads(void)
{
  if ( ta != NULL )
  {
    thrinfovec_t newlist;
    td_err_e err = td_ta_thr_iter(ta, update_threads_cb, &newlist,
                                  TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
                                  TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
    COMPLAIN_IF_FAILED("td_ta_thr_iter", err);
    if ( err != TD_OK )
      return;

    // generate THREAD_EXIT events
    for ( threads_t::iterator p=threads.begin(); p != threads.end(); ++p )
    {
      int i;
      int tid = p->first;
      for ( i=0; i < newlist.size(); i++ )
        if ( newlist[i].ti_lid == tid )
          break;
      if ( i == newlist.size() ) // not found
      {
        debug_event_t ev;
        ev.eid     = THREAD_EXIT;
        ev.pid     = process_handle;
        ev.tid     = tid;
        ev.ea      = BADADDR;
        ev.handled = true;
        ev.exit_code = 0; // ???
        enqueue_event(ev, IN_BACK);
      }
    }

    // generate THREAD_START events
    for ( int i=0; i < newlist.size(); i++ )
    {
      int tid = newlist[i].ti_lid;
//      display_thrinfo(tid);
      threads_t::iterator p = threads.find(tid);
      if ( p == threads.end() ) // not found
      {
        debug_event_t ev;
        ev.eid     = THREAD_START;
        ev.pid     = process_handle;
        ev.tid     = tid;
        ev.ea      = birth_bpt.bpt_addr; // just to show something
        ev.handled = true;
        add_thread(tid);
        enqueue_event(ev, IN_FRONT);
        // attach to the thread and make is ready for debugging
        qptrace(PTRACE_ATTACH, tid, 0, 0);
        int status;
        int tid2 = waitpid(tid, &status, __WCLONE); // (must succeed) consume SIGSTOP
        QASSERT(tid2 != -1 && WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
        get_thread(tid)->waiting_sigstop = false;

      }
      get_thread(tid)->thr = newlist[i].th_p;
    }
  }
}
Пример #25
0
void
run_phase (phases_t phase, char *name, string_list_t *args)
{
	char **argv;
	int argc = 1;
	string_item_t *p;
	char *output = NULL;
	char *input = NULL;
	boolean save_stderr = FALSE;
	int fdin, fdout;
	int forkpid;
	int waitpid;
	int waitstatus;
	int termsig;
	int	num_maps;
	char *rld_path, *absoft_path;
	struct stat stat_buf;
	const boolean uses_message_system = 
			(phase == P_f90_fe || phase == P_f90_cpp ||
			 phase == P_cppf90_fe);

#if defined(__APPLE__)
        // pass -Wa,-W to assembler so we ignore unknowns
        int hack_as_W = 0;
        if (strcmp(name, "/usr/bin/gcc") == 0)
        {
                hack_as_W = 1;
		argc++;
        }
#endif

	if (show_flag) {
		/* echo the command */
		fprintf(stderr, "%s ", name);
		print_string_list(stderr, args);
	}
	if (!execute_flag) return;

	if (time_flag) init_time();

	/* copy arg_list to argv format that exec wants */
	for (p = args->head; p != NULL; p=p->next) {
		//bug# 581, bug #932, bug #1049
		if (p->name == NULL) 
                  continue;
		argc++;
	}

	argv = (char **) malloc((argc+1)*sizeof(char*));
	argv[0] = name;
	for (argc = 1, p = args->head; p != NULL; argc++, p=p->next) {
		//bug# 581, bug #932
		if (p->name[0] == '\0') {
		  argc--;
                  continue;
		}
		/* don't put redirection in arg list */
		if (strcmp(p->name, "<") == 0) {
			/* has input file */
			input = p->next->name;
			break;
		} else if (strcmp(p->name, ">") == 0) {
			/* has output file */
			output = p->next->name;
			break;
		} else if (strcmp(p->name, ">&") == 0) {
			/* has error output file */
			output = p->next->name;
			save_stderr = TRUE;
			break;
		}
		argv[argc] = p->name;
	}
#if defined(__APPLE__)
	if (hack_as_W)
	{
#ifndef Is_True_On
		argv[argc++] = ""; // "-Wa,-W";
#endif
	}
#endif
	argv[argc] = NULL;

	/* fork a process */
	forkpid = fork();
	if (forkpid == -1) {
		error("no more processes");
		cleanup ();
		do_exit (RC_SYSTEM_ERROR);
		/* NOTREACHED */
	}

	if (forkpid == 0) {
		char *my_path, *l_path, *l32_path, *nls_path, *env_path;
		
		/* child */
		/* if we want memory stats, we have to wait for
		   parent to connect to our /proc */
		if (input != NULL) {
			if ((fdin = open (input, O_RDONLY)) == -1) {
				error ("cannot open input file %s", input);
				cleanup ();
				do_exit (RC_SYSTEM_ERROR);
				/* NOTREACHED */
			}
	    		dup2 (fdin, fileno(stdin));
		}
		if (output != NULL) {
			if ((fdout = creat (output, 0666)) == -1) {
				error ("cannot create output file %s", output);
				cleanup ();
				do_exit (RC_SYSTEM_ERROR);
				/* NOTREACHED */
			}
			if (save_stderr) {
	    			dup2 (fdout, fileno(stderr));
			} else {
	    			dup2 (fdout, fileno(stdout));
			}
		} 

		my_path = get_binutils_lib_path();
		rld_path = get_phase_ld_library_path (phase);
		absoft_path = get_absoft_ld_library_path (phase);
		
		if (absoft_path != 0)
			asprintf(&my_path, "%s:%s", my_path, absoft_path);

		if (rld_path != 0)
			asprintf(&my_path, "%s:%s", my_path, rld_path);
		
		l_path = l32_path = my_path;
		
		if (ld_library_path)
			asprintf(&l_path, "%s:%s", my_path, ld_library_path);

		if (ld_libraryn32_path)
			asprintf(&l32_path, "%s:%s", my_path,
				 ld_libraryn32_path);

		my_putenv("LD_LIBRARY_PATH", l_path);
		my_putenv("LD_LIBRARYN32_PATH", l32_path);
		
		// Set up NLSPATH, for the Fortran front end.

		nls_path = getenv("NLSPATH");
		env_path = get_phase_dir(P_f90_fe);

		if (nls_path) {
		    my_putenv("NLSPATH", "%s:%s/%%N.cat", nls_path, env_path);
		} else {
		    my_putenv("NLSPATH", "%s/%%N.cat", env_path);
		}

		if (uses_message_system && getenv("ORIG_CMD_NAME") == NULL)
		   my_putenv("ORIG_CMD_NAME", "%s", program_name);

		if (phase == P_f90_fe) {
		   char *root;
		   char *modulepath;
		   int len;
		   char *new_env;
		   char *env_name = "FORTRAN_SYSTEM_MODULES=";
		   char *env_val = "/usr/lib/f90modules";
		   root = getenv("TOOLROOT");
		   if (root != NULL) {
		      len = strlen(env_val) + strlen(root) +3 + strlen(env_val);
		      new_env = alloca(len);
		      sprintf(new_env,"%s/%s:%s",root,env_val,env_val);
		      env_val = new_env;
		   }
		   modulepath = string_copy(getenv("FORTRAN_SYSTEM_MODULES"));
		   if (modulepath != NULL) {
		      /* Append env_val to FORTRAN_SYSTEM_MODULES */
		      if (modulepath[strlen(modulepath)-1] == ':') {
			 /* Just append env_val */
			 len = strlen(modulepath) + strlen(env_val) + 1;
			 new_env = alloca(len);
			 sprintf(new_env,"%s%s",modulepath,env_val);
		      } else {
			 /* append :env_val */
			 len = strlen(modulepath) + strlen(env_val) + 2;
			 new_env = alloca(len);
			 sprintf(new_env,"%s:%s",modulepath,env_val);
		      }
		      env_val = new_env;
		   }
		   
		   my_putenv ("FORTRAN_SYSTEM_MODULES", "%s", env_val);
		}
		/* need to setenv COMPILER_PATH for collect to find ld */
		my_putenv ("COMPILER_PATH", "%s", get_phase_dir(P_collect));

		/* Tell IPA where to find the driver. */
#if defined(ABSOFT_EXTENSIONS)
		my_putenv ("COMPILER_BIN", "%s/" PSC_NAME_PREFIX "f90",
				get_executable_dir());
#else
		my_putenv ("COMPILER_BIN", "%s/" PSC_NAME_PREFIX "cc-"
			   PSC_FULL_VERSION, get_executable_dir());
#endif

		my_execv(name, argv);
	} else {
		/* parent */
		int procid;	/* id of the /proc file */
		while ((waitpid = wait (&waitstatus)) != forkpid) {
			if (waitpid == -1) {
				error("bad return from wait");
				cleanup();
				do_exit(RC_SYSTEM_ERROR);
				/* NOTREACHED */
			}
		}
		if (time_flag) print_time(name);

		if (WIFSTOPPED(waitstatus)) {
			termsig = WSTOPSIG(waitstatus);
			error("STOPPED signal received from %s", name);
			cleanup();
			do_exit(RC_SYSTEM_ERROR);
			/* NOTREACHED */
		} else if (WIFEXITED(waitstatus)) {
		        int status = WEXITSTATUS(waitstatus);
			extern int inline_t;
			boolean internal_err = FALSE;
			boolean user_err = FALSE;
		
			if (phase == P_prof) {
                           /* Make sure the .cfb files were created before
                              changing the STATUS to OKAY */
                           if (prof_file != NULL) {
                              if (!(stat(fb_file, &stat_buf) != 0 && errno == ENOENT))
                                  status = RC_OKAY;
                           } else {
			      internal_error("No count file was specified for a prof run");
			      perror(program_name);
                           }
                        }

			if (phase == P_f90_fe && keep_listing) {
			    char *cif_file;
			    cif_file = construct_given_name(
					  drop_path(source_file), "T", TRUE);
                            if (!(stat(cif_file, &stat_buf) != 0 && errno == ENOENT))
			       f90_fe_status = status;
			       f90_fe_name = string_copy(name);

			       /* Change the status to OKAY so that we can 
				* execute the lister on the cif_file; we will
				* take appropriate action on this status once 
				* the lister has finished executing. See below.
				*/

			       status = RC_OKAY;
                        }

			if (phase == P_lister) {
			   if (status == RC_OKAY && f90_fe_status != RC_OKAY) {

			      /* We had encountered an error in the F90_fe phase
			       * but we ignored it so that we could execute the
			       * lister on the cif file; we need to switch the
			       * status to the status we received from F90_fe
			       * and use the name of the F90_fe_phase, so that
			       * we can issue a correct error message.
			       */

			       status = f90_fe_status;
			       name = string_copy(f90_fe_name);

			       /* Reset f90_fe_status to OKAY for any further
				* compilations on other source files.
				*/

			       f90_fe_status = RC_OKAY;
                           }
                        }

			switch (status) {
			case RC_OKAY:
				if (inline_t == UNDEFINED
				    && is_matching_phase(
					get_phase_mask(phase), P_any_fe) )
				{
					inline_t = FALSE;
				}
				break;
			case RC_NEED_INLINER:
				if (inline_t == UNDEFINED
				    && is_matching_phase(
					get_phase_mask(phase), P_any_fe) )
				{
					inline_t = TRUE;
				}
				/* completed successfully */
				break;
				
			case RC_USER_ERROR:
			case RC_NORECOVER_USER_ERROR:
			case RC_SYSTEM_ERROR:
			case RC_GCC_ERROR:
				user_err = TRUE;
				break;

			case RC_OVERFLOW_ERROR:
				if (!ran_twice && phase == P_be) {
					/* try recompiling with larger limits */
					ran_twice = TRUE;
					add_string (args, "-TENV:long_eh_offsets");
					add_string (args, "-TENV:large_stack");
					run_phase (phase, name, args);
					return;
				}
				internal_err = TRUE;
				break;
			case RC_INTERNAL_ERROR:
				internal_err = TRUE;
				break;
			default:
				internal_err = TRUE;
				break;
			} 
			if (internal_err) {
				if (phase == P_ld || phase == P_ldplus ||
#ifdef KEY
				    phase == P_gas ||	// bug 4846
#endif
				    phase == P_gcpp || phase == P_gcpp_plus) {
					if (phase == P_gas)
						internal_error_occurred = 1;
					log_error("%s returned non-zero status %d",
						  name, status);
					nomsg_error(status);
				} else {
					internal_error("%s returned non-zero status %d",
						       name, status);
				}
			}
			else if (user_err) {
				/* assume phase will print diagnostics */
				if (phase == P_c_gfe || phase == P_cplus_gfe) {
					nomsg_error(RC_INTERNAL_ERROR);
				}
				else if (!show_flag || save_stderr) {
					nomsg_error(RC_USER_ERROR);
				} else {
					error("%s returned non-zero status %d",
						name, status);
				}
			}
			ran_twice = FALSE;
			return;
		} else if(WIFSIGNALED(waitstatus)){
			termsig = WTERMSIG(waitstatus);
			switch (termsig) {
			case SIGHUP:
			case SIGINT:
			case SIGQUIT:
			case SIGKILL:
			case SIGTERM:
				error("%s died due to signal %d", name, termsig);
				break;
			default:
				internal_error("%s died due to signal %d",
					       name, termsig);
				break;
			}
#ifndef __CYGWIN__
			if(waitstatus & WCOREFLAG) {
				error("core dumped");
			}
#endif
			if (termsig == SIGKILL) {
				error("Probably caused by running out of swap space -- check %s", LOGFILE);
			}
			cleanup();
			do_exit(RC_SYSTEM_ERROR);
		} else {
			/* cannot happen, I think! */
			internal_error("driver exec'ing is confused");
			return;
		}
	}
}
Пример #26
0
/** Main loop for the Event Dispatcher process.
 * 
 */
int dispatcher_main_loop(void)
{
   struct pollfd poll_fds[3+MAX_AS_NR],*poll_tmp;
   int clean_index,i,j,k,fd,poll_events=0,socks[2],chld_status;
   int as_nr,unc_as_nr;
   pid_t chld;
   struct timeval last_ping,now;
   struct as_entry *as;

   sig_flag=0;
   is_dispatcher=1;
   as_nr=0;

   timerclear(&last_ping);
   timerclear(&now);
   signal(SIGCHLD,seas_sighandler);
   signal(SIGTERM,seas_sighandler);
   signal(SIGUSR1,seas_sighandler);
   signal(SIGINT, seas_sighandler);
   signal(SIGKILL,seas_sighandler);

   strcpy(whoami,"Seas Event Dispatcher process");
   /*I set process_no to -1 because otherwise, the logging process confuses this process with another from SER
    * (see LM_*() and dprint() and my_pid())*/
   process_no = -1;

   if(open_server_sockets(seas_listen_ip,seas_listen_port,socks)==-1){
      LM_ERR("unable to open server sockets on dispatcher\n");
      return -1;
   }
   for(i=0;i<2;i++){
      poll_fds[i].fd=socks[i];
      poll_fds[i].revents=0;
      poll_fds[i].events=POLLIN;
   }
   poll_fds[2].fd=read_pipe;
   poll_fds[2].revents=0;
   poll_fds[2].events=POLLIN;/*pollhup ?*/

   poll_events=0;
   unc_as_nr=0;

   if(use_ha)
      spawn_pinger();

   while(1){
      if(sig_flag==SIGCHLD){
	 while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
	    if (WIFEXITED(chld_status)){
	       LM_INFO("child process %d exited normally, status=%d\n",
				   chld,WEXITSTATUS(chld_status));
	    }else if (WIFSIGNALED(chld_status)) {
	       LM_INFO("child process %d exited by a signal %d\n",
				   chld,WTERMSIG(chld_status));
	    }else if (WIFSTOPPED(chld_status)) 
	       LM_INFO("child process %d stopped by a signal %d\n",
				   chld,WSTOPSIG(chld_status));
	    for (as=as_list;as;as=as->next) {
	       if(as->type!=AS_TYPE)
		  continue;
	       if(as->u.as.action_pid==chld){
		  for(i=0;i<as_nr && ((poll_fds[3+i].fd)!=(as->u.as.event_fd));i++)
		     ;
		  if(i==as_nr){
		     LM_ERR("Either the pinger has died or BUG found..\n");
		     continue;
		  }
		  /*overwrite the obsolete 'i' position with the next position*/
		  for(j=3+i;j<(as_nr+unc_as_nr+3-1);i++){
		     poll_fds[j].fd=poll_fds[j+1].fd;
		     poll_fds[j].events=poll_fds[j+1].events;
		     poll_fds[j].revents=poll_fds[j+1].revents;
		  }
		  close(as->u.as.event_fd);/*close the socket fd*/
		  if (as->u.as.ev_buffer.s) {
		     pkg_free(as->u.as.ev_buffer.s);
		     as->u.as.ev_buffer.s=(char *)0;
		     as->u.as.ev_buffer.len=0;
		  }
		  as->u.as.event_fd=as->u.as.action_fd=-1;
		  as->connected=0;
		  destroy_pingtable(&as->u.as.jain_pings);
		  destroy_pingtable(&as->u.as.servlet_pings);
		  as_nr--;
		  LM_WARN("client [%.*s] leaving (Action Dispatcher Process died !)\n",
				  as->name.len,as->name.s);
		  break;
	       }/*if(action_pid==chld)*/
	    }/*for(as=as_list;as;as=as->next)*/
	 }/*while(waitpid(-1)>0)*/
      }else if (sig_flag) {
	 LM_WARN("received signal != sigchld(%d)\n",sig_flag);
	  }
      sig_flag=0;
      clean_index=0;
      LM_INFO("polling [2 ServSock] [1 pipe] [%d App Servers]"
			  " [%d Uncomplete AS]\n",as_nr,unc_as_nr);
      poll_events = poll(poll_fds,3+unc_as_nr+as_nr,-1);
      if (poll_events == -1) {
	 if(errno==EINTR){
	    /*handle the case a child has died.
	     * It will be done in the next iteration in if(seas_sigchld_received)*/
	    continue;
	 }
	 if(errno==EBADF){
	    LM_ERR("invalid file descriptor pased to poll (%s)\n",
				strerror(errno));
	    return -1;/*??*/
	 }
	 /* errors */
	 LM_ERR("poll'ing:%s\n",strerror(errno));
	 poll_events=0;
	 continue;
      } else if (poll_events == 0) {/*timeout*/
	 continue;
      } else {/*there are events !*/
	 /*handle connections from server sockets*/
	 for(i=0;i<2;i++){
	    if(poll_fds[i].revents)
	       poll_events--;
	    if(poll_fds[i].revents & POLLIN){
	       poll_fds[i].revents &= (~POLLIN);
	       if((fd=new_as_connect(socks[i],i==0?'e':'a'))>=0){
		  poll_tmp=&poll_fds[3+as_nr+unc_as_nr];
		  poll_tmp->fd=fd;
		  poll_tmp->events=POLLIN|POLLHUP;
		  unc_as_nr++;
		  LM_DBG("Have new %s client\n",i==0?"event":"action");
	       }else{
		  LM_ERR("accepting connection from AS\n");
	       }
	    }
	 }
	 /*handle data from pipe*/
	 if(poll_fds[2].revents & POLLIN){
	    poll_fds[2].revents &= (~POLLIN);
	    poll_events--;
	    if(dispatch_relay()<0){
	       LM_ERR("dispatch_relay returned -1"
		     "should clean-up table\n");
	    }
	 }
	 /*now handle receive data from completed AS*/
	 clean_index=0;
	 LM_DBG("Scanning data from %d AS\n",as_nr);
	 for(i=0;(i<as_nr) && poll_events;i++){
	    clean_index=0;
	    poll_tmp=&poll_fds[3+i];
	    if(poll_tmp->revents)
	       poll_events--;
	    if(poll_tmp->revents & POLLIN){
	       LM_DBG("POLLIN found in AS #%i\n",i);
	       poll_tmp->revents &= (~POLLIN);
	       switch(handle_as_data(poll_tmp->fd)){
		  case -2:/*read returned 0 bytes, an AS client is leaving*/
		     clean_index=1;
		     break;
		  case -1:/*shouldnt happen*/
		     LM_ERR("reading from AS socket\n");
		     break;
		  case 0:/* event_response received and processed*/
		     break;
		  default:
		     LM_WARN("unknown return type from handle_as_data\n");
	       }
	    }
	    if(clean_index || (poll_tmp->revents & POLLHUP)){
	       LM_DBG("POLHUP or read==0 found in %i AS \n",i);
	       clean_index=0;
	       poll_tmp->revents = 0;
	       for(as=as_list;as;as=as->next){
		  if(as->type==CLUSTER_TYPE)
		     continue;
		  if(as->connected && (as->u.as.event_fd == poll_tmp->fd)){
		     close(poll_tmp->fd);/*close the socket fd*/
		     /*TODO  we should send a signal to the Action Dispatcher !!!*/
		     as->connected=0;
		     as_nr--;
		     /*overwrite the obsolete 'i' position with the next position*/
		     for(k=i;k<(as_nr+unc_as_nr);k++){
			j=3+k;
			poll_fds[j].fd=poll_fds[j+1].fd;
			poll_fds[j].events=poll_fds[j+1].events;
			poll_fds[j].revents=poll_fds[j+1].revents;
		     }
		     --i;
		     LM_WARN("client %.*s leaving !!!\n",as->name.len,as->name.s);
		     break;
		  }
	       }
	       if (!as) {
		  LM_ERR("the leaving client was not found in the as_list\n");
		   }
	    }
	 }
	 /*now handle data sent from uncompleted AS*/
	 LM_DBG("Scanning data from %d uncomplete AS \n",unc_as_nr);
	 clean_index=0;
	 for(i=0;i<unc_as_nr && poll_events;i++){
	    poll_tmp=&poll_fds[3+as_nr+i];
	    if(poll_tmp->revents)
	       poll_events--;
	    if(poll_tmp->revents & POLLIN){
	       LM_DBG("POLLIN found in %d uncomplete AS \n",i);
	       poll_tmp->revents &= (~POLLIN);
	       fd=handle_unc_as_data(poll_tmp->fd);
	       if(fd>0){
		  /* there's a new AS, push the uncomplete poll_fds up and set the AS */
		  for(k=i;k>0;k--){
		     j=3+as_nr+k;
		     poll_fds[j].fd=poll_fds[j-1].fd;
		     poll_fds[j].events=poll_fds[j-1].events;
		     poll_fds[j].revents=poll_fds[j-1].revents;
		  }
		  poll_fds[3+as_nr].fd=fd;
		  poll_fds[3+as_nr].events=POLLIN|POLLHUP;
		  poll_fds[3+as_nr].revents=0;
		  as_nr++;/*not very sure if this is thread-safe*/
		  unc_as_nr--;
	       }else if(fd<=0){/* pull the upper set of uncomplete AS down and take this one out*/
		  poll_tmp->revents=0;
		  for(k=i;k<(unc_as_nr-1);k++){
		     j=3+as_nr+k;
		     poll_fds[j].fd=poll_fds[j+1].fd;
		     poll_fds[j].events=poll_fds[j+1].events;
		     poll_fds[j].revents=poll_fds[j+1].revents;
		  }
		  unc_as_nr--;
		  /** we decrement i so that pulling down the upper part of the unc_as array so that
		   * it doesn't affect our for loop */
		  i--;
	       }
	    }
	    if(poll_tmp->revents & POLLHUP){
	       LM_DBG("POLLHUP found in %d uncomplete AS \n",i);
	       close(poll_tmp->fd);
	       for(k=i;k<(unc_as_nr-1);k++){
		  j=3+as_nr+k;
		  poll_fds[j].fd=poll_fds[j+1].fd;
		  poll_fds[j].events=poll_fds[j+1].events;
		  poll_fds[j].revents=poll_fds[j+1].revents;
	       }
	       unc_as_nr--;
	       i--;
	       poll_tmp->revents = 0;
	    }
	 }/*for*/
      }/*else ...(poll_events>0)*/
   }/*while(1)*/
}
Пример #27
0
pid_t
waitpid(
    pid_t pid,			/* The pid to wait on. Must be -1 or greater
				 * than zero. */
    int *statusPtr,		/* Where to store wait status for the
				 * process. */
    int options)		/* OR'ed combination of WNOHANG and
				 * WUNTRACED. */
{
    register WaitInfo *waitPtr, *prevPtr;
    pid_t result;
    WAIT_STATUS_TYPE status;

    if ((pid < -1) || (pid == 0)) {
	errno = EINVAL;
	return -1;
    }

    /*
     * See if there's a suitable process that has already stopped or exited.
     * If so, remove it from the list of exited processes and return its
     * information.
     */

    for (waitPtr = deadList, prevPtr = NULL; waitPtr != NULL;
	    prevPtr = waitPtr, waitPtr = waitPtr->nextPtr) {
	if ((pid != waitPtr->pid) && (pid != -1)) {
	    continue;
	}
	if (!(options & WUNTRACED) && (WIFSTOPPED(waitPtr->status))) {
	    continue;
	}
	result = waitPtr->pid;
	*statusPtr = *((int *) &waitPtr->status);
	if (prevPtr == NULL) {
	    deadList = waitPtr->nextPtr;
	} else {
	    prevPtr->nextPtr = waitPtr->nextPtr;
	}
	ckfree((char *) waitPtr);
	return result;
    }

    /*
     * Wait for any process to stop or exit. If it's an acceptable one then
     * return it to the caller; otherwise store information about it in the
     * list of exited processes and try again. On systems that have only wait
     * but not wait3, there are several situations we can't handle, but we do
     * the best we can (e.g. can still handle some combinations of options by
     * invoking wait instead of wait3).
     */

    while (1) {
#if NO_WAIT3
	if (options & WNOHANG) {
	    return 0;
	}
	if (options != 0) {
	    errno = EINVAL;
	    return -1;
	}
	result = wait(&status);
#else
	result = wait3(&status, options, 0);
#endif
	if ((result == -1) && (errno == EINTR)) {
	    continue;
	}
	if (result <= 0) {
	    return result;
	}

	if ((pid != result) && (pid != -1)) {
	    goto saveInfo;
	}
	if (!(options & WUNTRACED) && (WIFSTOPPED(status))) {
	    goto saveInfo;
	}
	*statusPtr = *((int *) &status);
	return result;

	/*
	 * Can't return this info to caller. Save it in the list of stopped or
	 * exited processes. Tricky point: first check for an existing entry
	 * for the process and overwrite it if it exists (e.g. a previously
	 * stopped process might now be dead).
	 */

    saveInfo:
	for (waitPtr = deadList; waitPtr != NULL; waitPtr = waitPtr->nextPtr) {
	    if (waitPtr->pid == result) {
		waitPtr->status = status;
		goto waitAgain;
	    }
	}
	waitPtr = (WaitInfo *) ckalloc(sizeof(WaitInfo));
	waitPtr->pid = result;
	waitPtr->status = status;
	waitPtr->nextPtr = deadList;
	deadList = waitPtr;

    waitAgain:
	continue;
    }
}
Пример #28
0
int main(int argc, char *argv[]) 
{
	
		char *line;
		char *prompt = "myshell>";
		char *envPrompt = "DASH_PROMPT";
		char *args[2048];
		char *str;
		char *multiCmd[2048];
				
		int i=0;
		int flag;
	        int jobid;
		int code;
		int fd1,fd2;	
					
		tcpid = getpgrp();
		
		ObjectPtr myObj;
		NodePtr node;

		lst = createList(getKey,toString,freeObject);  // Creating a List
			
		prompt = getenv(envPrompt);

		if(prompt == NULL)
			prompt = "myshell>";
		
		using_history();

		if(signal(SIGINT,signalHandling) == SIG_ERR){}
		
		if(signal(SIGTSTP,signalHandling) == SIG_ERR){}

		if(signal(SIGTTOU,SIG_IGN)==SIG_ERR){}
		if(signal(SIGCHLD,SIG_DFL)==SIG_ERR){}

		if((argc == 2) && (strcmp(argv[1],"-v")==0))
		{
			printf("%s\n",svn_version());
			exit(0);
		}
			
		code = sigsetjmp(env,TRUE);
				
		while ((line=readline(prompt))) 		// Reading Input
		{
			if(line==NULL)
			{	
				printf("\n read line failed \n");
				continue;
			}
			
		      	add_history(line);
 
			str = (char *)mymalloc(sizeof(char)*(strlen(line)+1));
			strcpy(str,line);
											
			if(str[0] == '&' || str[0] == ';')
			{
				printf("dash: syntax error near unexpected token %c \n",str[0]);
				freeVar(line,str,args);
				continue;
			}
			
			while((pid = waitpid(-1,NULL,WNOHANG)) > 0)
			{
				node = search(lst,pid);
				((ObjectPtr)(node->obj))->jobStatus = 0;
				printf("%s\n",(*toString)(node->obj));
				removeNode(lst,node);
			}
			
						
			if(checkMultiCmd(str, multiCmd)== -1)
				continue;
			
			while(multiCmd[i])			
			{
				flag = searchAmp(multiCmd[i]);	// Function to check if there is an '&' in the Command
				struct IORedirect *ior = tokenize(multiCmd[i],args);
				if((int)ior == -1)
				break;		       // Parsing the Command that needs to be executed
				
				if(exitLogout(multiCmd[i]))	// Function to check Exit and Logout Commands
				{
					if(checkStoppedJobs())
					{
						//memset(multiCmd,0,sizeof(multiCmd));
						break;
					}
					else
					{
						freeVar(line,str,args);
						freeList(lst);
						memset(multiCmd,'\0',sizeof(multiCmd));
						myfree(ior);
						exit(0);
					}
				}
				if(checkEOF(multiCmd[i]))			// Function to check EOF
				{
					freeVar(line,str,args);
					memset(multiCmd,'\0',sizeof(multiCmd));	
					freeList(lst);
					myfree(ior);
					exit(0);
				}
				if(checkEmptyCmd(multiCmd[i]))		// Function to Check if Enter Key is pressed
				break;
			
			
				if((strcmp(args[0],"cd")==0) && (flag == FALSE))  // Function to check if 'cd' command is used
				{
					chgDir(args);
					break;
				}
			
				if((strcmp(args[0],"jobs")==0) && (flag == FALSE)) // Function to check if 'jobs' command is used
				{
					jobsCmd();
					break;
				}
			
				if(strcmp(args[0],"history")==0)
        		        {
                     	        	printHistory(args, str, flag);
	                                break;
       			        }
	
				if((strcmp(args[0],"bg") == 0) && (flag == FALSE))
				{
					bgCmd(args);
					break;
				}
					
				if((strcmp(args[0],"fg")==0) && (flag == FALSE))
				{
					fgCmd(args);
					break;
				}
			
				if(ampCount(multiCmd[i]))
				{
					printf(" dash: syntax error near unexpected token '&' \n");
					break;
				}
				if ( (pid = fork()) < 0)		// Forking a Process
				err_sys("fork error");
					
				else if (pid == 0) 
				{		
					struct stat buf;
					/* child */
    				     	if(flag == TRUE)
					{
						if(setpgid(0,0)!=0)
						perror("setpid() error");
					
						if(tcsetpgrp(0,tcpid)!=0)
						perror("tcsetpgrp() error");
					}
				
					if(ior->input != NULL)
					{
					
						if((fd1 = stat(ior->input,&buf))==-1){
                	                        printf("dash: %s file does not exist\n",ior->input);
                       			        break;
                                        	}

                                        	if((fd1= access(ior->input,R_OK))==-1){
                                   	        printf("dash: %s permission denied\n",ior->input);
                                        	break;
                                        	}
		                                if((fd1 = open(ior->input,O_RDONLY))==-1){
                		                printf("dash: %s inpRedirect opening failed\n",ior->input);
                                	        break;
                               		        }
                                      		else {
							close(0);
					 		dup(fd1);
						}
					}
	
					if(ior->output != NULL)				
					{
						/*if((fd1= access(ior->output,W_OK))==-1){
                        	                printf("dash: %s permission denied",ior->output);
                                	        break;}*/
                                        	if((fd2=open(ior->output,O_WRONLY|O_TRUNC|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH ))==-1){
                                        	printf("dash: %s outRedirect opening failed\n",ior->output);
                                       		break;}
                                       		else{
							close(1);
							dup(fd2);
						}
					}
					if (setpgid(0,0) != 0)
       		         		perror("setpgid() error");

			                if (tcsetpgrp(0, getpid()) != 0)
                			perror("tcsetpgrp() error");
					
					execvp(args[0],args);
					err_ret("couldn't execute: %s", line);
					exit(127);
				}
				if(flag == TRUE && (*args[0] !='\0'))
				{
					jobid = assignJobId();
					myObj = createObject(pid,multiCmd[i],jobid,1); 
					node = createNode(myObj);
					addAtRear(lst,node);
				
					printf("[%d] %d %s &\n",((ObjectPtr)(node->obj))->jobId, ((ObjectPtr)(node->obj))->key, ((ObjectPtr)(node->obj))->data);
					
					if ( (pid = waitpid(pid, &status, WNOHANG)) < 0)
					err_sys("waitpid error");
					if((tcsetpgrp(0,tcpid))!=0)
					perror("tcsetgroup error");
				
				}
				else
				{
				
					if ( (pid = waitpid(pid, &status, 0|WUNTRACED)) < 0)
					err_sys("waitpid error");
					if((tcsetpgrp(0,tcpid))!=0)
					perror("tcsetgroup error");
					if(WIFSTOPPED(status))
					{
						jobid = assignJobId();
                				myObj = createObject(pid,line,jobid,2);
                				node = createNode(myObj);
                				addAtRear(lst,node);
                				printf("%s\n",(*toString)(node->obj));
					}
			
				}
			i++;
			}
			freeVar(line,str,args);
			memset(multiCmd,'\0',sizeof(multiCmd));
			i=0;
		}
		freeList(lst);
		exit(0);
	}
Пример #29
0
static ptid_t
obsd_wait (struct target_ops *ops,
	   ptid_t ptid, struct target_waitstatus *ourstatus, int options)
{
  pid_t pid;
  int status, save_errno;

  do
    {
      set_sigint_trap ();

      do
	{
	  pid = waitpid (ptid_get_pid (ptid), &status, 0);
	  save_errno = errno;
	}
      while (pid == -1 && errno == EINTR);

      clear_sigint_trap ();

      if (pid == -1)
	{
	  fprintf_unfiltered (gdb_stderr,
			      _("Child process unexpectedly missing: %s.\n"),
			      safe_strerror (save_errno));

	  /* Claim it exited with unknown signal.  */
	  ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
	  ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
	  return inferior_ptid;
	}

      /* Ignore terminated detached child processes.  */
      if (!WIFSTOPPED (status) && pid != ptid_get_pid (inferior_ptid))
	pid = -1;
    }
  while (pid == -1);

  ptid = pid_to_ptid (pid);

  if (WIFSTOPPED (status))
    {
      ptrace_state_t pe;
      pid_t fpid;

      if (ptrace (PT_GET_PROCESS_STATE, pid, (caddr_t)&pe, sizeof pe) == -1)
	perror_with_name (("ptrace"));

      switch (pe.pe_report_event)
	{
	case PTRACE_FORK:
	  ourstatus->kind = TARGET_WAITKIND_FORKED;
	  ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid);

	  /* Make sure the other end of the fork is stopped too.  */
	  fpid = waitpid (pe.pe_other_pid, &status, 0);
	  if (fpid == -1)
	    perror_with_name (("waitpid"));

	  if (ptrace (PT_GET_PROCESS_STATE, fpid,
		      (caddr_t)&pe, sizeof pe) == -1)
	    perror_with_name (("ptrace"));

	  gdb_assert (pe.pe_report_event == PTRACE_FORK);
	  gdb_assert (pe.pe_other_pid == pid);
	  if (fpid == ptid_get_pid (inferior_ptid))
	    {
	      ourstatus->value.related_pid = pid_to_ptid (pe.pe_other_pid);
	      return pid_to_ptid (fpid);
	    }

	  return pid_to_ptid (pid);
	}

      ptid = ptid_build (pid, pe.pe_tid, 0);
      if (!in_thread_list (ptid))
	{
	  if (ptid_get_lwp (inferior_ptid) == 0)
	    thread_change_ptid (inferior_ptid, ptid);
	  else
	    add_thread (ptid);
	}
    }

  store_waitstatus (ourstatus, status);
  return ptid;
}
Пример #30
0
void execute(const string& script)
{
  // Create a temporary directory for the test.
  Try<string> directory = environment->mkdtemp();

  CHECK_SOME(directory) << "Failed to create temporary directory";

  if (flags.verbose) {
    std::cerr << "Using temporary directory '"
              << directory.get() << "'" << std::endl;
  }

  // Determine the path for the script.
  Result<string> path = os::realpath(getTestScriptPath(script));

  if (!path.isSome()) {
    FAIL() << "Failed to locate script "
           << script << ": "
           << (path.isError() ? path.error() : "No such file or directory");
  }

  // Fork a process to change directory and run the test.
  pid_t pid;
  if ((pid = fork()) == -1) {
    FAIL() << "Failed to fork to launch script";
  }

  if (pid > 0) {
    // In parent process.
    int status;
    while (wait(&status) != pid || WIFSTOPPED(status));
    CHECK(WIFEXITED(status) || WIFSIGNALED(status));

    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
      FAIL() << script << " " << WSTRINGIFY(status);
    }
  } else {
    // In child process. DO NOT USE GLOG!

    // Start by cd'ing into the temporary directory.
    Try<Nothing> chdir = os::chdir(directory.get());
    if (chdir.isError()) {
      std::cerr << "Failed to chdir to '" << directory.get() << "': "
                << chdir.error() << std::endl;
      abort();
    }

    // Redirect output to /dev/null unless the test is verbose.
    if (!flags.verbose) {
      if (freopen("/dev/null", "w", stdout) == NULL ||
          freopen("/dev/null", "w", stderr) == NULL) {
        std::cerr << "Failed to redirect stdout/stderr to /dev/null:"
                  << os::strerror(errno) << std::endl;
        abort();
      }
    }

    // Set up the environment for executing the script. We might be running from
    // the Mesos source tree or from an installed version of the tests. In the
    // latter case, all of the variables below are swizzled to point to the
    // installed locations, except MESOS_SOURCE_DIR. Scripts that make use of
    // MESOS_SOURCE_DIR are expected to gracefully degrade if the Mesos source
    // is no longer present.
    os::setenv("MESOS_BUILD_DIR", flags.build_dir);
    os::setenv("MESOS_HELPER_DIR", getTestHelperDir());
    os::setenv("MESOS_LAUNCHER_DIR", getLauncherDir());
    os::setenv("MESOS_SBIN_DIR", getSbinDir());
    os::setenv("MESOS_SOURCE_DIR", flags.source_dir);
    os::setenv("MESOS_WEBUI_DIR", getWebUIDir());

    // Enable replicated log based registry.
    os::setenv("MESOS_REGISTRY", "replicated_log");

    // Enable authentication.
    os::setenv("MESOS_AUTHENTICATE", "true");

    // Create test credentials.
    const string& credentials =
      DEFAULT_CREDENTIAL.principal() + " " + DEFAULT_CREDENTIAL.secret();

    const string& credentialsPath =
      path::join(directory.get(), "credentials");

    CHECK_SOME(os::write(credentialsPath, credentials))
      << "Failed to write credentials to '" << credentialsPath << "'";

    os::setenv("MESOS_CREDENTIALS", "file://" + credentialsPath);

    // We set test credentials here for example frameworks to use.
    os::setenv("DEFAULT_PRINCIPAL", DEFAULT_CREDENTIAL.principal());
    os::setenv("DEFAULT_SECRET", DEFAULT_CREDENTIAL.secret());

    // TODO(bmahler): Update the example frameworks to use flags and
    // remove the special DEFAULT_* environment variables above.
    os::setenv("MESOS_PRINCIPAL", DEFAULT_CREDENTIAL.principal());
    os::setenv("MESOS_SECRET", DEFAULT_CREDENTIAL.secret());

    // Create test ACLs.
    ACLs acls;
    acls.set_permissive(false);

    mesos::ACL::RunTask* run = acls.add_run_tasks();
    run->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal());

    Result<string> user = os::user();
    CHECK_SOME(user) << "Failed to get current user name";
    run->mutable_users()->add_values(user.get());

    mesos::ACL::RegisterFramework* register_ = acls.add_register_frameworks();
    register_->mutable_principals()->add_values(DEFAULT_CREDENTIAL.principal());
    register_->mutable_roles()->add_values("*");

    const string& aclsPath = path::join(directory.get(), "acls");

    CHECK_SOME(os::write(aclsPath, stringify(JSON::protobuf(acls))))
      << "Failed to write ACLs to '" << aclsPath << "'";

    os::setenv("MESOS_ACLS", "file://" + aclsPath);

    // Now execute the script.
    execl(path.get().c_str(), path.get().c_str(), (char*) NULL);

    std::cerr << "Failed to execute '" << script << "': "
              << os::strerror(errno) << std::endl;
    abort();
  }
}