Example #1
0
static void
action_launch_child(svc_action_t *op)
{
    int lpc;

    /* SIGPIPE is ignored (which is different from signal blocking) by the gnutls library.
     * Depending on the libqb version in use, libqb may set SIGPIPE to be ignored as well. 
     * We do not want this to be inherited by the child process. By resetting this the signal
     * to the default behavior, we avoid some potential odd problems that occur during OCF
     * scripts when SIGPIPE is ignored by the environment. */
    signal(SIGPIPE, SIG_DFL);

#if defined(HAVE_SCHED_SETSCHEDULER)
    if (sched_getscheduler(0) != SCHED_OTHER) {
        struct sched_param sp;

        memset(&sp, 0, sizeof(sp));
        sp.sched_priority = 0;

        if (sched_setscheduler(0, SCHED_OTHER, &sp) == -1) {
            crm_perror(LOG_ERR, "Could not reset scheduling policy to SCHED_OTHER for %s", op->id);
        }
    }
#endif
    if (setpriority(PRIO_PROCESS, 0, 0) == -1) {
        crm_perror(LOG_ERR, "Could not reset process priority to 0 for %s", op->id);
    }

    /* Man: The call setpgrp() is equivalent to setpgid(0,0)
     * _and_ compiles on BSD variants too
     * need to investigate if it works the same too.
     */
    setpgid(0, 0);

    /* close all descriptors except stdin/out/err and channels to logd */
    for (lpc = getdtablesize() - 1; lpc > STDERR_FILENO; lpc--) {
        close(lpc);
    }

#if SUPPORT_CIBSECRETS
    if (replace_secret_params(op->rsc, op->params) < 0) {
        /* replacing secrets failed! */
        if (safe_str_eq(op->action,"stop")) {
            /* don't fail on stop! */
            crm_info("proceeding with the stop operation for %s", op->rsc);

        } else {
            crm_err("failed to get secrets for %s, "
                    "considering resource not configured", op->rsc);
            _exit(PCMK_OCF_NOT_CONFIGURED);
        }
    }
#endif
    /* Setup environment correctly */
    add_OCF_env_vars(op);

    /* execute the RA */
    execvp(op->opaque->exec, op->opaque->args);

    /* Most cases should have been already handled by stat() */
    services_handle_exec_error(op, errno);

    _exit(op->rc);
}
Example #2
0
/* 
 * eval - Evaluate the command line that the user has just typed in
 * 
 * If the user has requested a built-in command (quit, jobs, bg or fg)
 * then execute it immediately. Otherwise, fork a child process and
 * run the job in the context of the child. If the job is running in
 * the foreground, wait for it to terminate and then return.  Note:
 * each child process must have a unique process group ID so that our
 * background children don't receive SIGINT (SIGTSTP) from the kernel
 * when we type ctrl-c (ctrl-z) at the keyboard.  
 */
void eval(char *cmdline) 
{
    int bg; /* should the job run in bg or fg? */
    struct cmdline_tokens tok;
	pid_t pid; /* process id of each process */ 
	struct job_t *job;
    sigset_t set;
	sigset_t prev_set;
    int input_fd, output_fd; /* input and output redirect file descriptor */

    /* Parse command line */
    bg = parseline(cmdline, &tok); 

    if (bg == -1) /* parsing error */
        return;

    if (tok.argv[0] == NULL) /* ignore empty lines */
        return;
	
    /*
     * Determine whether the command is builtin command
     * If so, handled by the helper function
     * If not, fork a child process and handle it
     */
    if (!cmd_builtins(&tok)) {

        /*
         * Block signals before the parent add the child into job list to avoid race condition and ensure parent can reap child process
         */
        if (sigemptyset(&set) < 0) {

            unix_error("sigemptyset failed.\n");

        }

        if (sigaddset(&set, SIGINT) || sigaddset(&set, SIGTSTP) || sigaddset(&set, SIGCHLD)) {

            unix_error("sigaddset failed.\n");

        }

        if (sigprocmask(SIG_BLOCK, &set, &prev_set) < 0) {

            unix_error("sigprocmask failed.\n");

        }
		
		/*
         * fork a child process to run the job
         */
        if ((pid = fork()) == 0) {
 			
			/* asign unique group process to each child process 
			 * set the the group id as the process id
             */
            if (setpgid(0, 0) < 0) {

                unix_error("set process group failed.\n");
                return;

            }           
			
			// unblock the signal set for receiving signals 
            if (sigprocmask(SIG_UNBLOCK, &set, &prev_set) < 0) {

                unix_error("sigprocmask failed.\n");

            }

            // redirect the input file descriptor
            if (tok.infile != NULL) {

                input_fd = open(tok.infile, O_RDONLY);

                if (dup2(input_fd, 0) < 0) {

                    unix_error("Failed to restore stdin.\n");

                }

            }

            // redirect the output file descriptor
            if (tok.outfile != NULL) {

                output_fd = open(tok.outfile, O_WRONLY);

                if (dup2(output_fd, 1) < 0) {

                    unix_error("Failed to restore stdout.\n");

                }

            }

			// execute a non-builtin process
			if( execve(tok.argv[0], tok.argv, environ) < 0 ) {
				
				printf("%s: Command not found!\n", tok.argv[0]);
				exit(0);

			}

        }

        // parent process add the child process in the job list
        addjob (job_list, pid, bg ? BG : FG, cmdline);	
		
		/*
         * In the parent process, determine whehter the child process is a foreground process
         * If so, parent process should wait for it
         * If not, leave it as a background job
         */
		if (!bg) {

            while (fgpid(job_list)) {

                sigsuspend(&prev_set); // wait until get the signal that the foreground child process finishes

            }
            		
		 } else {
			
			job = getjobpid(job_list, pid);	
			printf("[%d] (%d) %s\n", job -> jid, job -> pid, cmdline);
			
		 }
	
		 sigprocmask(SIG_UNBLOCK, &set, &prev_set); // unblock the signal set to receive any signals

    }

}
Example #3
0
int setpgrp(void)
{
	return setpgid(0,0);
}
Example #4
0
void do_pipe(char *cmds[MAXCMDS][MAXARGS], int nbcmd, int bg) {

    int fd[2][2], i;
    pid_t pid;

    if (verbose) printf("Entering pipe\n");

    if (verbose) printf("Pipe creation\n");


    if (pipe(fd[0]) == -1) {

      if (verbose) printf("Error in pipe creation\n");
    }

    for (i = 0; i < nbcmd; i++) {

      if (i == 0) {

        switch(pid = fork()) {
          case -1 :

            if (verbose) unix_error("fork cmd 1 error");

          case 0 :
            if (verbose) printf("First son process\n");

            setpgid(0, 0);
            dup2(fd[0][1],STDOUT_FILENO);

            close(fd[0][0]);
            close(fd[0][1]);

            execvp(cmds[0][0],cmds[0]);

            printf("execvp error\n");
            exit(EXIT_FAILURE);

          default :
            if (verbose) printf("Father process\n");
        }
      }

      else if (i > 0 && i < nbcmd -1) {

        switch(pid = fork()) {
          case -1 :
            unix_error("fork cmd 2 error");

          case 0 :

            if (verbose) printf("the %dth process\n",i);

            assert(pipe(fd[i%2]) != -1);

            setpgid(0, pid);
            dup2(fd[(i+1)%2][0], STDIN_FILENO);
            dup2(fd[i%2][1], STDOUT_FILENO);
            close(fd[0][0]);
            close(fd[0][1]);
            close(fd[1][1]);
            close(fd[1][0]);
            execvp(cmds[i][0],cmds[i]);
            printf("execvp 2 error\n");
            exit(EXIT_FAILURE);

          default :

            close(fd[(i+1)%2][0]);
            close(fd[(i+1)%2][1]);
        }
      }

      else {
        switch(pid = fork()) {
          case -1 :
            unix_error("fork cmd 2 error");

          case 0 :
            if (verbose) {
                printf("Last process\n");
            }
            dup2(fd[(i+1)%2][0], STDIN_FILENO);
            close(fd[(i+1)%2][0]);
            close(fd[(i+1)%2][1]);
            execvp(cmds[i][0],cmds[i]);
            printf("execvp 2 error\n");
            exit(EXIT_FAILURE);

          default:

            close(fd[(i+1)%2][0]);
            close(fd[(i+1)%2][1]);
        }
      }

    }

    jobs_addjob(pid, (bg == 1 ? BG : FG), cmds[0][0]);

    if (!bg) {
      if (verbose) printf("pipe waiting fg \n");

      waitfg(pid);
    }

    return;
}
Example #5
0
void
ipmi_start_daemon(struct ipmi_intf *intf)
{
	pid_t pid;
	int fd;
#ifdef SIGHUP
	sigset_t sighup;
#endif

#ifdef SIGHUP
	sigemptyset(&sighup);
	sigaddset(&sighup, SIGHUP);
	if (sigprocmask(SIG_UNBLOCK, &sighup, NULL) < 0)
		fprintf(stderr, "ERROR: could not unblock SIGHUP signal\n");
	signal(SIGHUP, SIG_IGN);
#endif
#ifdef SIGTTOU
	signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
	signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGQUIT
	signal(SIGQUIT, SIG_IGN);
#endif
#ifdef SIGTSTP
	signal(SIGTSTP, SIG_IGN);
#endif

	pid = (pid_t) fork();
	if (pid < 0 || pid > 0)
		exit(0);

#if defined(SIGTSTP) && defined(TIOCNOTTY)
	if (setpgid(0, getpid()) == -1)
		exit(1);
	if ((fd = open(_PATH_TTY, O_RDWR)) >= 0) {
		ioctl(fd, TIOCNOTTY, NULL);
		close(fd);
	}
#else
	if (setpgid(0, 0) == -1)
		exit(1);
	pid = (pid_t) fork();
	if (pid < 0 || pid > 0)
		exit(0);
#endif

	chdir("/");
	umask(0);

	for (fd=0; fd<64; fd++) {
		if (fd != intf->fd)
			close(fd);
	}

	fd = open("/dev/null", O_RDWR);
	assert(0 == fd);
	dup(fd);
	dup(fd);
}
Example #6
0
File: main.c Project: etrunko/ibus
gint
main (gint argc, gchar **argv)
{
    setlocale (LC_ALL, "");

    GOptionContext *context = g_option_context_new ("- ibus daemon");
    g_option_context_add_main_entries (context, entries, "ibus-daemon");

    g_argv = g_strdupv (argv);
    GError *error = NULL;
    if (!g_option_context_parse (context, &argc, &argv, &error)) {
        g_printerr ("Option parsing failed: %s\n", error->message);
	g_error_free (error);
        exit (-1);
    }
    if (g_gdbus_timeout < -1) {
        g_printerr ("Bad timeout (must be >= -1): %d\n", g_gdbus_timeout);
        exit (-1);
    }

    if (g_mempro) {
        g_mem_set_vtable (glib_mem_profiler_table);
        signal (SIGUSR2, _sig_usr2_handler);
    }

    /* check uid */
    {
        const gchar *username = ibus_get_user_name ();
        uid_t uid = getuid ();
        struct passwd *pwd = getpwuid (uid);

        if (pwd == NULL || g_strcmp0 (pwd->pw_name, username) != 0) {
            g_printerr ("Please run ibus-daemon with login user! Do not run ibus-daemon with sudo or su.\n");
            exit (-1);
        }
    }

    /* daemonize process */
    if (daemonize) {
        if (daemon (1, 0) != 0) {
            g_printerr ("Can not daemonize ibus.\n");
            exit (-1);
        }
    }

    /* create a new process group. this is important to kill all of its children by SIGTERM at a time in bus_ibus_impl_destroy. */
    setpgid (0, 0);

    ibus_init ();

    ibus_set_log_handler (g_verbose);

    /* check if ibus-daemon is running in this session */
    if (ibus_get_address () != NULL) {
        IBusBus *bus = ibus_bus_new ();

        if (ibus_bus_is_connected (bus)) {
            if (!replace) {
                g_printerr ("current session already has an ibus-daemon.\n");
                exit (-1);
            }
            ibus_bus_exit (bus, FALSE);
            while (ibus_bus_is_connected (bus)) {
                g_main_context_iteration (NULL, TRUE);
            }
        }
        g_object_unref (bus);
    }

    bus_server_init ();
    if (!single) {
        /* execute config component */
        if (g_strcmp0 (config, "default") == 0) {
            BusComponent *component;
            component = bus_ibus_impl_lookup_component_by_name (
                    BUS_DEFAULT_IBUS, IBUS_SERVICE_CONFIG);
            if (component) {
                bus_component_set_restart (component, restart);
            }
            if (component == NULL || !bus_component_start (component, g_verbose)) {
                g_printerr ("Can not execute default config program\n");
                exit (-1);
            }
        } else if (g_strcmp0 (config, "disable") != 0 && g_strcmp0 (config, "") != 0) {
            if (!execute_cmdline (config))
                exit (-1);
        }

        /* execute panel component */
        if (g_strcmp0 (panel, "default") == 0) {
            BusComponent *component;
            component = bus_ibus_impl_lookup_component_by_name (
                    BUS_DEFAULT_IBUS, IBUS_SERVICE_PANEL);
            if (component) {
                bus_component_set_restart (component, restart);
            }
            if (component == NULL || !bus_component_start (component, g_verbose)) {
                g_printerr ("Can not execute default panel program\n");
                exit (-1);
            }
        } else if (g_strcmp0 (panel, "disable") != 0 && g_strcmp0 (panel, "") != 0) {
            if (!execute_cmdline (panel))
                exit (-1);
        }
    }

    /* execute ibus xim server */
    if (xim) {
        if (!execute_cmdline (LIBEXECDIR "/ibus-x11 --kill-daemon"))
            exit (-1);
    }

    bus_server_run ();
    return 0;
}
Example #7
0
int
main(int argc, char *argv[])
{
	char buf[8192], ptyname[16], *username, *logfile;
	struct utmp utmp;
	struct sigaction act;
	sigset_t set;
	int mfd, sfd;
	ssize_t n;

	if (argc != 3)
		usage();
	username = argv[1];
	logfile = argv[2];

	sigemptyset(&set);
	sigaddset(&set, SIGTERM);
	sigaddset(&set, SIGIO);
	if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
		err(1, "sigprocmask block init");

	if ((lg = fopen(logfile, "w")) == NULL)
		err(1, "fopen %s", logfile);
	if (setlinebuf(lg) != 0)
		err(1, "setlinebuf");

	memset(&act, 0, sizeof(act));
	act.sa_mask = set;
	act.sa_flags = SA_RESTART;
	act.sa_handler = terminate;
	if (sigaction(SIGTERM, &act, NULL) == -1)
		err(1, "sigaction SIGTERM");
	if (sigaction(SIGINT, &act, NULL) == -1)
		err(1, "sigaction SIGINT");

	if (openpty(&mfd, &sfd, ptyname, NULL, NULL) == -1)
		err(1, "openpty");
	fprintf(lg, "openpty %s\n", ptyname);
	if ((tty = strrchr(ptyname, '/')) == NULL)
		errx(1, "tty: %s", ptyname);
	tty++;

	/* login(3) searches for a controlling tty, use the created one */
	if (dup2(sfd, 1) == -1)
		err(1, "dup2 stdout");

	memset(&utmp, 0, sizeof(utmp));
	strlcpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
	strlcpy(utmp.ut_name, username, sizeof(utmp.ut_name));
	time(&utmp.ut_time);
	login(&utmp);
	fprintf(lg, "login %s %s\n", username, tty);

	act.sa_handler = iostdin;
	if (sigaction(SIGIO, &act, NULL) == -1)
		err(1, "sigaction SIGIO");
	if (setpgid(0, 0) == -1)
		err(1, "setpgid");
	if (fcntl(0, F_SETOWN, getpid()) == -1)
		err(1, "fcntl F_SETOWN");
	if (fcntl(0, F_SETFL, O_ASYNC) == -1)
		err(1, "fcntl O_ASYNC");

	act.sa_handler = timeout;
	if (sigaction(SIGALRM, &act, NULL) == -1)
		err(1, "sigaction SIGALRM");
	if (alarm(30) == (unsigned int)-1)
		err(1, "alarm");

	fprintf(lg, "%s: started\n", getprogname());

	if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
		err(1, "sigprocmask unblock init");

	/* do not block signals during read, it has to be interrupted */
	while ((n = read(mfd, buf, sizeof(buf))) > 0) {
		if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
			err(1, "sigprocmask block write");
		fprintf(lg, ">>> ");
		if (fwrite(buf, 1, n, lg) != (size_t)n)
			err(1, "fwrite %s", logfile);
		if (buf[n-1] != '\n')
			fprintf(lg, "\n");
		if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
			err(1, "sigprocmask unblock write");
	}
	if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
		err(1, "sigprocmask block exit");
	if (n < 0)
		err(1, "read %s", ptyname);
	fprintf(lg, "EOF %s\n", ptyname);

	if (logout(tty) == 0)
		errx(1, "logout %s", tty);
	fprintf(lg, "logout %s\n", tty);

	errx(3, "EOF");
}
Example #8
0
int job_start(struct job *j)
{
	struct proc *p;
	struct redir *redir_iter;
	int pipey[2] = { -1, -1 };

#define REDIR(a, b) \
					do{ \
						if(a != b){ \
							/* close b and copy a into b */ \
							if(dup2(a, b) == -1) \
								perror("dup2()"); \
							if(close(a) == -1) \
								perror("close()"); \
						} \
					}while(0)

	for(redir_iter = j->redir; redir_iter; redir_iter = redir_iter->next){
		int fd;

		if(redir_iter->fname){
			fd = open(redir_iter->fname, O_WRONLY | O_CREAT | O_TRUNC); /* FIXME: only out for now - need "<" and ">>" */
			if(fd == -1){
				fprintf(stderr, "ush: open %s: %s\n", redir_iter->fname, strerror(errno));
				/* FIXME: close all other fds */
				return 1;
			}
		}else{
			fd = redir_iter->fd_out;
		}

		fprintf(stderr, "job_start(): REDIR(%d [%s], %d)\n", fd, redir_iter->fname, redir_iter->fd_in);
		REDIR(fd, redir_iter->fd_in);
	}

	j->proc->in = STDIN_FILENO;
	for(p = j->proc; p; p = p->next){
		p->err = STDERR_FILENO;
		if(p->next){
			if(pipe(pipey) < 0){
				perror("pipe()");
				goto bail;
			}
			p->out = pipey[1];
			p->next->in = pipey[0];
		}else{
			p->out = STDOUT_FILENO;
		}

		/* TODO: cd, fg, rehash */

		switch(p->pid = fork()){
			case 0:
				p->pid = getpid();
				REDIR(p->in,   STDIN_FILENO);
				REDIR(p->out, STDOUT_FILENO);
				REDIR(p->err, STDERR_FILENO);
#undef REDIR
				job_close_fds(j, p->next);
				proc_exec(p, j->gid);
				break; /* unreachable */

			case -1:
				perror("fork()");
				goto bail;

			default:
				if(interactive){
					if(!j->gid)
						j->gid = p->pid;
					setpgid(p->pid, j->gid);
				}
				p->state = PROC_RUN;
		}
	}

	/* close our access to all these pipes */
	job_close_fds(j, NULL);

	j->state = JOB_RUNNING;

	return 0;
bail:
	fprintf(stderr, "warning: error starting job: %s\n", strerror(errno));
	for(; p; p = p->next)
		p->state = PROC_FIN;
	job_close_fds(j, NULL);
	job_sig(j, SIGCONT);
	return 1;
}
Example #9
0
void Setpgid(pid_t pid, pid_t pgid) {
	int rc;
	if ((rc = setpgid(pid, pgid)) < 0)
		unix_error("Setpgid error");
	return;
}
Example #10
0
static ATTRIBUTE_NO_SANITIZE_THREAD
void backtrace_sigaction(int signum, siginfo_t *info, void* ptr) {
	void *array[42];
	size_t size;
	void * caller_address;
	ucontext_t *uc = (ucontext_t *) ptr;
	int gdb_pid = -1;

	/* get all entries on the stack */
	size = backtrace(array, 42);

	/* Get the address at the time the signal was raised */
#if defined(REG_RIP)
	caller_address = (void *) uc->uc_mcontext.gregs[REG_RIP];
#elif defined(REG_EIP)
	caller_address = (void *) uc->uc_mcontext.gregs[REG_EIP];
#elif defined(__arm__)
	caller_address = (void *) uc->uc_mcontext.arm_pc;
#elif defined(__mips__)
	caller_address = (void *) uc->uc_mcontext.sc_pc;
#elif defined(REG_PC) && defined(__e2k__)
        caller_address = (void *) ((mcontext_t*) &uc->uc_mcontext)->mc_gregs[REG_PC];
#else /* TODO support more arch(s) */
#	warning Unsupported architecture.
	caller_address = info->si_addr;
#endif

	int should_die = 0;
	switch(info->si_signo) {
	case SIGXCPU:
	case SIGXFSZ:
		should_die = 1;
		break;
	case SIGABRT:
	case SIGALRM:
		if (info->si_pid == getpid())
			should_die = 1;
	case SIGBUS:
	case SIGFPE:
	case SIGILL:
	case SIGSEGV:
#ifndef SI_FROMKERNEL
#	define SI_FROMKERNEL(info) (info->si_code > 0)
#endif
		if (SI_FROMKERNEL(info))
			should_die = 1;
	}

	char time_buf[64];
	time_t t = ldap_time_unsteady();
	strftime(time_buf, sizeof(time_buf), "%F-%H%M%S", localtime(&t));

	char name_buf[PATH_MAX];
	int fd = -1;
#ifdef snprintf
#	undef snprintf
#endif
	if (snprintf(name_buf, sizeof(name_buf), "%s/slapd-backtrace.%s-%i.log%c",
				 backtrace_homedir ? backtrace_homedir : ".", time_buf, getpid(), 0) > 0)
		fd = open(name_buf, O_CREAT | O_EXCL | O_WRONLY | O_APPEND, 0644);

	if (fd < 0) {
		if (backtrace_homedir)
			fd = open(strrchr(name_buf, '/') + 1, O_CREAT | O_EXCL | O_WRONLY | O_APPEND, 0644);
		if (fd < 0)
			fd = STDERR_FILENO;
		dprintf(fd, "\n\n*** Unable create \"%s\": %s!", name_buf, STRERROR(errno));
	}

	dprintf(fd, "\n\n*** Signal %d (%s), address is %p from %p\n", signum, strsignal(signum),
			info->si_addr, (void *)caller_address);

	int n = readlink("/proc/self/exe", name_buf, sizeof(name_buf) - 1);
	if (n > 0) {
		name_buf[n] = 0;
		dprintf(fd, "    Executable file %s\n", name_buf);
	} else {
		dprintf(fd, "    Unable read executable name: %s\n", STRERROR(errno));
		strcpy(name_buf, "unknown");
	}

	void** actual = array;
	int frame = 0;
	for (n = 0; n < size; ++n)
		if (array[n] == caller_address) {
			frame = n;
			actual = array + frame;
			size -= frame;
			break;
		}

	dprintf(fd, "\n*** Backtrace by glibc:\n");
	backtrace_symbols_fd(actual, size, fd);

	int mem_map_fd = open("/proc/self/smaps", O_RDONLY, 0);
	if (mem_map_fd >= 0) {
		char buf[1024];
		dprintf(fd, "\n*** Memory usage map (by /proc/self/smaps):\n");
		while(1) {
			int n = read(mem_map_fd, &buf, sizeof(buf));
			if (n < 1)
				break;
			if (write(fd, &buf, n) != n)
				break;
		}
		close(mem_map_fd);
	}

	/* avoid ECHILD from waitpid() */
	signal(SIGCHLD, SIG_DFL);

	dprintf(fd, "\n*** Backtrace by addr2line:\n");
	for(n = 0; n < size; ++n) {
		int status = EXIT_FAILURE, child_pid = fork();
		if (! child_pid) {
			char addr_buf[64];
			close(STDIN_FILENO);
			dup2(fd, STDOUT_FILENO);
			close(fd);
			dprintf(STDOUT_FILENO, "(%d) %p: ", n, actual[n]);
			sprintf(addr_buf, "%p", actual[n]);
			execlp("addr2line", "addr2line", addr_buf, "-C", "-f", "-i",
#if __GLIBC_PREREQ(2,14)
				"-p", /* LY: not available on RHEL6, guest by glibc version */
#endif
				"-e", name_buf, NULL);
			exit(EXIT_FAILURE);
		} else if (child_pid < 0) {
			dprintf(fd, "\n*** Unable complete backtrace by addr2line, sorry (%s, %d).\n", "fork", errno);
			break;
		} else if (waitpid(child_pid, &status, 0) < 0 || status != W_EXITCODE(EXIT_SUCCESS, 0)) {
			dprintf(fd, "\n*** Unable complete backtrace by addr2line, sorry (%s, pid %d, errno %d, status 0x%x).\n",
				"waitpid", child_pid, errno, status);
			break;
		}
	}

	if (is_debugger_present()) {
		dprintf(fd, "*** debugger already present\n");
		goto ballout;
	}

	int retry_by_return = 0;
	if (should_die && SI_FROMKERNEL(info)) {
		/* LY: Expect kernel kill us again,
		 * therefore for switch to 'guilty' thread and we may just return,
		 * instead of sending SIGTRAP and later switch stack frame by GDB. */
		retry_by_return = 1;
	}

	if (is_valgrind_present()) {
		dprintf(fd, "*** valgrind present, skip backtrace by gdb\n");
		goto ballout;
	}

	int pipe_fd[2];
	if (pipe(pipe_fd)) {
		pipe_fd[0] = pipe_fd[1] = -1;
		goto ballout;
	}

	gdb_is_ready_for_backtrace = 0;
	pid_t tid = syscall(SYS_gettid);
	gdb_pid = fork();
	if (!gdb_pid) {
		char pid_buf[16];
		sprintf(pid_buf, "%d", getppid());

		dup2(pipe_fd[0], STDIN_FILENO);
		close(pipe_fd[1]);
		pipe_fd[0] = pipe_fd[1] =-1;
		dup2(fd, STDOUT_FILENO);
		dup2(fd, STDERR_FILENO);
		for(fd = getdtablesize(); fd > STDERR_FILENO; --fd)
			close(fd);
		setsid();
		setpgid(0, 0);

		dprintf(STDOUT_FILENO, "\n*** Backtrace by GDB "
#if GDB_SWITCH2GUILTY_THREAD
			"(pid %s, LWP %i, frame #%d):\n", pid_buf, tid, frame);
#else
			"(pid %s, LWP %i, please find frame manually):\n", pid_buf, tid);
#endif
		execlp("gdb", "gdb", "-q", "-se", name_buf, "-n", NULL);
		kill(getppid(), SIGKILL);
		dprintf(STDOUT_FILENO, "\n*** Sorry, GDB launch failed: %s\n", STRERROR(errno));
		fsync(STDOUT_FILENO);
		exit(EXIT_FAILURE);
	}
Example #11
0
static char *feh_magick_load_image(char *filename)
{
	char argv_fd[12];
	char *basename;
	char *tmpname;
	char *sfn;
	int fd = -1, devnull = -1;
	int status;

	if (opt.magick_timeout < 0)
		return NULL;

	basename = strrchr(filename, '/');

	if (basename == NULL)
		basename = filename;
	else
		basename++;

	tmpname = feh_unique_filename("/tmp/", basename);

	if (strlen(tmpname) > (NAME_MAX-6))
		tmpname[NAME_MAX-7] = '\0';

	sfn = estrjoin("_", tmpname, "XXXXXX", NULL);
	free(tmpname);

	fd = mkstemp(sfn);

	if (fd == -1)
		return NULL;

	snprintf(argv_fd, sizeof(argv_fd), "png:fd:%d", fd);

	if ((childpid = fork()) == 0) {

		/* discard convert output */
		devnull = open("/dev/null", O_WRONLY);
		dup2(devnull, 0);
		dup2(devnull, 1);
		dup2(devnull, 2);

		/*
		 * convert only accepts SIGINT via killpg, a normal kill doesn't work
		 */
		setpgid(0, 0);

		execlp("convert", "convert", filename, argv_fd, NULL);
		exit(1);
	}
	else {
		alarm(opt.magick_timeout);
		waitpid(childpid, &status, 0);
		alarm(0);
		if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
			close(fd);
			unlink(sfn);
			free(sfn);
			sfn = NULL;

			if (!opt.quiet) {
				if (WIFSIGNALED(status))
					weprintf("%s - Conversion took too long, skipping",
						filename);
			}

			/*
			 * Reap child.  The previous waitpid call was interrupted by
			 * alarm, but convert doesn't terminate immediately.
			 * XXX
			 * normally, if (WIFSIGNALED(status)) waitpid(childpid, &status, 0);
			 * would suffice. However, as soon as feh has its own window,
			 * this doesn't work anymore and the following workaround is
			 * required. Hm.
			 */
			waitpid(-1, &status, 0);
		}
		childpid = 0;
	}

	return sfn;
}
Example #12
0
/* 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;
}
Example #13
0
void
forkchild(struct job *jp, union node *n, int mode, int vforked)
{
	int wasroot;
#if JOBS /* LSC: for proper compilation with JOBS == 0 */
	int pgrp;
#endif
	const char *devnull = _PATH_DEVNULL;
	const char *nullerr = "Can't open %s";

	wasroot = rootshell;
	TRACE(("Child shell %d\n", getpid()));
	if (!vforked)
		rootshell = 0;

	closescript(vforked);
	clear_traps(vforked);
#if JOBS
	if (!vforked)
		jobctl = 0;		/* do job control only in root shell */
	if (wasroot && mode != FORK_NOJOB && mflag) {
		if (jp == NULL || jp->nprocs == 0)
			pgrp = getpid();
		else
			pgrp = jp->ps[0].pid;
		/* This can fail because we are doing it in the parent also */
		(void)setpgid(0, pgrp);
		if (mode == FORK_FG) {
			if (tcsetpgrp(ttyfd, pgrp) == -1)
				error("Cannot set tty process group (%s) at %d",
				    strerror(errno), __LINE__);
		}
		setsignal(SIGTSTP, vforked);
		setsignal(SIGTTOU, vforked);
	} else if (mode == FORK_BG) {
		ignoresig(SIGINT, vforked);
		ignoresig(SIGQUIT, vforked);
		if ((jp == NULL || jp->nprocs == 0) &&
		    ! fd0_redirected_p ()) {
			close(0);
			if (open(devnull, O_RDONLY) != 0)
				error(nullerr, devnull);
		}
	}
#else
	if (mode == FORK_BG) {
		ignoresig(SIGINT, vforked);
		ignoresig(SIGQUIT, vforked);
		if ((jp == NULL || jp->nprocs == 0) &&
		    ! fd0_redirected_p ()) {
			close(0);
			if (open(devnull, O_RDONLY) != 0)
				error(nullerr, devnull);
		}
	}
#endif
	if (wasroot && iflag) {
		setsignal(SIGINT, vforked);
		setsignal(SIGQUIT, vforked);
		setsignal(SIGTERM, vforked);
	}

	if (!vforked)
		jobs_invalid = 1;
}
Example #14
0
/*
 * Turn job control on and off.
 *
 * Note:  This code assumes that the third arg to ioctl is a character
 * pointer, which is true on Berkeley systems but not System V.  Since
 * System V doesn't have job control yet, this isn't a problem now.
 */

MKINIT int jobctl;

#if JOBS /* Minix setjobctl is defined to empty, compilation error */
void
setjobctl(int on)
{
#ifdef OLD_TTY_DRIVER
	int ldisc;
#endif

	if (on == jobctl || rootshell == 0)
		return;
	if (on) {
#if defined(FIOCLEX) || defined(FD_CLOEXEC)
		int err;
		int i;
		if (ttyfd != -1)
			close(ttyfd);
		if ((ttyfd = open("/dev/tty", O_RDWR)) == -1) {
			for (i = 0; i < 3; i++) {
				if (isatty(i) && (ttyfd = dup(i)) != -1)
					break;
			}
			if (i == 3)
				goto out;
		}
		/* Move to a high fd */
		for (i = 10; i > 2; i--) {
			if ((err = fcntl(ttyfd, F_DUPFD, (1 << i) - 1)) != -1)
				break;
		}
		if (err != -1) {
			close(ttyfd);
			ttyfd = err;
		}
#ifdef FIOCLEX
		err = ioctl(ttyfd, FIOCLEX, 0);
#elif FD_CLOEXEC
		err = fcntl(ttyfd, F_SETFD,
		    fcntl(ttyfd, F_GETFD, 0) | FD_CLOEXEC);
#endif
		if (err == -1) {
			close(ttyfd);
			ttyfd = -1;
			goto out;
		}
#else
		out2str("sh: Need FIOCLEX or FD_CLOEXEC to support job control");
		goto out;
#endif
		do { /* while we are in the background */
			if ((initialpgrp = tcgetpgrp(ttyfd)) < 0) {
out:
				out2str("sh: can't access tty; job control turned off\n");
				mflag = 0;
				return;
			}
			if (initialpgrp == -1)
				initialpgrp = getpgrp();
			else if (initialpgrp != getpgrp()) {
				killpg(0, SIGTTIN);
				continue;
			}
		} while (0);

#ifdef OLD_TTY_DRIVER
		if (ioctl(ttyfd, TIOCGETD, (char *)&ldisc) < 0
		    || ldisc != NTTYDISC) {
			out2str("sh: need new tty driver to run job control; job control turned off\n");
			mflag = 0;
			return;
		}
#endif
		setsignal(SIGTSTP, 0);
		setsignal(SIGTTOU, 0);
		setsignal(SIGTTIN, 0);
		if (getpgrp() != rootpid && setpgid(0, rootpid) == -1)
			error("Cannot set process group (%s) at %d",
			    strerror(errno), __LINE__);
		if (tcsetpgrp(ttyfd, rootpid) == -1)
			error("Cannot set tty process group (%s) at %d",
			    strerror(errno), __LINE__);
	} else { /* turning job control off */
		if (getpgrp() != initialpgrp && setpgid(0, initialpgrp) == -1)
			error("Cannot set process group (%s) at %d",
			    strerror(errno), __LINE__);
		if (tcsetpgrp(ttyfd, initialpgrp) == -1)
			error("Cannot set tty process group (%s) at %d",
			    strerror(errno), __LINE__);
		close(ttyfd);
		ttyfd = -1;
		setsignal(SIGTSTP, 0);
		setsignal(SIGTTOU, 0);
		setsignal(SIGTTIN, 0);
	}
	jobctl = on;
}
Example #15
0
static int miscd_dodaemon(char *argv1, char *daemon)
{
    struct sigaction act;
    char *commandline;
    char commbuf[10];
    char ch;

	if (!check_file_writable(PASSFILE))
	{
		fprintf(stderr, "Error! File %s is not writable.\n", PASSFILE);
		exit(-1);
	}
	if (!check_file_writable(BOARDS))
	{
		fprintf(stderr, "Error! File %s is not writable.\n", BOARDS);
		exit(-1);
	}
	truncate(BOARDS, MAXBOARD * sizeof(struct boardheader));

    if (load_ucache() != 0) {
        printf("ft,load ucache error!");
        exit(-1);
    }

    /* init tmpfs */
    sprintf(genbuf1,"%s/home",TMPFSROOT);
    mkdir(genbuf1,0700);
    sprintf(genbuf1,"%s/boards",TMPFSROOT);
    mkdir(genbuf1,0700);
    for (ch='A';ch<='Z';ch++) {
    sprintf(genbuf1,"%s/home/%c",TMPFSROOT,ch);
    mkdir(genbuf1,0700);
    }

    resolve_boards();
    resolve_utmp();
    resolve_guest_table();

    if (argv1 != NULL) {
        switch (fork()) {
        case -1:
            printf("faint, i can't fork.\n");
            exit(0);
            break;
        case 0:
            break;
        default:
            exit(0);
            break;
        }
        commandline = argv1;
    } else {
        commandline = commbuf;
    }
    setsid();
#ifdef AIX
    setpgrp();
#elif defined FREEBSD
    setpgid(0, 0);
#else
    // by zixia setpgrp(0, 0);
    setpgrp();
#endif
#ifdef AIX
    act.sa_handler = NULL;
    act.sa_flags = SA_RESTART | SA_NOCLDWAIT;
    sigaction(SIGCHLD, &act, NULL);
#else
    act.sa_handler = reaper;
    act.sa_flags = SA_RESTART;
    sigaction(SIGCHLD, &act, NULL);
#endif
    if (((daemon == NULL) || (!strcmp(daemon, "timed"))) && ((argv1 == NULL) || fork())) {
        strcpy(commandline, "timed");
        timed();
        exit(0);
    }

    if (((daemon == NULL) || (!strcmp(daemon, "killd"))) && ((argv1 == NULL) || fork())) {
        strcpy(commandline, "killd");
        while (1) {
            time_t ft;

            ft = getnextday4am();
            do {
                sleep(ft - time(0));
            } while (ft > time(0));

            if (argv1 == NULL) {
                dokilluser();
                //doupdategiveupuser();
            } else {
                switch (fork()) {
                case -1:
                    bbslog("3error", "fork failed\n");
                    break;
                case 0:
                    dokilluser();
                    //doupdategiveupuser();
                    exit(0);
                    break;
                default:
                    break;
                }
            }
            switch (fork()) {
                case -1:
                    bbslog("3error", "fork failed\n");
                    break;
                case 0:
                    dokillalldir();
                    exit(0);
                    break;
                default:
                    break;
            }
        };
        exit(0);
    }
    if (((daemon == NULL) || (!strcmp(daemon, "userd"))) && ((argv1 == NULL) || fork())) {
        strcpy(commandline, "userd");
        userd();
        exit(0);
    }
    if ((daemon == NULL) || (!strcmp(daemon, "flushd"))) {
        strcpy(commandline, "flushd");
        flushd();
        exit(0);
    }
    return 0;
}