コード例 #1
0
ファイル: shell.c プロジェクト: Ras-al-Ghul/cshell
void execfg(char *cmdarr[MAXCMD][MAXOP],int i) {		//Brings the specified background process to the foreground
    if(cmdarr[i][1] == NULL) {
        printf("Takes one argument\n");
        return;
    }
    strcpy(fname,cmdarr[i][0]);
    int j,temppid = 0;

    int tempposn = atoi(cmdarr[i][1]);
    //int tempcnt = 0;
    for(j=0; j<(MAXNUM*MAXOP); j++) {
        if(jobsarray[j].count == tempposn && jobsarray[j].state == 1) {
            temppid = jobsarray[j].pid;
            break;
        }
    }

    if(temppid > 0) {
        for(j=0; j<(MAXNUM*MAXOP); j++) {
            if(jobsarray[j].pid == temppid && jobsarray[j].state == 1) {
                strcpy(fname,jobsarray[j].name);
                jobsarray[j].state = 0;
                fpid = temppid;



                int temppgid=getpgid(temppid);

                tcsetpgrp(shell_terminal,temppgid);

                killpg(temppgid,SIGCONT);

                int status;
                do {
                    int w = waitpid(temppid, &status, WUNTRACED | WCONTINUED);
                    if (w == -1) {

                        perror("waitpid");
                        exit(EXIT_FAILURE);
                    }

                    if (WIFEXITED(status)) {
                        printf("exited, status=%d\n", WEXITSTATUS(status));
                        break;
                    }
                    else if (WIFSIGNALED(status)) {
                        printf("killed by signal %d\n", WTERMSIG(status));
                        break;
                    }
                    else if (WIFSTOPPED(status)) {
                        printf("\nstopped by signal %d\n", WSTOPSIG(status));
                        if(WSTOPSIG(status) == 19 || WSTOPSIG(status) == 20) {
                            strcpy(jobsarray[jobsarraycnt].name,fname);
                            jobsarray[jobsarraycnt].pid = fpid;
                            jobsarray[jobsarraycnt].stopped = 1;
                            jobsarray[jobsarraycnt++].state = 1;
                        }
                        printf("\nstopped by signal %d\n", WSTOPSIG(status));
                        if(WSTOPSIG(status) == 22)
                            kill(fpid,SIGKILL);
                        break;
                    }
                    else if (WIFCONTINUED(status)) {
                        printf("continued\n");
                    }
                } while(!WIFEXITED(status) && !WIFSIGNALED(status));
                tcsetpgrp (shell_terminal, shell_pgid);

                return;
            }
        }
    }
    printf("No background job with given pid exists\n");
    return;
}
コード例 #2
0
ProgramWidget::ProgramWidget(Vector2n Position, TypingModule & TypingModule, Project & Project, TextFieldWidget * Target)
	: FlowLayoutWidget(Position, { std::shared_ptr<Widget>(m_SourceWidget = new ConnectionWidget<TextFieldWidget>(Vector2n::ZERO, Target)),
								   std::shared_ptr<Widget>(new LabelWidget(Vector2n::ZERO, std::string("go run"), LabelWidget::Background::Normal)),
								   std::shared_ptr<Widget>(m_OutputWidget = new TextFieldWidget(Vector2n::ZERO, TypingModule)) }, { std::shared_ptr<Behavior>(new DraggablePositionBehavior(*this)) }),
	  m_Project(Project)
{
	{
		m_SourceWidget->m_OnChange = [=, &Project]()
		{
			//PlayBeep();

			Project.m_ProcessEndedTime = glfwGetTime();
			Project.m_BackgroundState = 0;

			// Kill child processes
			if (0 != Project.m_LastPid)
			{
				//std::cout << "Sending kill to last child pid " << Project.m_LastPid << ".\n";
				//auto Result = kill(0, SIGTERM);
				auto Result = killpg(Project.m_LastPid, SIGKILL);
				//waitpid(m_LastPid, NULL, 0);

				if (0 != Result) {
					std::cerr << "Error: kill() failed with return " << Result << ", errno " << errno << ".\n";
					//throw 0;
				}
			}

			//std::cout << "Closing " << Project.m_PipeFd[0] << " and " << Project.m_PipeFd[1] << "; ";
			close(Project.m_PipeFd[0]);		// Close the read end of the pipe in the parent
			Project.m_PipeFd[0] = Project.m_PipeFd[1] = -1;

			if (!m_SourceWidget->m_LiveToggle->GetState())
			{
				//OutputWidget.m_Visible = false;
				return;
			}
			else
			{
				//OutputWidget.m_Visible = true;
			}

			std::string Content = "";
			if (nullptr != m_SourceWidget->Target()) {
				Content = m_SourceWidget->Target()->GetContent();
			}
			Project.GenerateProgram(Content);

			g_OutputWidget = m_OutputWidget;		// HACK
			//m_OutputWidget->SetContent("");
			Project.m_ProcessStartedTime = glfwGetTime();
			Project.m_ExpiredOutput = true;
			Project.m_BackgroundState = 1;
		};

		// If there's already a Target for source, then refresh ourselves
		m_SourceWidget->m_OnChange();
	}

	// TODO: Make this work in LiveProgramWidget too (currently the Cmd+R event doesn't go from LiveProgramWidget to this ProgramWidget)
	ModifyGestureRecognizer().AddShortcut(GestureRecognizer::ShortcutEntry('R', PointerState::Modifiers::Super, m_SourceWidget->m_OnChange, "Run/Refresh"));

	m_GetLineAnnotations = [this](uint32 LineNumber) -> std::string
	{
		//return std::to_string(LineNumber + 1) + "-" + (m_ProgramWidget->m_OutputWidget->GetContent().length() >= 3 ? m_ProgramWidget->m_OutputWidget->GetContent().substr(0, 3) : "...");

		// HACK: Using hardcoded color, make this better
		// Don't do this if the result is not compile error, or if Live Toggle is off
		if (   Color(1.0, 0.9, 0.9) != this->m_OutputWidget->GetBackground()
			|| false == this->m_SourceWidget->m_LiveToggle->GetState())
			return "";

		// TODO: Clean up
		{
			std::stringstream ss;
			auto Input = this->m_OutputWidget->GetContent();
			TrimLastNewline(Input);
			ss << Input;
			std::string Line;

			std::getline(ss, Line);		// Skip first line
			for (;;)
			{
				std::getline(ss, Line);

				// Parse one go error line
				try
				{
					auto FirstColon = Line.find(':');
					auto SecondColon = Line.find(':', FirstColon + 1);
					uint32 FoundLineNumber = std::stoi(Line.substr(FirstColon + 1, SecondColon - (FirstColon + 1)));

					if (FoundLineNumber == LineNumber + 1)
						return TrimFirstSpace(Line.substr(SecondColon + 1));
				}
				catch (...) {}

				if (ss.eof())
					break;
			}
		}
		return "";
	};
}
コード例 #3
0
ファイル: signal.c プロジェクト: SongJungHwan/hwan
VALUE
rb_f_kill(int argc, VALUE *argv)
{
#ifndef HAVE_KILLPG
#define killpg(pg, sig) kill(-(pg), (sig))
#endif
    int negative = 0;
    int sig;
    int i;
    volatile VALUE str;
    const char *s;

    rb_secure(2);
    rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);

    switch (TYPE(argv[0])) {
      case T_FIXNUM:
	sig = FIX2INT(argv[0]);
	break;

      case T_SYMBOL:
	s = rb_id2name(SYM2ID(argv[0]));
	if (!s) rb_raise(rb_eArgError, "bad signal");
	goto str_signal;

      case T_STRING:
	s = RSTRING_PTR(argv[0]);
      str_signal:
	if (s[0] == '-') {
	    negative++;
	    s++;
	}
	if (strncmp("SIG", s, 3) == 0)
	    s += 3;
	if ((sig = signm2signo(s)) == 0)
	    rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);

	if (negative)
	    sig = -sig;
	break;

      default:
	str = rb_check_string_type(argv[0]);
	if (!NIL_P(str)) {
	    s = RSTRING_PTR(str);
	    goto str_signal;
	}
	rb_raise(rb_eArgError, "bad signal type %s",
		 rb_obj_classname(argv[0]));
	break;
    }

    if (sig < 0) {
	sig = -sig;
	for (i=1; i<argc; i++) {
	    if (killpg(NUM2PIDT(argv[i]), sig) < 0)
		rb_sys_fail(0);
	}
    }
    else {
	for (i=1; i<argc; i++) {
	    if (kill(NUM2PIDT(argv[i]), sig) < 0)
		rb_sys_fail(0);
	}
    }
    return INT2FIX(i-1);
}
コード例 #4
0
ファイル: req.c プロジェクト: lipari/slurm
static int
_handle_signal_process_group(int fd, slurmd_job_t *job, uid_t uid)
{
	int rc = SLURM_SUCCESS;
	int signal;

	debug3("_handle_signal_process_group for job %u.%u",
	      job->jobid, job->stepid);

	safe_read(fd, &signal, sizeof(int));

	debug3("  uid = %d", uid);
	if (uid != job->uid && !_slurm_authorized_user(uid)) {
		debug("kill req from uid %ld for job %u.%u owned by uid %ld",
		      (long)uid, job->jobid, job->stepid, (long)job->uid);
		rc = EPERM;
		goto done;
	}

	/*
	 * Sanity checks
	 */
	if (job->pgid <= (pid_t)1) {
		debug ("step %u.%u invalid [jmgr_pid:%d pgid:%u]",
		       job->jobid, job->stepid, job->jmgr_pid, job->pgid);
		rc = ESLURMD_JOB_NOTRUNNING;
		goto done;
	}

	/*
	 * Signal the process group
	 */
	pthread_mutex_lock(&suspend_mutex);
	if (suspended && (signal != SIGKILL)) {
		rc = ESLURMD_STEP_SUSPENDED;
		pthread_mutex_unlock(&suspend_mutex);
		goto done;
	}

	/*
	 * Print a message in the step output before killing when
	 * SIGTERM or SIGKILL are sent
	 */
	if ((signal == SIGTERM) || (signal == SIGKILL)) {
		time_t now = time(NULL);
		char entity[24], time_str[24];
		if (job->stepid == SLURM_BATCH_SCRIPT) {
			snprintf(entity, sizeof(entity), "JOB %u", job->jobid);
		} else {
			snprintf(entity, sizeof(entity), "STEP %u.%u",
				 job->jobid, job->stepid);
		}
		slurm_make_time_str(&now, time_str, sizeof(time_str));

		error("*** %s KILLED AT %s WITH SIGNAL %u ***",
		      entity, time_str, signal);
	}

	if (killpg(job->pgid, signal) == -1) {
		rc = -1;
		verbose("Error sending signal %d to %u.%u, pgid %d: %m",
			signal, job->jobid, job->stepid, job->pgid);
	} else {
		verbose("Sent signal %d to %u.%u, pgid %d",
			signal, job->jobid, job->stepid, job->pgid);
	}
	pthread_mutex_unlock(&suspend_mutex);

done:
	/* Send the return code */
	safe_write(fd, &rc, sizeof(int));
	return SLURM_SUCCESS;
rwfail:
	return SLURM_FAILURE;
}
コード例 #5
0
ファイル: proc.cpp プロジェクト: JanKanis/fish-shell
void job_continue(job_t *j, int cont)
{
    /*
      Put job first in the job list
    */
    job_promote(j);
    job_set_flag(j, JOB_NOTIFIED, 0);

    CHECK_BLOCK();

    debug(4,
          L"Continue job %d, gid %d (%ls), %ls, %ls",
          j->job_id,
          j->pgid,
          j->command_wcstr(),
          job_is_completed(j)?L"COMPLETED":L"UNCOMPLETED",
          is_interactive?L"INTERACTIVE":L"NON-INTERACTIVE");

    if (!job_is_completed(j))
    {
        if (job_get_flag(j, JOB_TERMINAL) && job_get_flag(j, JOB_FOREGROUND))
        {
            /* Put the job into the foreground.  */
            int ok;

            signal_block();

            ok = terminal_give_to_job(j, cont);

            signal_unblock();

            if (!ok)
                return;

        }

        /*
           Send the job a continue signal, if necessary.
        */
        if (cont)
        {
            process_t *p;

            for (p=j->first_process; p; p=p->next)
                p->stopped=0;

            if (job_get_flag(j, JOB_CONTROL))
            {
                if (killpg(j->pgid, SIGCONT))
                {
                    wperror(L"killpg (SIGCONT)");
                    return;
                }
            }
            else
            {
                for (p=j->first_process; p; p=p->next)
                {
                    if (kill(p->pid, SIGCONT) < 0)
                    {
                        wperror(L"kill (SIGCONT)");
                        return;
                    }
                }
            }
        }

        if (job_get_flag(j, JOB_FOREGROUND))
        {
            int quit = 0;

            /*
               Wait for job to report. Looks a bit ugly because it has to
               handle the possibility that a signal is dispatched while
               running job_is_stopped().
            */
            while (!quit)
            {
                do
                {
                    got_signal = 0;
                    quit = job_is_stopped(j) || job_is_completed(j);
                }
                while (got_signal && !quit);

                if (!quit)
                {

//					debug( 1, L"select_try()" );
                    switch (select_try(j))
                    {
                        case 1:
                        {
                            read_try(j);
                            break;
                        }

                        case -1:
                        {
                            /*
                              If there is no funky IO magic, we can use
                              waitpid instead of handling child deaths
                              through signals. This gives a rather large
                              speed boost (A factor 3 startup time
                              improvement on my 300 MHz machine) on
                              short-lived jobs.
                            */
                            int status;
                            pid_t pid = waitpid(-1, &status, WUNTRACED);
                            if (pid > 0)
                            {
                                handle_child_status(pid, status);
                            }
                            else
                            {
                                /*
                                  This probably means we got a
                                  signal. A signal might mean that the
                                  terminal emulator sent us a hup
                                  signal to tell is to close. If so,
                                  we should exit.
                                */
                                if (reader_exit_forced())
                                {
                                    quit = 1;
                                }

                            }
                            break;
                        }

                    }
                }
            }
        }
    }

    if (job_get_flag(j, JOB_FOREGROUND))
    {

        if (job_is_completed(j))
        {

            // It's possible that the job will produce output and exit before we've even read from it.
            // We'll eventually read the output, but it may be after we've executed subsequent calls
            // This is why my prompt colors kept getting screwed up - the builtin echo calls
            // were sometimes having their output combined with the set_color calls in the wrong order!
            read_try(j);


            process_t *p = j->first_process;
            while (p->next)
                p = p->next;

            if (WIFEXITED(p->status) || WIFSIGNALED(p->status))
            {
                /*
                   Mark process status only if we are in the foreground
                   and the last process in a pipe, and it is not a short circuted builtin
                */
                if (p->pid)
                {
                    int status = proc_format_status(p->status);
                    //wprintf(L"setting status %d for %ls\n", job_get_flag( j, JOB_NEGATE )?!status:status, j->command);
                    proc_set_last_status(job_get_flag(j, JOB_NEGATE)?!status:status);
                }
            }
        }
        /*
           Put the shell back in the foreground.
        */
        if (job_get_flag(j, JOB_TERMINAL) && job_get_flag(j, JOB_FOREGROUND))
        {
            int ok;

            signal_block();

            ok = terminal_return_from_job(j);

            signal_unblock();

            if (!ok)
                return;

        }
    }

}
コード例 #6
0
ファイル: userfn.c プロジェクト: penicolas/Practicas_ITIS_UMU
/*---------------------------------------------------------------------------*/
void matar_procesos_propios()
{
   killpg(getpgrp(),SIGINT);
   killpg(getpgrp(),SIGQUIT);
   killpg(getpgrp(),SIGKILL);
}
コード例 #7
0
ファイル: limit.c プロジェクト: seplogic/jstar
/*
 * Exit codes:
 *  0 - everything went OK (might be CPU, MEM, or FILE limit exceeded!)
 *  1 - I was not invoked correctly
 *  2 - I can't fork
 *  3 - I can't execute
 *  4 - wall time expired, I had to abort
 */
int main(int argc, char* argv[]) {
    int i;
    int child;
    int status;
    int tle;
    struct rlimit cpu, mem, file, fcnt;
    int wall;
    struct timeval start_time, current_time;
    char* cmd;
    int sec, usec; // elapsed wall time

    /* defaults */
    wall = 180;               // 3 minutes
    cpu.rlim_cur = 60;        // 1 minute
    mem.rlim_cur = 512;       // half a giga
    file.rlim_cur = 1 << 14;  // 16 MB
    fcnt.rlim_cur = fcnt.rlim_max = 128; // no need for more open files

    /* parse arguments */
    if (!(argc&1)) usage();
    cmd = NULL;
    for (i = 1; i + 1 < argc; i += 2) {
        if (!strcmp("-m", argv[i])) sscanf(argv[i+1], "%d", &mem.rlim_cur);
        else if (!strcmp("-c", argv[i])) sscanf(argv[i+1], "%d", &cpu.rlim_cur);
        else if (!strcmp("-w", argv[i])) sscanf(argv[i+1], "%d", &wall);
        else if (!strcmp("-f", argv[i])) sscanf(argv[i+1], "%d", &file.rlim_cur);
        else if (!strcmp("-x", argv[i])) cmd = argv[i+1];
        else usage();
    }
    if (cmd == NULL) usage();
    if (wall > cpu.rlim_cur) wall = cpu.rlim_cur;
    mem.rlim_cur <<= 20;  // MB
    file.rlim_cur <<= 10; // KB
    cpu.rlim_max = cpu.rlim_cur;
    mem.rlim_max = mem.rlim_cur;
    file.rlim_max = file.rlim_cur;

    /* set limits */
    setrlimit(RLIMIT_CPU, &cpu);
    setrlimit(RLIMIT_AS, &mem);
    setrlimit(RLIMIT_FSIZE, &file);
    setrlimit(RLIMIT_NOFILE, &fcnt);

    /* start the child */
    child = fork();
    if (child == -1) {
        fprintf(stderr, "can't fork.");
        return 2;
    }
    if (child == 0) {
        setsid();
        execl("/bin/sh", "sh", "-c", cmd, (char*)0);
        perror("Can't execute");
        return 3;
    }

    /* watch out for wall time limit */
    gettimeofday(&start_time, NULL);
    while (!waitpid(child, &status, WNOHANG)) {
        usleep(25000);
        gettimeofday(&current_time, NULL);
        sec = current_time.tv_sec - start_time.tv_sec;
        usec = current_time.tv_usec - start_time.tv_usec;
        if (sec > wall || (sec == wall && usec > 0)) {
            fprintf(stderr, "Hanged\n");
            if (killpg(child, SIGKILL))
                fprintf(stderr, "Failed to kill");
        }
        usleep(50000);
    }
    if (WIFSIGNALED(status)) return 4;
    return 0;
}
コード例 #8
0
ファイル: calendar.c プロジェクト: SylvestreG/bitrig
int
main(int argc, char *argv[])
{
	int ch;
	char *caldir;

	(void)setlocale(LC_ALL, "");

	while ((ch = getopt(argc, argv, "abf:t:A:B:-")) != -1)
		switch (ch) {
		case '-':		/* backward contemptible */
		case 'a':
			if (getuid())
				errx(1, "%s", strerror(EPERM));
			doall = 1;
			break;

		case 'b':
			bodun_always++;
			break;

		case 'f': /* other calendar file */
		        calendarFile = optarg;
			break;

		case 't': /* other date, undocumented, for tests */
			if ((f_time = Mktime(optarg)) <= 0)
				errx(1, "specified date is outside allowed range");
			break;

		case 'A': /* days after current date */
			f_dayAfter = atoi(optarg);
			f_SetdayAfter = 1;
			break;

		case 'B': /* days before current date */
			f_dayBefore = atoi(optarg);
			break;

		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc)
		usage();

	/* use current time */
	if (f_time <= 0)
	    (void)time(&f_time);

	if (f_dayBefore) {
		/* Move back in time and only look forwards */
		f_dayAfter += f_dayBefore;
		f_time -= SECSPERDAY * f_dayBefore;
		f_dayBefore = 0;
	}
	settime(&f_time);

	if (doall) {
		pid_t kid, deadkid;
		int kidstat, kidreaped, runningkids;
		int acstat;
		struct stat sbuf;
		time_t t;
		unsigned int sleeptime;

		signal(SIGCHLD, childsig);
		runningkids = 0;
		t = time(NULL);
		while ((pw = getpwent()) != NULL) {
			acstat = 0;
			/* Avoid unnecessary forks.  The calendar file is only
			 * opened as the user later; if it can't be opened,
			 * it's no big deal.  Also, get to correct directory.
			 * Note that in an NFS environment root may get EACCES
			 * on a chdir(), in which case we have to fork.  As long as
			 * we can chdir() we can stat(), unless the user is
			 * modifying permissions while this is running.
			 */
			if (chdir(pw->pw_dir)) {
				if (errno == EACCES)
					acstat = 1;
				else
					continue;
			}
			if (stat(calendarFile, &sbuf) != 0) {
				if (chdir(calendarHome)) {
					if (errno == EACCES)
						acstat = 1;
					else
						continue;
				}
				if (stat(calendarNoMail, &sbuf) == 0 ||
				    stat(calendarFile, &sbuf) != 0)
					continue;
			}
			sleeptime = USERTIMEOUT;
			switch ((kid = fork())) {
			case -1:	/* error */
				warn("fork");
				continue;
			case 0:	/* child */
				(void)setpgid(getpid(), getpid());
				(void)setlocale(LC_ALL, "");
				if (setusercontext(NULL, pw, pw->pw_uid,
				    LOGIN_SETALL ^ LOGIN_SETLOGIN))
					err(1, "unable to set user context (uid %u)",
					    pw->pw_uid);
				if (acstat) {
					if (chdir(pw->pw_dir) ||
					    stat(calendarFile, &sbuf) != 0 ||
					    chdir(calendarHome) || 
					    stat(calendarNoMail, &sbuf) == 0 ||
					    stat(calendarFile, &sbuf) != 0)
						exit(0);
				}
				cal();
				exit(0);
			}
			/* parent: wait a reasonable time, then kill child if
			 * necessary.
			 */
			runningkids++;
			kidreaped = 0;
			do {
				sleeptime = sleep(sleeptime);
				/* Note that there is the possibility, if the sleep
				 * stops early due to some other signal, of the child
				 * terminating and not getting detected during the next
				 * sleep.  In that unlikely worst case, we just sleep
				 * too long for that user.
				 */
				for (;;) {
					deadkid = waitpid(-1, &kidstat, WNOHANG);
					if (deadkid <= 0)
						break;
					runningkids--;
					if (deadkid == kid) {
						kidreaped = 1;
						sleeptime = 0;
					}
				}
			} while (sleeptime);

			if (!kidreaped) {
				/* It doesn't _really_ matter if the kill fails, e.g.
				 * if there's only a zombie now.
				 */
				if (getpgid(kid) != getpgrp())
					(void)killpg(getpgid(kid), SIGTERM);
				else
					(void)kill(kid, SIGTERM);
				warnx("uid %u did not finish in time", pw->pw_uid);
			}
			if (time(NULL) - t >= SECSPERDAY)
				errx(2, "'calendar -a' took more than a day; "
				    "stopped at uid %u",
				    pw->pw_uid);
		}
		for (;;) {
			deadkid = waitpid(-1, &kidstat, WNOHANG);
			if (deadkid <= 0)
				break;
			runningkids--;
		}
		if (runningkids)
			warnx("%d child processes still running when "
			    "'calendar -a' finished", runningkids);
	} else if ((caldir = getenv("CALENDAR_DIR")) != NULL) {
		if(!chdir(caldir))
			cal();
	} else
		cal();

	exit(0);
}
コード例 #9
0
ファイル: power_common.c プロジェクト: A1ve5/slurm
/* Execute a script, wait for termination and return its stdout.
 * script_name IN - Name of program being run (e.g. "StartStageIn")
 * script_path IN - Fully qualified program of the program to execute
 * script_args IN - Arguments to the script
 * max_wait IN - Maximum time to wait in milliseconds,
 *		 -1 for no limit (asynchronous)
 * data_in IN - data to use as program STDIN (NULL if not STDIN)
 * status OUT - Job exit code
 * Return stdout+stderr of spawned program, value must be xfreed. */
extern char *power_run_script(char *script_name, char *script_path,
			      char **script_argv, int max_wait, char *data_in,
			      int *status)
{
	int i, new_wait, resp_size = 0, resp_offset = 0;
	int send_size = 0, send_offset = 0;
	pid_t cpid;
	char *resp = NULL;
	int fd_stdout[2] = { -1, -1 };
	int fd_stdin[2] = { -1, -1 };

	if ((script_path == NULL) || (script_path[0] == '\0')) {
		error("%s: no script specified", __func__);
		*status = 127;
		resp = xstrdup("Slurm burst buffer configuration error");
		return resp;
	}
	if (slurm_get_debug_flags() & DEBUG_FLAG_POWER) {
		for (i = 0; i < 10; i++) {
			if (!script_argv[i])
				break;
		}
		if (i == 0) {
			info("%s:", __func__);
		} else if (i == 1) {
			info("%s: %s", __func__, script_name);
		} else if (i == 2) {
			info("%s: %s %s", __func__, script_name,
			     script_argv[1]);
		} else if (i == 3) {
			info("%s: %s %s %s", __func__, script_name,
			     script_argv[1], script_argv[2]);
		} else if (i == 4) {
			info("%s: %s %s %s %s", __func__, script_name,
			     script_argv[1], script_argv[2], script_argv[3]);
		} else if (i == 5) {
			info("%s: %s %s %s %s %s", __func__, script_name,
			     script_argv[1], script_argv[2], script_argv[3],
			     script_argv[4]);
		} else if (i == 6) {
			info("%s: %s %s %s %s %s %s", __func__, script_name,
			     script_argv[1], script_argv[2], script_argv[3],
			     script_argv[4], script_argv[5]);
		} else if (i == 7) {
			info("%s: %s %s %s %s %s %s %s", __func__,
			     script_name, script_argv[1], script_argv[2],
			     script_argv[3], script_argv[4], script_argv[5],
			     script_argv[6]);
		} else {	/* 8 or more args here, truncate as needed */
			info("%s: %s %s %s %s %s %s %s %s", __func__,
			     script_name, script_argv[1], script_argv[2],
			     script_argv[3], script_argv[4], script_argv[5],
			     script_argv[6], script_argv[7]);
		}
		if (data_in)
			info("%s: %s", __func__, data_in);
	}
	if (script_path[0] != '/') {
		error("%s: %s is not fully qualified pathname (%s)",
		      __func__, script_name, script_path);
		*status = 127;
		resp = xstrdup("Slurm burst buffer configuration error");
		return resp;
	}
	if (access(script_path, R_OK | X_OK) < 0) {
		error("%s: %s can not be executed (%s) %m",
		      __func__, script_name, script_path);
		*status = 127;
		resp = xstrdup("Slurm burst buffer configuration error");
		return resp;
	}
	if (data_in) {
		if (pipe(fd_stdin) != 0) {
			error("%s: pipe(): %m", __func__);
			*status = 127;
			resp = xstrdup("System error");
			return resp;
		}
	}
	if (max_wait != -1) {
		if (pipe(fd_stdout) != 0) {
			error("%s: pipe(): %m", __func__);
			*status = 127;
			resp = xstrdup("System error");
			return resp;
		}
	}
	if ((cpid = fork()) == 0) {
		int cc;

		cc = sysconf(_SC_OPEN_MAX);
		if (data_in)
			dup2(fd_stdin[0], STDIN_FILENO);
		if (max_wait != -1) {
			dup2(fd_stdout[1], STDERR_FILENO);
			dup2(fd_stdout[1], STDOUT_FILENO);
			for (i = 0; i < cc; i++) {
				if ((i != STDERR_FILENO) &&
				    (i != STDIN_FILENO)  &&
				    (i != STDOUT_FILENO))
					close(i);
			}
		} else {
			for (i = 0; i < cc; i++) {
				if (!data_in || (i != STDERR_FILENO))
					close(i);
			}
			if ((cpid = fork()) < 0)
				exit(127);
			else if (cpid > 0)
				exit(0);
		}
		setpgid(0, 0);
		execv(script_path, script_argv);
		error("%s: execv(%s): %m", __func__, script_path);
		exit(127);
	} else if (cpid < 0) {
		if (data_in) {
			close(fd_stdin[0]);
			close(fd_stdin[1]);
		}
		if (max_wait != -1) {
			close(fd_stdout[0]);
			close(fd_stdout[1]);
		}
		error("%s: fork(): %m", __func__);
	} else if (max_wait != -1) {
		struct pollfd fds;
		time_t start_time = time(NULL);
		if (data_in) {
			close(fd_stdin[0]);
			send_size = strlen(data_in);
			while (send_size > send_offset) {
				i = write(fd_stdin[1], data_in + send_offset,
					 send_size - send_offset);
				if (i == 0) {
					break;
				} else if (i < 0) {
					if (errno == EAGAIN)
						continue;
					error("%s: write(%s): %m", __func__,
					      script_path);
					break;
				} else {
					send_offset += i;
				}
			}
			close(fd_stdin[1]);
		}
		resp_size = 1024;
		resp = xmalloc(resp_size);
		close(fd_stdout[1]);
		while (1) {
			fds.fd = fd_stdout[0];
			fds.events = POLLIN | POLLHUP | POLLRDHUP;
			fds.revents = 0;
			if (max_wait <= 0) {
				new_wait = -1;
			} else {
				new_wait = (time(NULL) - start_time) * 1000
					   + max_wait;
				if (new_wait <= 0)
					break;
			}
			i = poll(&fds, 1, new_wait);
			if (i == 0) {
				error("%s: %s poll timeout",
				      __func__, script_name);
				break;
			} else if (i < 0) {
				error("%s: %s poll:%m", __func__, script_name);
				break;
			}
			if ((fds.revents & POLLIN) == 0)
				break;
			i = read(fd_stdout[0], resp + resp_offset,
				 resp_size - resp_offset);
			if (i == 0) {
				break;
			} else if (i < 0) {
				if (errno == EAGAIN)
					continue;
				error("%s: read(%s): %m", __func__,
				      script_path);
				break;
			} else {
				resp_offset += i;
				if (resp_offset + 1024 >= resp_size) {
					resp_size *= 2;
					resp = xrealloc(resp, resp_size);
				}
			}
		}
		killpg(cpid, SIGKILL);
		waitpid(cpid, status, 0);
		close(fd_stdout[0]);
	} else {
		waitpid(cpid, status, 0);
	}
	return resp;
}
コード例 #10
0
ファイル: Execution.cpp プロジェクト: captn3m0/CodeRunner
void signalHandler(int signum){
	if(cpid!=0){
		killpg(cpid,SIGKILL);
	}
}
コード例 #11
0
ファイル: signal.c プロジェクト: RWB01/Code-Translator
VALUE
rb_f_kill(int argc, VALUE *argv)
{
    int negative = 0;
    int sig;
    int i;
    const char *s;

    rb_secure(2);
    if (argc < 2)
	rb_raise(rb_eArgError, "wrong number of arguments -- kill(sig, pid...)");
    switch (TYPE(argv[0])) {
      case T_FIXNUM:
	sig = FIX2INT(argv[0]);
	break;

      case T_SYMBOL:
	s = rb_id2name(SYM2ID(argv[0]));
	if (!s) rb_raise(rb_eArgError, "bad signal");
	goto str_signal;

      case T_STRING:
	s = RSTRING_PTR(argv[0]);
	if (s[0] == '-') {
	    negative++;
	    s++;
	}
      str_signal:
	if (strncmp("SIG", s, 3) == 0)
	    s += 3;
	if((sig = signm2signo(s)) == 0)
	    rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);

	if (negative)
	    sig = -sig;
	break;

      default:
        {
	    VALUE str;

	    str = rb_check_string_type(argv[0]);
	    if (!NIL_P(str)) {
		s = RSTRING_PTR(str);
		goto str_signal;
	    }
	    rb_raise(rb_eArgError, "bad signal type %s",
		     rb_obj_classname(argv[0]));
	}
	break;
    }

    if (sig < 0) {
	sig = -sig;
	for (i=1; i<argc; i++) {
	    int pid = NUM2INT(argv[i]);
#ifdef HAS_KILLPG
	    if (killpg(pid, sig) < 0)
#else
	    if (kill(-pid, sig) < 0)
#endif
		rb_sys_fail(0);
	}
    }
    else {
	for (i=1; i<argc; i++) {
	    Check_Type(argv[i], T_FIXNUM);
	    if (kill(FIX2INT(argv[i]), sig) < 0)
		rb_sys_fail(0);
	}
    }
    return INT2FIX(i-1);
}
コード例 #12
0
ファイル: simu.c プロジェクト: 12019/smews
void cleanup(int signo) {
	/* Kill all Smews processes AND the simulator. No need to free any malloc... */
	if(signo > 0 && signo <= 16)
		fprintf(stderr,"Signal received: %d (SIG%s)\n",signo,sigNames[signo-1]);
	killpg(0, SIGKILL);
}
コード例 #13
0
ファイル: rktio_process.c プロジェクト: cderici/racket
static int do_subprocess_kill(rktio_t *rktio, rktio_process_t *sp, int as_kill)
{
#if defined(RKTIO_SYSTEM_UNIX)
# if defined(CENTRALIZED_SIGCHILD)
  {
    int status;

    if (sp->done)
      return 1;

    centralized_wait_suspend();

    /* Don't allow group checking, because we don't want to wait
       on a group if we haven't already: */
    if (centralized_get_child_status(sp->pid, 0, 0, &status)) {
      sp->status = status;
      sp->done = 1;
      centralized_wait_resume();
      centralized_ended_child();
      return 1;
    }
  }
# else
  {
    System_Child *sc = (System_Child *)sp->handle;

    /* Don't pass sp->pid, because we don't want to wait
       on a group if we haven't already: */
    check_child_done(rktio, 0);
    if (sc->done)
      return 1;
  }
# define centralized_wait_resume() /* empty */
# endif

  while (1) {

    if (sp->is_group) {
      if (!killpg(sp->pid, as_kill ? SIGKILL : SIGINT)) {
        centralized_wait_resume();
        return 1;
      }
    } else {
      if (!kill(sp->pid, as_kill ? SIGKILL : SIGINT)) {
        centralized_wait_resume();
        return 1;
      }
    }
    
    if (errno != EINTR)
      break;
    /* Otherwise we were interrupted. Try `kill' again. */
  }

  get_posix_error();

  centralized_wait_resume();

  return 0;
#endif
#if defined(RKTIO_SYSTEM_WINDOWS)  
  if (as_kill || sp->is_group) {
    DWORD w;

    if (!sp->handle)
      return 1;

    if (!as_kill) {
      /* must be for a group; we don't care whether the
         original process is still running */
      if (GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, sp->pid))
        return 1;
    } else if (GetExitCodeProcess((HANDLE)sp->handle, &w)) {
      collect_process_time(rktio, w, sp);
      if (w != STILL_ACTIVE)
        return 1;
      if (TerminateProcess((HANDLE)sp->handle, 1))
        return 1;
    }
    get_windows_error();

    return 0;
  } else
    return 1;
#endif
}
コード例 #14
0
ファイル: shell.c プロジェクト: Ras-al-Ghul/cshell
int pipesexecute(char *cmdarr[MAXCMD][MAXOP],char *pipecmdarr[MAXCMD][MAXCMD][MAXOP],int *numofpipes,int ii) {		//Execute piped commands

    int dupstdin = dup(0);
    int dupstdout = dup(1);



    int i,j=numofpipes[ii],k,pipes[2*numofpipes[ii]],pgid,comc = 0;

    for(i=0; j--; i+=2) {
        if((pipe(pipes+i))<0)						//open the pipes
        {
            perror("pipe error");
            return -1;
        }
    }

    j=0;
    k=0;
    while(j < (numofpipes[ii]+1)) {

        strcpy(infile,"\0");
        strcpy(outfile,"\0");

        k = 0;
        while(pipecmdarr[ii][j][k] != NULL) {
            if(strcmp(pipecmdarr[ii][j][k],"<") == 0) {
                if(fopen(pipecmdarr[ii][j][k+1],"r") == NULL) {
                    printf("No such file exists\n");
                    return -1;
                }
                strcpy(infile,pipecmdarr[ii][j][k+1]);
                int kk;
                for(kk=k; kk<(MAXOP-2); kk++) {
                    pipecmdarr[ii][j][kk] = pipecmdarr[ii][j][kk+2];
                }
                break;
            }
            k++;
        }




        k=0;
        int outretval = 0;
        while(pipecmdarr[ii][j][k] != NULL) {

            if(strcmp(pipecmdarr[ii][j][k],">") == 0) {
                if(pipecmdarr[ii][j][k+1] != NULL) {
                    strcpy(outfile,pipecmdarr[ii][j][k+1]);
                    outretval = 1;
                    int kk;
                    for(kk=k; kk<(MAXOP-2); kk++) {
                        pipecmdarr[ii][j][kk] = pipecmdarr[ii][j][kk+2];
                    }
                    break;
                }
                else {
                    printf("Unexpected error near > token\n");
                    strcpy(outfile,"\0");
                    return -1;
                }

            }
            if(strcmp(pipecmdarr[ii][j][k],">>") == 0) {
                if(pipecmdarr[ii][j][k+1] != NULL) {
                    strcpy(outfile,pipecmdarr[ii][j][k+1]);
                    outretval = 0;
                    int kk;
                    for(kk=k; kk<(MAXOP-2); kk++) {
                        pipecmdarr[ii][j][kk] = pipecmdarr[ii][j][kk+2];
                    }
                    break;
                }
                else {
                    printf("Unexpected error near > token\n");
                    strcpy(outfile,"\0");
                    return -1;
                }

            }
            k++;
        }

        int pid = fork(),in,out;

        if(pid > 0) { //Parent
            if(comc == 0)
                pgid=pid;
            if(pid != 0)
                setpgid(pid,pgid);
        }
        else if(pid==0) {
            /*set the signal of child to default*/
            signal (SIGINT, SIG_DFL);
            signal (SIGQUIT, SIG_DFL);
            signal (SIGTSTP, SIG_DFL);
            signal (SIGTTIN, SIG_DFL);
            signal (SIGTTOU, SIG_DFL);
            signal (SIGCHLD, SIG_DFL);

            if(strcmp(outfile,"\0") != 0 && pipecmdarr[ii][j+1][0] == NULL) {					//if there is an outfile
                if(outretval == 1) {
                    out=open(outfile,O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR);
                    dup2(out,1);
                    close(out);
                }
                else {
                    if(fopen(outfile,"r") == NULL) {
                        out=open(outfile,O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR);
                        dup2(out,1);
                        close(out);
                    }
                    else {
                        out=open(outfile,O_WRONLY | O_APPEND, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR);
                        dup2(out,1);
                        close(out);
                    }
                }

            }
            else if(pipecmdarr[ii][j+1][0] != NULL) {				//if not the last command
                if((dup2(pipes[2*comc+1],1))<0) {
                    perror("dup2 error");
                }
            }
            else {
                if((dup2(dupstdout,1))<0) {
                    perror("dup2 error");
                }
            }

            if(strcmp(infile,"\0") != 0 && comc == 0) {					//if there is an infile
                in=open(infile,O_RDONLY);
                dup2(in,0);
                close(in);
            }
            else if(comc!=0) {					//if not the first command
                if((dup2(pipes[2*(comc-1)],0))<0) {
                    perror("dup2 error");
                }
            }
            else {
                if((dup2(dupstdin,0))<0) {
                    perror("dup2 error");
                }
            }

            //close all pipes in the children
            for(i=0; i<2*(numofpipes[ii]); i++)				//close all pipes in the children
                close(pipes[i]);

            if((execvp(pipecmdarr[ii][j][0],pipecmdarr[ii][j]))<0) {
                perror("Cannot execute");
                _exit(-1);
            }



        }
        else if(pid<0) {
            perror("Could not fork child");
            return -1;
        }
        if(pipecmdarr[ii][j][0] != NULL)
            comc++;

        j++;
    }

    int status;
    for(i=0; i<2*(numofpipes[ii]); i++)
    {
        close(pipes[i]);							//close all pipes in parent
    }


    tcsetpgrp(shell_terminal,pgid);						//set the terminal control to child
    for(i=0; i<(numofpipes[ii]+1); i++) {
        waitpid(-pgid,&status,WUNTRACED);			//Wait for all processes in the pipe
        if(WIFSTOPPED(status))
            killpg(pgid,SIGSTOP);
    }
    tcsetpgrp(shell_terminal,shell_pgid);					//return control to parent


    return 0;
}
コード例 #15
0
ファイル: worker.c プロジェクト: tooooots/mod_gearman
/* stop all children */
void stop_children(int mode) {
    int status, chld;
    int waited = 0;
    int x, curpid;

    gm_log( GM_LOG_TRACE, "stop_children(%d)\n", mode);

    /* ignore some signals for now */
    signal(SIGTERM, SIG_IGN);
    signal(SIGINT,  SIG_IGN);

    /*
     * send term signal to our children
     * children will finish the current job and exit
     */
    killpg(0, SIGTERM);
    while(current_number_of_workers > 0) {
        gm_log( GM_LOG_TRACE, "send SIGTERM\n");
        for(x=3; x < mod_gm_opt->max_worker+4; x++) {
            curpid = shm[x];
            if(curpid < 0) { curpid = -curpid; }
            if( curpid != 0 ) {
                kill(curpid, SIGTERM);
            }
        }
        while((chld = waitpid(-1, &status, WNOHANG)) != -1 && chld > 0) {
            gm_log( GM_LOG_TRACE, "wait() %d exited with %d\n", chld, status);
        }
        sleep(1);
        waited++;
        if(waited > GM_CHILD_SHUTDOWN_TIMEOUT) {
            break;
        }
        count_current_worker(GM_DISABLED);
        if(current_number_of_workers == 0)
            return;
        gm_log( GM_LOG_TRACE, "still waiting (%d) %d children missing...\n", waited, current_number_of_workers);
    }

    if(mode == GM_WORKER_STOP) {
        killpg(0, SIGINT);
        count_current_worker(GM_DISABLED);
        if(current_number_of_workers == 0)
            return;

        gm_log( GM_LOG_TRACE, "sending SIGINT...\n");
        for(x=3; x < mod_gm_opt->max_worker+4; x++) {
            curpid = shm[x];
            if(curpid < 0) { curpid = -curpid; }
            if( curpid != 0 ) {
                kill(curpid, SIGINT);
            }
        }

        while((chld = waitpid(-1, &status, WNOHANG)) != -1 && chld > 0) {
            gm_log( GM_LOG_TRACE, "wait() %d exited with %d\n", chld, status);
        }

        /* kill them the hard way */
        count_current_worker(GM_DISABLED);
        if(current_number_of_workers == 0)
            return;
        for(x=3; x < mod_gm_opt->max_worker+4; x++) {
            if( shm[x] != 0 ) {
                curpid = shm[x];
                if(curpid < 0) { curpid = -curpid; }
                if( curpid != 0 ) {
                    kill(curpid, SIGKILL);
                }
            }
        }

        /* count children a last time */
        count_current_worker(GM_DISABLED);
        if(current_number_of_workers == 0)
            return;

        /* this will kill us too */
        gm_log( GM_LOG_ERROR, "exiting by SIGKILL...\n");
        killpg(0, SIGKILL);
    }

    /* restore signal handlers for a clean exit */
    signal(SIGINT, clean_exit);
    signal(SIGTERM,clean_exit);
}
コード例 #16
0
static int _call_external_program(stepd_step_rec_t *job)
{
	int status, rc, opt;
	pid_t cpid;
	int max_wait = 300; /* seconds */
	int time_remaining;

	if ((job->state != SLURMSTEPD_STEP_RUNNING) ||
	    program_name == NULL || program_name[0] == '\0')
		return 0;

	debug("step_terminate_monitor: unkillable after %d sec, calling: %s",
	     timeout, program_name);

	if (access(program_name, R_OK | X_OK) < 0) {
		debug("step_terminate_monitor not running %s: %m",
		      program_name);
		return 0;
	}

	if ((cpid = fork()) < 0) {
		error("step_terminate_monitor executing %s: fork: %m",
		      program_name);
		return -1;
	}
	if (cpid == 0) {
		/* child */
		char *argv[2];
		char buf[16];

		/* container_g_add_pid needs to be called in the
		   forked process part of the fork to avoid a race
		   condition where if this process makes a file or
		   detacts itself from a child before we add the pid
		   to the container in the parent of the fork.
		*/
		if (container_g_add_pid(recorded_jobid, getpid(), getuid())
		    != SLURM_SUCCESS)
			error("container_g_add_pid(%u): %m", recorded_jobid);

		snprintf(buf, 16, "%u", recorded_jobid);
		setenv("SLURM_JOBID", buf, 1);
		setenv("SLURM_JOB_ID", buf, 1);
		snprintf(buf, 16, "%u", recorded_stepid);
		setenv("SLURM_STEPID", buf, 1);
		setenv("SLURM_STEP_ID", buf, 1);

		argv[0] = program_name;
		argv[1] = NULL;

		setpgid(0, 0);
		execv(program_name, argv);
		error("step_terminate_monitor execv(): %m");
		exit(127);
	}

	opt = WNOHANG;
	time_remaining = max_wait;
	while (1) {
		rc = waitpid(cpid, &status, opt);
		if (rc < 0) {
			if (errno == EINTR)
				continue;
			/* waitpid may very well fail under normal conditions
			   because the wait3() in mgr.c:_wait_for_any_task()
			   may have reaped the return code. */
			return 0;
		} else if (rc == 0) {
			sleep(1);
			if ((--time_remaining) == 0) {
				error("step_terminate_monitor: %s still running"
				      " after %d seconds.  Killing.",
				      program_name, max_wait);
				killpg(cpid, SIGKILL);
				opt = 0;
			}
		} else  {
			return status;
		}
	}

	/* NOTREACHED */
}
コード例 #17
0
ファイル: select_cray.c プロジェクト: jsollom/slurm
static int _run_nhc(uint64_t id, char *nodelist, bool step)
{
#ifdef HAVE_NATIVE_CRAY
	int argc = 5, status = 1, wait_rc;
	char *argv[argc];
	pid_t cpid;
	DEF_TIMERS;

	START_TIMER;
	argv[0] = "/opt/cray/nodehealth/default/bin/xtcleanup_after";
	if (step)
		argv[1] = "-a";
	else
		argv[1] = "-r";
	argv[2] = xstrdup_printf("%"PRIu64"", id);
	argv[3] = cray_nodelist2nids(NULL, nodelist);
	argv[4] = NULL;

	if (debug_flags & DEBUG_FLAG_SELECT_TYPE)
		info("Calling NHC for id %"PRIu64" on nodes %s(%s)",
		     id, nodelist, argv[3]);

	if ((cpid = fork()) < 0) {
		error("_run_nhc fork error: %m");
		goto fini;
	}
	if (cpid == 0) {
#ifdef SETPGRP_TWO_ARGS
		setpgrp(0, 0);
#else
		setpgrp();
#endif
		execvp(argv[0], argv);
		exit(127);
	}

	while (1) {
		wait_rc = waitpid(cpid, &status, 0);
		if (wait_rc < 0) {
			if (errno == EINTR)
				continue;
			error("_run_nhc waitpid error: %m");
			break;
		} else if (wait_rc > 0) {
			killpg(cpid, SIGKILL);	/* kill children too */
			break;
		}
	}
	END_TIMER;
	if (status != 0) {
		error("_run_nhc %s %"PRIu64" exit status %u:%u took: %s",
		      step ? "step" : "job", step ? id : id,
		      WEXITSTATUS(status), WTERMSIG(status), TIME_STR);
	} else if (debug_flags & DEBUG_FLAG_SELECT_TYPE)
		info("_run_nhc %s %"PRIu64" completed took: %s",
		     step ? "step" : "job", step ? id : id, TIME_STR);

 fini:
	xfree(argv[2]);
	xfree(argv[3]);
	return status;
#else
	if (debug_flags & DEBUG_FLAG_SELECT_TYPE)
		info("simluating calling NHC for id %"PRIu64" on nodes %s",
		     id, nodelist);

	/* simulate sleeping */
	sleep(2);
	return 0;
#endif
}
コード例 #18
0
ファイル: helper.c プロジェクト: jayjung1018/shell
node* execute(node* jobList, char* largs[], char* rargs[], char* input, char* in, char* out, int pipestatus, int back, int jc, int error){
	int pidl;
	int pidr = 0;
	int pg;
	int status;
	int count = 0;
	int new_outno;
	int new_inno;
	int fd[2];
	char* job;
	node* current;
	node* recentJob;

	//error checking block
	if (error < 0) {
		if (error == -1) {
			write(1, "Error: Invalid I/O Input\n", 26);
			return jobList;
		}

		if (error == -2) {
			write(1, "Error: Invalid Pipe Input\n", 27);
			return jobList;
		}

		if (error == -3) {
			write(1, "Error: Invalid Background Input\n", 33);
			return jobList;
		}

		if (error == -4) {
			write(1, "Error: Invalid fg or bg input\n", 31);
			return jobList;
		}
	}

	//fg
	if (jc == 1) {
		//find a stopped job
		recentJob = findStopped(jobList);
		if (recentJob == NULL) {
			recentJob = jobList; // get the top of the stack
		}

		//this means that there are 0 background jobs
		if (recentJob == NULL) {
			printf("Error: No background jobs\n");
		}

		//send cont signal, give tc to the group
		else {
			if (killpg(recentJob->pgid, SIGCONT) < 0) perror("kill");
			if (tcsetpgrp(STDIN_FILENO, recentJob->pgid) < 0) perror("tcsetpgrp fg");

			//get the pid and pg
			pidl = recentJob->pid;
			pg = recentJob->pgid;
			pipestatus = recentJob->pipe;
			job = malloc(slen(recentJob->command) + 1);
			scopy(recentJob->command, job);

			//if pipe, get the other pid too
			if(pipestatus) {
				jobList = delete(jobList, recentJob->pid);
				recentJob = getg(jobList, pg);
				pidr = recentJob->pid;
			}

			//delete the job off the bg list
			jobList = delete(jobList, recentJob->pid);

			//print job on the shell
			printf("%s\n", job);

			//wait for both processes to finish
			waitpid(pidl, &status, WUNTRACED);
			waitpid(pidr, &status, WUNTRACED);

			// if foreground was stopped, place this job onto the list, notify it was stopped
			if (WIFSTOPPED(status)) {
				printf("\nStopped: %s\n", job);
				jobList = push(jobList, job, pidl, getpgid(pidl), pipestatus, 1);
				if (pipestatus) jobList = push(jobList, job, pidr, getpgid(pidl), pipestatus, 1);
			}

			//free job (i wish)
			free(job);

			//take back control of tc
			if (tcsetpgrp(STDIN_FILENO, getpgid(0)) < 0) perror("tcsetpgrp parent");

			jobList = bgWait(jobList);
		}
		return jobList;
	}

	//bg
	if (jc == 2) {
		// find a stopped job
		recentJob = findStopped(jobList);

		//if there are no stopped jobs, move on
		if (recentJob == NULL) {
			printf("Error: No stopped background jobs\n");
		}

		//otherwise, give signal to that job to continue
		else {
			if (killpg(recentJob->pgid, SIGCONT) < 0) perror("kill");
			pg = recentJob->pgid;
			jobList = changeStopped(jobList, pg);
			printf("Running : %s\n", recentJob->command);
		}

		// poll for background processes
		jobList = bgWait(jobList);

		//return
		return jobList;
	}

	//set up pipe fd's
	if (pipestatus) {
		if (pipe(fd) < 0) perror("Error");
	}

	// fork - twice if there's a pipe
	if ((pidl = fork()) < 0) {
		perror("Error");
	}

	//left command child branch
	if(pidl == 0) {
		//set all signals to default
		signal(SIGTTOU, SIG_DFL);
		signal(SIGTTIN, SIG_DFL);
		signal(SIGTERM, SIG_DFL);
		signal(SIGTSTP, SIG_DFL);
		signal(SIGINT, SIG_DFL);

		// set pgid
		if (setpgid(getpid(), getpid()) < 0) perror("setpgid");

		// give tc if not background (both in child and parent for rc)
		if (!back) {
			if (tcsetpgrp(STDIN_FILENO, getpgid(0)) < 0) perror("tcsetpgrp child");
		}

		//close input + dup2 out to the pipe
		if (pipestatus) {
			if (close(fd[0]) < 0) perror("Error");
			if(dup2(fd[1], 1) < 0) perror("Error");
		}

		// set I/O redirections in child process - stdout
		if (out != NULL && (!pipestatus)) {
			new_outno = open(out, O_WRONLY | O_TRUNC | O_CREAT, 0644); //to do - error check
			if (dup2(new_outno, STDOUT_FILENO) < 0) {
				perror("Error");
				exit(1);
			}
		}

		//stdin
		if (in != NULL) {
			new_inno = open(in, O_RDONLY); //to do - error check
			if (dup2(new_inno, STDIN_FILENO) < 0) {
				perror("Error");
				exit(1);
			}
		}

		// exec
		if (execvp(largs[0], largs) < 0) {
			perror("Error");
			exit(1);
		}
	}

	//PARENT
	else {
		// SECOND PROCESS BRANCH
		if (pipestatus) {
			if((pidr = fork()) < 0) {
				perror("Error");
			}

			// second child branch
			else if(pidr == 0) {

				//set all signals to default
				signal(SIGTTOU, SIG_DFL);
				signal(SIGTTIN, SIG_DFL);
				signal(SIGTERM, SIG_DFL);
				signal(SIGTSTP, SIG_DFL);
				signal(SIGINT, SIG_DFL);

				// set group id if foreground
				if (setpgid(getpid(), pidl) < 0) perror("Error");

				// give tc if not background (both in child and parent for rc)
				if (!back) {
					if (tcsetpgrp(STDIN_FILENO, getpgid(0)) < 0) perror("tcsetpgrp child");
				}

				//close output + dup2 input from pipe
				if (close(fd[1]) < 0) perror("Error");
				if (dup2(fd[0], 0) < 0) perror("Error");

				// set I/O redirections in child process - stdout
				if (out != NULL) {
					new_outno = open(out, O_WRONLY | O_TRUNC | O_CREAT, 0644); //to do - error check
					if (dup2(new_outno, STDOUT_FILENO) < 0) {
						perror("Error");
						exit(1);
					}
				}

				// exec
				if (execvp(rargs[0], rargs) < 0) {
					perror("Error");
					exit(1);
				}
			}
		}

		//PARENT BRANCH:
		//close both pipes in the parent
		if (pipestatus) {
			if (close(fd[0]) < 0) perror("Error");
			if (close(fd[1]) < 0) perror("Error");
		} 

		//set groups
		if (setpgid(pidl, pidl) < 0) perror("setpgid"); 
		if (pipestatus) {
			if (setpgid(pidr, pidl) < 0) perror("setpgid");
		}

		//if background, put job into the list
		if (back) {
			jobList = push(jobList, input, pidl, getpgid(pidl), pipestatus, 0);
			// also put the right side on the list if pipe
			if (pipestatus) jobList = push(jobList, input, pidr, getpgid(pidr), pipestatus, 0);
		}

		//for foreground
		if (!back) {
			//set tcpgrp for child/children
			if (tcsetpgrp(STDIN_FILENO, pidl) < 0) perror("tcsetpgrp child");

			//wait for both child processes to finish if not bg
			waitpid(pidl, &status, WUNTRACED);
			waitpid(pidr, &status, WUNTRACED);

			// if foreground was stopped, place this job onto the list, notify it was stopped
			if (WIFSTOPPED(status)) {
				printf("\nStopped: %s\n", input);
				jobList = push(jobList, input, pidl, getpgid(pidl), pipestatus, 1);
				if (pipestatus) jobList = push(jobList, input, pidr, getpgid(pidl), pipestatus, 1);
			}

			//take back control of tc
			if (tcsetpgrp(STDIN_FILENO, getpgid(0)) < 0) perror("tcsetpgrp parent");
		}

		// wait for background
		jobList = bgWait(jobList);
		return jobList;
	}
	//should never get here but to fend off warnings
	return jobList;
}
コード例 #19
0
ファイル: jawasd.c プロジェクト: cthulhuology/Jawas2
void signalHandler() {
	if (!done) killpg(0,SIGHUP);
	done = 1;
}
コード例 #20
0
VALUE
rb_f_kill(int argc, const VALUE *argv)
{
#ifndef HAVE_KILLPG
#define killpg(pg, sig) kill(-(pg), (sig))
#endif
    int negative = 0;
    int sig;
    int i;
    VALUE str;
    const char *s;

    rb_secure(2);
    rb_check_arity(argc, 2, UNLIMITED_ARGUMENTS);

    switch (TYPE(argv[0])) {
      case T_FIXNUM:
	sig = FIX2INT(argv[0]);
	break;

      case T_SYMBOL:
	str = rb_sym2str(argv[0]);
	goto str_signal;

      case T_STRING:
	str = argv[0];
      str_signal:
	s = RSTRING_PTR(str);
	if (s[0] == '-') {
	    negative++;
	    s++;
	}
	if (strncmp(signame_prefix, s, sizeof(signame_prefix)) == 0)
	    s += 3;
	if ((sig = signm2signo(s)) == 0) {
	    long ofs = s - RSTRING_PTR(str);
	    if (ofs) str = rb_str_subseq(str, ofs, RSTRING_LEN(str)-ofs);
	    rb_raise(rb_eArgError, "unsupported name `SIG%"PRIsVALUE"'", str);
	}

	if (negative)
	    sig = -sig;
	break;

      default:
	str = rb_check_string_type(argv[0]);
	if (!NIL_P(str)) {
	    goto str_signal;
	}
	rb_raise(rb_eArgError, "bad signal type %s",
		 rb_obj_classname(argv[0]));
	break;
    }

    if (argc <= 1) return INT2FIX(0);

    if (sig < 0) {
	sig = -sig;
	for (i=1; i<argc; i++) {
	    if (killpg(NUM2PIDT(argv[i]), sig) < 0)
		rb_sys_fail(0);
	}
    }
    else {
	const rb_pid_t self = (GET_THREAD() == GET_VM()->main_thread) ? getpid() : -1;
	int wakeup = 0;

	for (i=1; i<argc; i++) {
	    rb_pid_t pid = NUM2PIDT(argv[i]);

	    if ((sig != 0) && (self != -1) && (pid == self)) {
		int t;
		/*
		 * When target pid is self, many caller assume signal will be
		 * delivered immediately and synchronously.
		 */
		switch (sig) {
		  case SIGSEGV:
#ifdef SIGBUS
		  case SIGBUS:
#endif
#ifdef SIGKILL
		  case SIGKILL:
#endif
#ifdef SIGSTOP
		  case SIGSTOP:
#endif
		    ruby_kill(pid, sig);
		    break;
		  default:
		    t = signal_ignored(sig);
		    if (t) {
			if (t < 0 && kill(pid, sig))
			    rb_sys_fail(0);
			break;
		    }
		    signal_enque(sig);
		    wakeup = 1;
		}
	    }
	    else if (kill(pid, sig) < 0) {
		rb_sys_fail(0);
	    }
	}
	if (wakeup) {
	    rb_threadptr_check_signal(GET_VM()->main_thread);
	}
    }
    rb_thread_execute_interrupts(rb_thread_current());

    return INT2FIX(i-1);
}
コード例 #21
0
ファイル: capmc_suspend.c プロジェクト: A1ve5/slurm
/* Run a script and return its stdout plus exit status */
static char *_run_script(char **script_argv, int *status)
{
	int cc, i, new_wait, resp_size = 0, resp_offset = 0;
	pid_t cpid;
	char *resp = NULL;
	int pfd[2] = { -1, -1 };

	if (access(capmc_path, R_OK | X_OK) < 0) {
		error("%s: Can not execute: %s", prog_name, capmc_path);
		*status = 127;
		resp = xstrdup("Slurm node_features/knl_cray configuration error");
		return resp;
	}
	if (pipe(pfd) != 0) {
		error("%s: pipe(): %s", prog_name,
		      slurm_strerror(slurm_get_errno()));
		*status = 127;
		resp = xstrdup("System error");
		return resp;
	}

	if ((cpid = fork()) == 0) {
		cc = sysconf(_SC_OPEN_MAX);
		dup2(pfd[1], STDERR_FILENO);
		dup2(pfd[1], STDOUT_FILENO);
		for (i = 0; i < cc; i++) {
			if ((i != STDERR_FILENO) && (i != STDOUT_FILENO))
				close(i);
		}
		setpgid(0, 0);
		execv(capmc_path, script_argv);
		error("%s: execv(): %s", prog_name,
		      slurm_strerror(slurm_get_errno()));
		exit(127);
	} else if (cpid < 0) {
		close(pfd[0]);
		close(pfd[1]);
		error("%s: fork(): %s", prog_name,
		      slurm_strerror(slurm_get_errno()));
		*status = 127;
		resp = xstrdup("System error");
		return resp;
	} else {
		struct pollfd fds;
		struct timeval tstart;
		resp_size = 1024;
		resp = xmalloc(resp_size);
		close(pfd[1]);
		gettimeofday(&tstart, NULL);
		while (1) {
			fds.fd = pfd[0];
			fds.events = POLLIN | POLLHUP | POLLRDHUP;
			fds.revents = 0;
			new_wait = capmc_timeout - _tot_wait(&tstart);
			if (new_wait <= 0) {
				error("%s: poll() timeout @ %d msec", prog_name,
				      capmc_timeout);
				break;
			}
			new_wait = MIN(new_wait, MAX_POLL_WAIT);
			i = poll(&fds, 1, new_wait);
			if (i == 0) {
				continue;
			} else if (i < 0) {
				error("%s: poll(): %s", prog_name,
				      slurm_strerror(slurm_get_errno()));
				break;
			}
			if ((fds.revents & POLLIN) == 0)
				break;
			i = read(pfd[0], resp + resp_offset,
				 resp_size - resp_offset);
			if (i == 0) {
				break;
			} else if (i < 0) {
				if (errno == EAGAIN)
					continue;
				error("%s: read(): %s", prog_name,
				      slurm_strerror(slurm_get_errno()));
				break;
			} else {
				resp_offset += i;
				if (resp_offset + 1024 >= resp_size) {
					resp_size *= 2;
					resp = xrealloc(resp, resp_size);
				}
			}
		}
		killpg(cpid, SIGTERM);
		usleep(10000);
		killpg(cpid, SIGKILL);
		waitpid(cpid, status, 0);
		close(pfd[0]);
	}
	return resp;
}
コード例 #22
0
ファイル: cleanup.c プロジェクト: herzfeldd/parallel_wrapper
/**
 * Clean up and then exit with the associated return code
 */
void cleanup(parallel_wrapper *par_wrapper, int return_code)
{
    int i, j;
    /* Try to lock the keep-alive mutex */
    pthread_mutex_trylock(&keep_alive_mutex);
    if (par_wrapper -> this_machine -> rank == MASTER &&
            par_wrapper -> machines != (machine **)NULL)
    {

        /* Send the term signal (don't send to self) */
        for (i = 1; i < par_wrapper -> num_procs; i++)
        {
            if (par_wrapper -> machines[i] == (machine *)NULL)
            {
                continue;
            }
            for (j = 0; j < 10; j++)
            {
                term(par_wrapper -> command_socket, return_code,
                     par_wrapper -> machines[i] -> ip_addr, par_wrapper -> machines[i] -> port);
                usleep(100000); /* Sleep 1/10th second */
            }
        }
    }

    /* If we spawned subgroups, attempt to kill them all */
    if (par_wrapper -> pgid > 0 && par_wrapper -> child_pid > 0)
    {
        int RC = killpg(par_wrapper -> child_pid, SIGTERM);
        if (RC == EPERM)
        {
            print(PRNT_WARN, "Unable to kill child pid %d - permission denied\n");
        }
        else if (RC == 0)
        {
            debug(PRNT_INFO, "Sent SIGTERM to child group %d\n", par_wrapper -> child_pid);
        }
    }

    /* Lock the parallel_wrapper structure */
    pthread_mutex_trylock(&par_wrapper -> mutex);

    /* Clean up the scratch directory */
    cleanup_scratch(par_wrapper -> scratch_dir);

    /* Unlink all softlinks */
    if (is_valid_sll(par_wrapper -> symlinks))
    {
        struct sll_element *element = par_wrapper -> symlinks -> head -> next;
        while (element != (struct sll_element *)NULL)
        {
            char *filename = (char *)element -> ptr;
            if (filename != (char *)NULL)
            {
                if (unlink(filename) != 0)
                {
                    print(PRNT_WARN, "Unable to unlink file %s\n", filename);
                }
            }
            element = element -> next;
        }
    }
    /* No need to unlock - we are exitting */
    exit(return_code);
}
コード例 #23
0
ファイル: 1-2.c プロジェクト: Mellanox/arc_ltp
int main()
{
	int child_pid, child_pgid;

	if ((child_pid = fork()) == 0) {
		/* child here */
		struct sigaction act;
		act.sa_handler=myhandler;
		act.sa_flags=0;
		sigemptyset(&act.sa_mask);
		sigaction(SIGTOTEST, &act, 0);

		/* change child's process group id */

		/*
		 * XXX: POSIX 1003.1-2001 added setpgrp(2) to BASE, but
		 * unfortunately BSD has had their own implementations for
		 * ages for compatibility reasons.
		 */
#if __FreeBSD__ || __NetBSD__ || __OpenBSD__
		setpgrp(0, 0);
#else
		setpgrp();
#endif

		sigpause(SIGABRT);

		return 0;
	} else {
		/* parent here */
		int i;
		sigignore(SIGTOTEST);

		sleep(1);
		if ((child_pgid = getpgid(child_pid)) == -1) {
			printf("Could not get pgid of child\n");
			return PTS_UNRESOLVED;
		}

		if (killpg(child_pgid, SIGTOTEST) != 0) {
			printf("Could not raise signal being tested\n");
			return PTS_UNRESOLVED;
		}

		if (wait(&i) == -1) {
			perror("Error waiting for child to exit\n");
			return PTS_UNRESOLVED;
		}

		if (WEXITSTATUS(i)) {
			printf("Child exited normally\n");
			printf("Test PASSED\n");
			return PTS_PASS;
		} else {
			printf("Child did not exit normally.\n");
			printf("Test FAILED\n");
			return PTS_FAIL;
		}
	}

	printf("Should have exited from parent\n");
	printf("Test FAILED\n");
	return PTS_FAIL;
}
コード例 #24
0
ファイル: proc.cpp プロジェクト: actionless/fish-shell
void job_continue(job_t *j, bool cont)
{
    /*
      Put job first in the job list
    */
    job_promote(j);
    job_set_flag(j, JOB_NOTIFIED, 0);

    CHECK_BLOCK();

    debug(4,
          L"Continue job %d, gid %d (%ls), %ls, %ls",
          j->job_id,
          j->pgid,
          j->command_wcstr(),
          job_is_completed(j)?L"COMPLETED":L"UNCOMPLETED",
          is_interactive?L"INTERACTIVE":L"NON-INTERACTIVE");

    if (!job_is_completed(j))
    {
        if (job_get_flag(j, JOB_TERMINAL) && job_get_flag(j, JOB_FOREGROUND))
        {
            /* Put the job into the foreground. Hack: ensure that stdin is marked as blocking first (#176). */
            make_fd_blocking(STDIN_FILENO);

            signal_block();

            bool ok = terminal_give_to_job(j, cont);

            signal_unblock();

            if (!ok)
                return;
        }

        /*
           Send the job a continue signal, if necessary.
        */
        if (cont)
        {
            process_t *p;

            for (p=j->first_process; p; p=p->next)
                p->stopped=0;

            if (job_get_flag(j, JOB_CONTROL))
            {
                if (killpg(j->pgid, SIGCONT))
                {
                    wperror(L"killpg (SIGCONT)");
                    return;
                }
            }
            else
            {
                for (p=j->first_process; p; p=p->next)
                {
                    if (kill(p->pid, SIGCONT) < 0)
                    {
                        wperror(L"kill (SIGCONT)");
                        return;
                    }
                }
            }
        }

        if (job_get_flag(j, JOB_FOREGROUND))
        {
            /* Look for finished processes first, to avoid select() if it's already done. */
            process_mark_finished_children(false);

            /*
               Wait for job to report.
            */
            while (! reader_exit_forced() && ! job_is_stopped(j) && ! job_is_completed(j))
            {
//					debug( 1, L"select_try()" );
                switch (select_try(j))
                {
                    case 1:
                    {
                        read_try(j);
                        process_mark_finished_children(false);
                        break;
                    }
                    
                    case 0:
                    {
                        /* No FDs are ready. Look for finished processes. */
                        process_mark_finished_children(false);
                        break;
                    }

                    case -1:
                    {
                        /*
                          If there is no funky IO magic, we can use
                          waitpid instead of handling child deaths
                          through signals. This gives a rather large
                          speed boost (A factor 3 startup time
                          improvement on my 300 MHz machine) on
                          short-lived jobs.
                         
                          This will return early if we get a signal,
                          like SIGHUP.
                        */
                        process_mark_finished_children(true);
                        break;
                    }
                }
            }
        }
    }

    if (job_get_flag(j, JOB_FOREGROUND))
    {

        if (job_is_completed(j))
        {

            // It's possible that the job will produce output and exit before we've even read from it.
            // We'll eventually read the output, but it may be after we've executed subsequent calls
            // This is why my prompt colors kept getting screwed up - the builtin echo calls
            // were sometimes having their output combined with the set_color calls in the wrong order!
            read_try(j);

            process_t *p = j->first_process;
            while (p->next)
                p = p->next;

            if (WIFEXITED(p->status) || WIFSIGNALED(p->status))
            {
                /*
                   Mark process status only if we are in the foreground
                   and the last process in a pipe, and it is not a short circuited builtin
                */
                if (p->pid)
                {
                    int status = proc_format_status(p->status);
                    //wprintf(L"setting status %d for %ls\n", job_get_flag( j, JOB_NEGATE )?!status:status, j->command);
                    proc_set_last_status(job_get_flag(j, JOB_NEGATE)?!status:status);
                }
            }
        }

        /* Put the shell back in the foreground. */
        if (job_get_flag(j, JOB_TERMINAL) && job_get_flag(j, JOB_FOREGROUND))
        {
            int ok;

            signal_block();

            ok = terminal_return_from_job(j);

            signal_unblock();

            if (!ok)
                return;

        }
    }

}
コード例 #25
0
int main(int argc, char *argv[])
{
	log_options_t logopt = LOG_OPTS_STDERR_ONLY;
	job_desc_msg_t desc;
	resource_allocation_response_msg_t *alloc;
	time_t before, after;
	allocation_msg_thread_t *msg_thr;
	char **env = NULL, *cluster_name;
	int status = 0;
	int retries = 0;
	pid_t pid  = getpid();
	pid_t tpgid = 0;
	pid_t rc_pid = 0;
	int i, rc = 0;
	static char *msg = "Slurm job queue full, sleeping and retrying.";
	slurm_allocation_callbacks_t callbacks;

	slurm_conf_init(NULL);
	log_init(xbasename(argv[0]), logopt, 0, NULL);
	_set_exit_code();

	if (spank_init_allocator() < 0) {
		error("Failed to initialize plugin stack");
		exit(error_exit);
	}

	/* Be sure to call spank_fini when salloc exits
	 */
	if (atexit((void (*) (void)) spank_fini) < 0)
		error("Failed to register atexit handler for plugins: %m");


	if (initialize_and_process_args(argc, argv) < 0) {
		error("salloc parameter parsing");
		exit(error_exit);
	}
	/* reinit log with new verbosity (if changed by command line) */
	if (opt.verbose || opt.quiet) {
		logopt.stderr_level += opt.verbose;
		logopt.stderr_level -= opt.quiet;
		logopt.prefix_level = 1;
		log_alter(logopt, 0, NULL);
	}

	if (spank_init_post_opt() < 0) {
		error("Plugin stack post-option processing failed");
		exit(error_exit);
	}

	_set_spank_env();
	_set_submit_dir_env();
	if (opt.cwd && chdir(opt.cwd)) {
		error("chdir(%s): %m", opt.cwd);
		exit(error_exit);
	}

	if (opt.get_user_env_time >= 0) {
		bool no_env_cache = false;
		char *sched_params;
		char *user = uid_to_string(opt.uid);

		if (xstrcmp(user, "nobody") == 0) {
			error("Invalid user id %u: %m", (uint32_t)opt.uid);
			exit(error_exit);
		}

		sched_params = slurm_get_sched_params();
		no_env_cache = (sched_params &&
				strstr(sched_params, "no_env_cache"));
		xfree(sched_params);

		env = env_array_user_default(user,
					     opt.get_user_env_time,
					     opt.get_user_env_mode,
					     no_env_cache);
		xfree(user);
		if (env == NULL)
			exit(error_exit);    /* error already logged */
		_set_rlimits(env);
	}

	/*
	 * Job control for interactive salloc sessions: only if ...
	 *
	 * a) input is from a terminal (stdin has valid termios attributes),
	 * b) controlling terminal exists (non-negative tpgid),
	 * c) salloc is not run in allocation-only (--no-shell) mode,
	 * NOTE: d and e below are configuration dependent
	 * d) salloc runs in its own process group (true in interactive
	 *    shells that support job control),
	 * e) salloc has been configured at compile-time to support background
	 *    execution and is not currently in the background process group.
	 */
	if (tcgetattr(STDIN_FILENO, &saved_tty_attributes) < 0) {
		/*
		 * Test existence of controlling terminal (tpgid > 0)
		 * after first making sure stdin is not redirected.
		 */
	} else if ((tpgid = tcgetpgrp(STDIN_FILENO)) < 0) {
#ifdef HAVE_ALPS_CRAY
		verbose("no controlling terminal");
#else
		if (!opt.no_shell) {
			error("no controlling terminal: please set --no-shell");
			exit(error_exit);
		}
#endif
#ifdef SALLOC_RUN_FOREGROUND
	} else if ((!opt.no_shell) && (pid == getpgrp())) {
		if (tpgid == pid)
			is_interactive = true;
		while (tcgetpgrp(STDIN_FILENO) != pid) {
			if (!is_interactive) {
				error("Waiting for program to be placed in "
				      "the foreground");
				is_interactive = true;
			}
			killpg(pid, SIGTTIN);
		}
	}
#else
	} else if ((!opt.no_shell) && (getpgrp() == tcgetpgrp(STDIN_FILENO))) {
コード例 #26
0
ファイル: app.cpp プロジェクト: BackupTheBerlios/slim-svn
void App::Login() {
    struct passwd *pw;
    pid_t pid;

    pw = LoginPanel->GetInput()->GetPasswdStruct();
    if(pw == 0)
        return;

    // Create new process
    pid = fork();
    if(pid == 0) {
        // Login process starts here
        SwitchUser Su(pw, &cfg, DisplayName);
        string session = LoginPanel->getSession();
        string loginCommand = cfg.getOption("login_cmd");
        replaceVariables(loginCommand, SESSION_VAR, session);
        replaceVariables(loginCommand, THEME_VAR, themeName);
        string sessStart = cfg.getOption("sessionstart_cmd");
        if (sessStart != "") {
            replaceVariables(sessStart, USER_VAR, pw->pw_name);
            system(sessStart.c_str());
        }
        Su.Login(loginCommand.c_str());
        exit(OK_EXIT);
    }

#ifndef XNEST_DEBUG
    CloseLog();
#endif

    // Wait until user is logging out (login process terminates)
    pid_t wpid = -1;
    int status;
    while (wpid != pid) {
        wpid = wait(&status);
    }
    if (WIFEXITED(status) && WEXITSTATUS(status)) {
        LoginPanel->Message("Failed to execute login command");
    } else {
         string sessStop = cfg.getOption("sessionstop_cmd");
         if (sessStop != "") {
            replaceVariables(sessStop, USER_VAR, pw->pw_name);
            system(sessStop.c_str());
        }
    }

    // Close all clients
    KillAllClients(False);
    KillAllClients(True);

    // Send HUP signal to clientgroup
    killpg(pid, SIGHUP);

    // Send TERM signal to clientgroup, if error send KILL
    if(killpg(pid, SIGTERM))
    killpg(pid, SIGKILL);

    HideCursor();

#ifndef XNEST_DEBUG
    // Re-activate log file
    OpenLog();
#endif
}
コード例 #27
0
/* Execute a script, wait for termination and return its stdout.
 * script_type IN - Type of program being run (e.g. "StartStageIn")
 * script_path IN - Fully qualified pathname of the program to execute
 * script_args IN - Arguments to the script
 * max_wait IN - Maximum time to wait in milliseconds,
 *		 -1 for no limit (asynchronous)
 * status OUT - Job exit code
 * Return stdout+stderr of spawned program, value must be xfreed. */
extern char *bb_run_script(char *script_type, char *script_path,
			   char **script_argv, int max_wait, int *status)
{
	int i, new_wait, resp_size = 0, resp_offset = 0;
	pid_t cpid;
	char *resp = NULL;
	int pfd[2] = { -1, -1 };

	if ((script_path == NULL) || (script_path[0] == '\0')) {
		error("%s: no script specified", __func__);
		*status = 127;
		resp = xstrdup("Slurm burst buffer configuration error");
		return resp;
	}
	if (script_path[0] != '/') {
		error("%s: %s is not fully qualified pathname (%s)",
		      __func__, script_type, script_path);
		*status = 127;
		resp = xstrdup("Slurm burst buffer configuration error");
		return resp;
	}
	if (access(script_path, R_OK | X_OK) < 0) {
		error("%s: %s can not be executed (%s) %m",
		      __func__, script_type, script_path);
		*status = 127;
		resp = xstrdup("Slurm burst buffer configuration error");
		return resp;
	}
	if (max_wait != -1) {
		if (pipe(pfd) != 0) {
			error("%s: pipe(): %m", __func__);
			*status = 127;
			resp = xstrdup("System error");
			return resp;
		}
	}
	slurm_mutex_lock(&proc_count_mutex);
	child_proc_count++;
	slurm_mutex_unlock(&proc_count_mutex);
	if ((cpid = fork()) == 0) {
		int cc;

		cc = sysconf(_SC_OPEN_MAX);
		if (max_wait != -1) {
			dup2(pfd[1], STDERR_FILENO);
			dup2(pfd[1], STDOUT_FILENO);
			for (i = 0; i < cc; i++) {
				if ((i != STDERR_FILENO) &&
				    (i != STDOUT_FILENO))
					close(i);
			}
		} else {
			for (i = 0; i < cc; i++)
				close(i);
			if ((cpid = fork()) < 0)
				exit(127);
			else if (cpid > 0)
				exit(0);
		}
		setpgid(0, 0);
		execv(script_path, script_argv);
		error("%s: execv(%s): %m", __func__, script_path);
		exit(127);
	} else if (cpid < 0) {
		if (max_wait != -1) {
			close(pfd[0]);
			close(pfd[1]);
		}
		error("%s: fork(): %m", __func__);
		slurm_mutex_lock(&proc_count_mutex);
		child_proc_count--;
		slurm_mutex_unlock(&proc_count_mutex);
	} else if (max_wait != -1) {
		struct pollfd fds;
		struct timeval tstart;
		resp_size = 1024;
		resp = xmalloc(resp_size);
		close(pfd[1]);
		gettimeofday(&tstart, NULL);
		while (1) {
			if (bb_plugin_shutdown) {
				error("%s: killing %s operation on shutdown",
				      __func__, script_type);
				break;
			}
			fds.fd = pfd[0];
			fds.events = POLLIN | POLLHUP | POLLRDHUP;
			fds.revents = 0;
			if (max_wait <= 0) {
				new_wait = MAX_POLL_WAIT;
			} else {
				new_wait = max_wait - _tot_wait(&tstart);
				if (new_wait <= 0) {
					error("%s: %s poll timeout @ %d msec",
					      __func__, script_type, max_wait);
					break;
				}
				new_wait = MIN(new_wait, MAX_POLL_WAIT);
			}
			i = poll(&fds, 1, new_wait);
			if (i == 0) {
				continue;
			} else if (i < 0) {
				error("%s: %s poll:%m", __func__, script_type);
				break;
			}
			if ((fds.revents & POLLIN) == 0)
				break;
			i = read(pfd[0], resp + resp_offset,
				 resp_size - resp_offset);
			if (i == 0) {
				break;
			} else if (i < 0) {
				if (errno == EAGAIN)
					continue;
				error("%s: read(%s): %m", __func__,
				      script_path);
				break;
			} else {
				resp_offset += i;
				if (resp_offset + 1024 >= resp_size) {
					resp_size *= 2;
					resp = xrealloc(resp, resp_size);
				}
			}
		}
		killpg(cpid, SIGTERM);
		usleep(10000);
		killpg(cpid, SIGKILL);
		waitpid(cpid, status, 0);
		close(pfd[0]);
		slurm_mutex_lock(&proc_count_mutex);
		child_proc_count--;
		slurm_mutex_unlock(&proc_count_mutex);
	} else {
		waitpid(cpid, status, 0);
	}
	return resp;
}
コード例 #28
0
ファイル: rshd.c プロジェクト: hmatyschok/MeshBSD
void
doit(struct sockaddr *fromp)
{
	extern char *__rcmd_errstr;	/* syslog hook from libc/net/rcmd.c. */
	struct passwd *pwd;
	u_short port;
	fd_set ready, readfrom;
	int cc, fd, nfd, pv[2], pid, s;
	int one = 1;
	const char *cp, *errorstr;
	char sig, buf[BUFSIZ];
	char *cmdbuf, luser[16], ruser[16];
	char rhost[2 * MAXHOSTNAMELEN + 1];
	char numericname[INET6_ADDRSTRLEN];
	int af, srcport;
	int maxcmdlen;
	login_cap_t *lc;

	maxcmdlen = (int)sysconf(_SC_ARG_MAX);
	if (maxcmdlen <= 0 || (cmdbuf = malloc(maxcmdlen)) == NULL)
		exit(1);

	(void) signal(SIGINT, SIG_DFL);
	(void) signal(SIGQUIT, SIG_DFL);
	(void) signal(SIGTERM, SIG_DFL);
	af = fromp->sa_family;
	srcport = ntohs(*((in_port_t *)&fromp->sa_data));
	if (af == AF_INET) {
		inet_ntop(af, &((struct sockaddr_in *)fromp)->sin_addr,
		    numericname, sizeof numericname);
	} else if (af == AF_INET6) {
		inet_ntop(af, &((struct sockaddr_in6 *)fromp)->sin6_addr,
		    numericname, sizeof numericname);
	} else {
		syslog(LOG_ERR, "malformed \"from\" address (af %d)", af);
		exit(1);
	}
#ifdef IP_OPTIONS
	if (af == AF_INET) {
		u_char optbuf[BUFSIZ/3];
		socklen_t optsize = sizeof(optbuf), ipproto, i;
		struct protoent *ip;

		if ((ip = getprotobyname("ip")) != NULL)
			ipproto = ip->p_proto;
		else
			ipproto = IPPROTO_IP;
		if (!getsockopt(0, ipproto, IP_OPTIONS, optbuf, &optsize) &&
		    optsize != 0) {
			for (i = 0; i < optsize; ) {
				u_char c = optbuf[i];
				if (c == IPOPT_LSRR || c == IPOPT_SSRR) {
					syslog(LOG_NOTICE,
					    "connection refused from %s with IP option %s",
					    numericname,
					    c == IPOPT_LSRR ? "LSRR" : "SSRR");
					exit(1);
				}
				if (c == IPOPT_EOL)
					break;
				i += (c == IPOPT_NOP) ? 1 : optbuf[i+1];
			}
		}
	}
#endif

	if (srcport >= IPPORT_RESERVED ||
	    srcport < IPPORT_RESERVED/2) {
		syslog(LOG_NOTICE|LOG_AUTH,
		    "connection from %s on illegal port %u",
		    numericname,
		    srcport);
		exit(1);
	}

	(void) alarm(60);
	port = 0;
	s = 0;		/* not set or used if port == 0 */
	for (;;) {
		char c;
		if ((cc = read(STDIN_FILENO, &c, 1)) != 1) {
			if (cc < 0)
				syslog(LOG_NOTICE, "read: %m");
			shutdown(0, SHUT_RDWR);
			exit(1);
		}
		if (c == 0)
			break;
		port = port * 10 + c - '0';
	}

	(void) alarm(0);
	if (port != 0) {
		int lport = IPPORT_RESERVED - 1;
		s = rresvport_af(&lport, af);
		if (s < 0) {
			syslog(LOG_ERR, "can't get stderr port: %m");
			exit(1);
		}
		if (port >= IPPORT_RESERVED ||
		    port < IPPORT_RESERVED/2) {
			syslog(LOG_NOTICE|LOG_AUTH,
			    "2nd socket from %s on unreserved port %u",
			    numericname,
			    port);
			exit(1);
		}
		*((in_port_t *)&fromp->sa_data) = htons(port);
		if (connect(s, fromp, fromp->sa_len) < 0) {
			syslog(LOG_INFO, "connect second port %d: %m", port);
			exit(1);
		}
	}

	errorstr = NULL;
	realhostname_sa(rhost, sizeof(rhost) - 1, fromp, fromp->sa_len);
	rhost[sizeof(rhost) - 1] = '\0';
	/* XXX truncation! */

	(void) alarm(60);
	getstr(ruser, sizeof(ruser), "ruser");
	getstr(luser, sizeof(luser), "luser");
	getstr(cmdbuf, maxcmdlen, "command");
	(void) alarm(0);

	pam_err = pam_start("rsh", luser, &pamc, &pamh);
	if (pam_err != PAM_SUCCESS) {
		syslog(LOG_ERR|LOG_AUTH, "pam_start(): %s",
		    pam_strerror(pamh, pam_err));
		rshd_errx(1, "Login incorrect.");
	}

	if ((pam_err = pam_set_item(pamh, PAM_RUSER, ruser)) != PAM_SUCCESS ||
	    (pam_err = pam_set_item(pamh, PAM_RHOST, rhost)) != PAM_SUCCESS) {
		syslog(LOG_ERR|LOG_AUTH, "pam_set_item(): %s",
		    pam_strerror(pamh, pam_err));
		rshd_errx(1, "Login incorrect.");
	}

	pam_err = pam_authenticate(pamh, 0);
	if (pam_err == PAM_SUCCESS) {
		if ((pam_err = pam_get_user(pamh, &cp, NULL)) == PAM_SUCCESS) {
			strncpy(luser, cp, sizeof(luser));
			luser[sizeof(luser) - 1] = '\0';
			/* XXX truncation! */
		}
		pam_err = pam_acct_mgmt(pamh, 0);
	}
	if (pam_err != PAM_SUCCESS) {
		syslog(LOG_INFO|LOG_AUTH,
		    "%s@%s as %s: permission denied (%s). cmd='%.80s'",
		    ruser, rhost, luser, pam_strerror(pamh, pam_err), cmdbuf);
		rshd_errx(1, "Login incorrect.");
	}

	setpwent();
	pwd = getpwnam(luser);
	if (pwd == NULL) {
		syslog(LOG_INFO|LOG_AUTH,
		    "%s@%s as %s: unknown login. cmd='%.80s'",
		    ruser, rhost, luser, cmdbuf);
		if (errorstr == NULL)
			errorstr = "Login incorrect.";
		rshd_errx(1, errorstr, rhost);
	}

	lc = login_getpwclass(pwd);
	if (pwd->pw_uid)
		auth_checknologin(lc);

	if (chdir(pwd->pw_dir) < 0) {
		if (chdir("/") < 0 ||
		    login_getcapbool(lc, "requirehome", !!pwd->pw_uid)) {
			syslog(LOG_INFO|LOG_AUTH,
			"%s@%s as %s: no home directory. cmd='%.80s'",
			ruser, rhost, luser, cmdbuf);
			rshd_errx(0, "No remote home directory.");
		}
		pwd->pw_dir = slash;
	}

	if (lc != NULL && fromp->sa_family == AF_INET) {	/*XXX*/
		char	remote_ip[MAXHOSTNAMELEN];

		strncpy(remote_ip, numericname,
			sizeof(remote_ip) - 1);
		remote_ip[sizeof(remote_ip) - 1] = 0;
		/* XXX truncation! */
		if (!auth_hostok(lc, rhost, remote_ip)) {
			syslog(LOG_INFO|LOG_AUTH,
			    "%s@%s as %s: permission denied (%s). cmd='%.80s'",
			    ruser, rhost, luser, __rcmd_errstr,
			    cmdbuf);
			rshd_errx(1, "Login incorrect.");
		}
		if (!auth_timeok(lc, time(NULL)))
			rshd_errx(1, "Logins not available right now");
	}

	/*
	 * PAM modules might add supplementary groups in
	 * pam_setcred(), so initialize them first.
	 * But we need to open the session as root.
	 */
	if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGROUP) != 0) {
		syslog(LOG_ERR, "setusercontext: %m");
		exit(1);
	}

	if ((pam_err = pam_open_session(pamh, 0)) != PAM_SUCCESS) {
		syslog(LOG_ERR, "pam_open_session: %s", pam_strerror(pamh, pam_err));
	} else if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) {
		syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, pam_err));
	}

	(void) write(STDERR_FILENO, "\0", 1);
	sent_null = 1;

	if (port) {
		if (pipe(pv) < 0)
			rshd_errx(1, "Can't make pipe.");
		pid = fork();
		if (pid == -1)
			rshd_errx(1, "Can't fork; try again.");
		if (pid) {
			(void) close(0);
			(void) close(1);
			(void) close(2);
			(void) close(pv[1]);

			FD_ZERO(&readfrom);
			FD_SET(s, &readfrom);
			FD_SET(pv[0], &readfrom);
			if (pv[0] > s)
				nfd = pv[0];
			else
				nfd = s;
				ioctl(pv[0], FIONBIO, (char *)&one);

			/* should set s nbio! */
			nfd++;
			do {
				ready = readfrom;
				if (select(nfd, &ready, (fd_set *)0,
				  (fd_set *)0, (struct timeval *)0) < 0)
					break;
				if (FD_ISSET(s, &ready)) {
					int	ret;
						ret = read(s, &sig, 1);
				if (ret <= 0)
					FD_CLR(s, &readfrom);
				else
					killpg(pid, sig);
				}
				if (FD_ISSET(pv[0], &ready)) {
					errno = 0;
					cc = read(pv[0], buf, sizeof(buf));
					if (cc <= 0) {
						shutdown(s, SHUT_RDWR);
						FD_CLR(pv[0], &readfrom);
					} else {
						(void)write(s, buf, cc);
					}
				}

			} while (FD_ISSET(s, &readfrom) ||
			    FD_ISSET(pv[0], &readfrom));
			PAM_END;
			exit(0);
		}
		(void) close(s);
		(void) close(pv[0]);
		dup2(pv[1], 2);
		close(pv[1]);
	}
	else {
		pid = fork();
		if (pid == -1)
			rshd_errx(1, "Can't fork; try again.");
		if (pid) {
			/* Parent. */
			while (wait(NULL) > 0 || errno == EINTR)
				/* nothing */ ;
			PAM_END;
			exit(0);
		}
	}

	for (fd = getdtablesize(); fd > 2; fd--)
		(void) close(fd);
	if (setsid() == -1)
		syslog(LOG_ERR, "setsid() failed: %m");
	if (setlogin(pwd->pw_name) < 0)
		syslog(LOG_ERR, "setlogin() failed: %m");

	if (*pwd->pw_shell == '\0')
		pwd->pw_shell = bshell;
	(void) pam_setenv(pamh, "HOME", pwd->pw_dir, 1);
	(void) pam_setenv(pamh, "SHELL", pwd->pw_shell, 1);
	(void) pam_setenv(pamh, "USER", pwd->pw_name, 1);
	(void) pam_setenv(pamh, "PATH", _PATH_DEFPATH, 1);
	environ = pam_getenvlist(pamh);
	(void) pam_end(pamh, pam_err);
	cp = strrchr(pwd->pw_shell, '/');
	if (cp)
		cp++;
	else
		cp = pwd->pw_shell;

	if (setusercontext(lc, pwd, pwd->pw_uid,
		LOGIN_SETALL & ~LOGIN_SETGROUP) < 0) {
		syslog(LOG_ERR, "setusercontext(): %m");
		exit(1);
	}
	login_close(lc);
	endpwent();
	if (log_success || pwd->pw_uid == 0) {
		    syslog(LOG_INFO|LOG_AUTH, "%s@%s as %s: cmd='%.80s'",
			ruser, rhost, luser, cmdbuf);
	}
	execl(pwd->pw_shell, cp, "-c", cmdbuf, (char *)NULL);
	err(1, "%s", pwd->pw_shell);
	exit(1);
}
コード例 #29
0
ファイル: task.c プロジェクト: damienfrancois/slurm
/*
 * Run a task prolog script.  Also read the stdout of the script and set
 * 	environment variables in the task's environment as specified
 *	in the script's standard output.
 * name IN: class of program ("system prolog", "user prolog", etc.)
 * path IN: pathname of program to run
 * job IN/OUT: pointer to associated job, can update job->env
 *	if prolog
 * RET 0 on success, -1 on failure.
 */
static int
_run_script_and_set_env(const char *name, const char *path,
			stepd_step_rec_t *job)
{
	int status, rc;
	pid_t cpid;
	int pfd[2];
	char buf[4096];
	FILE *f;

	xassert(job->env);
	if (path == NULL || path[0] == '\0')
		return 0;

	debug("[job %u] attempting to run %s [%s]", job->jobid, name, path);

	if (access(path, R_OK | X_OK) < 0) {
		error("Could not run %s [%s]: %m", name, path);
		return -1;
	}
	if (pipe(pfd) < 0) {
		error("executing %s: pipe: %m", name);
		return -1;
	}
	if ((cpid = fork()) < 0) {
		error("executing %s: fork: %m", name);
		return -1;
	}
	if (cpid == 0) {
		char *argv[2];

		argv[0] = xstrdup(path);
		argv[1] = NULL;
		close(1);
		if (dup(pfd[1]) == -1)
			error("couldn't do the dup: %m");
		close(2);
		close(0);
		close(pfd[0]);
		close(pfd[1]);
#ifdef SETPGRP_TWO_ARGS
		setpgrp(0, 0);
#else
		setpgrp();
#endif
		execve(path, argv, job->env);
		error("execve(%s): %m", path);
		exit(127);
	}

	close(pfd[1]);
	f = fdopen(pfd[0], "r");
	if (f == NULL) {
		error("Cannot open pipe device: %m");
		log_fini();
		exit(1);
	}
	while (feof(f) == 0) {
		if (fgets(buf, sizeof(buf) - 1, f) != NULL) {
			_proc_stdout(buf, job);
		}
	}
	fclose(f);

	while (1) {
		rc = waitpid(cpid, &status, 0);
		if (rc < 0) {
			if (errno == EINTR)
				continue;
			error("waidpid: %m");
			return 0;
		} else  {
			killpg(cpid, SIGKILL);  /* kill children too */
			return status;
		}
	}

	/* NOTREACHED */
}
コード例 #30
0
void runSuccess() {
    killpg(anypid(), anyint());
}