Esempio n. 1
0
void reattach_tty(char *tty, char *password)
{
int s = -1;
char *name;
struct sockaddr_in addr;
struct hostent *hp;
int len = 0;
fd_set rd_fd;
struct timeval tm = {0};
char chr_c[] = "\003";

/* 
 * this buffer has to be big enough to handle a full screen of 
 * information from the detached process.
 */
unsigned char buffer[6 * BIG_BUFFER_SIZE+1];
char *p;
int port = 0;
#if defined (TIOCGWINSZ)
struct winsize window;
#endif
	memset(&parm, 0, sizeof(struct param));

	if (!(name = find_detach_socket(socket_path, tty)))
	{
		fprintf(stderr, "No detached process to attach too\r\n");
		_exit(1);
	}

	strcpy(parm.cookie, get_cookie(name));
	if (!*parm.cookie)
		_exit(1);
	if ((p = strrchr(name, '/')))
		p++;
	sscanf(p, "%d.%*s.%*s", &port);
	displays = 1;
	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		displays = 0;
		_exit(1);
	}

	chmod(name, SOCKMODE);
	set_socket_options(s);
	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_port = htons(port);
	addr.sin_family = AF_INET;
	if((hp = gethostbyname("localhost")))
		memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
	else
		inet_aton("127.0.0.1", (struct in_addr *)&addr.sin_addr);
	if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{
		fprintf(stderr, "connection refused for %s\r\n", name);
		_exit(1);
	}

	parm.pid = getpid();
	parm.pgrp = getpgrp();
	parm.uid = getuid();
	strcpy(parm.tty, ttyname(0));
	strncpy(parm.termid, getenv("TERM"), 80);
	if (password) 
		strncpy(parm.password, password, 60);
	fprintf(stderr, "attempting to wakeup %s\r\n", find_tty_name(name));
#if defined (TIOCGWINSZ)
	if (ioctl(0, TIOCGWINSZ, &window) > -1)
	{
		parm.cols = window.ws_col;
		parm.rows = window.ws_row;
	}
	else
#endif
	{
		parm.cols = 79;
		parm.rows = 25;
	}
	write(s, &parm, sizeof(struct param));	
	sleep(2);
	alarm(15);
	len = read(s, &parm, sizeof(struct param));
	alarm(0);
	if (len <= 0)
	{
		fprintf(stderr, "error reconnecting to %s\r\n", find_tty_name(name));
		displays = 0;
		chmod(name, SOCKMODE);
		exit(1);
	}
	unlink(name);

	term_init(parm.termid);
	set_term_eight_bit(1);
	charset_ibmpc();
	term_clear_screen();
	term_resize();
	term_move_cursor(0,0);

	my_signal(SIGPIPE, handle_pipe, 0);
	my_signal(SIGINT,  handle_ctrlc, 0);
	my_signal(SIGHUP,  handle_hup, 0);

	/*
	 * according to MHacker we need to set errno to 0 under BSD.
	 * for some reason we get a address in use from a socket 
	 *
	 */
	errno = 0;
	while (1)
	{
		FD_ZERO(&rd_fd);
		FD_SET(0, &rd_fd);
		FD_SET(s, &rd_fd);
		tm.tv_sec = 2;
		
		switch(select(s+1, &rd_fd, NULL, NULL, &tm))
		{
			case -1:
				if (ctrl_c)
				{
					write(s, chr_c, 1);
					ctrl_c = 0;
				}
				else if (errno != EINTR)
				{
					close(s);
					_exit(1);
				}
				break;
			case 0:
				break;
			default:
			{
				if (FD_ISSET(0, &rd_fd))
				{
					len = read(0, buffer, sizeof(buffer)-1);
					write(s, buffer, len);
				}
				if (FD_ISSET(s, &rd_fd))
				{
					len = read(s, buffer, sizeof(buffer)-1);
					write(1, buffer, len);
				}
			}
		}
	}
	close(s);
	fprintf(stderr, "Never should have got here");
	_exit(1);			 

	return; /* error return */
}
Esempio n. 2
0
static void
tstp(int dummy GCC_UNUSED)
{
    SCREEN *sp = CURRENT_SCREEN;
    sigset_t mask, omask;
    sigaction_t act, oact;

#ifdef SIGTTOU
    int sigttou_blocked;
#endif

    T(("tstp() called"));

    /*
     * The user may have changed the prog_mode tty bits, so save them.
     *
     * But first try to detect whether we still are in the foreground
     * process group - if not, an interactive shell may already have
     * taken ownership of the tty and modified the settings when our
     * parent was stopped before us, and we would likely pick up the
     * settings already modified by the shell.
     */
    if (sp != 0 && !sp->_endwin)	/* don't do this if we're not in curses */
#if HAVE_TCGETPGRP
	if (tcgetpgrp(STDIN_FILENO) == getpgrp())
#endif
	    NCURSES_SP_NAME(def_prog_mode) (NCURSES_SP_ARG);

    /*
     * Block window change and timer signals.  The latter
     * is because applications use timers to decide when
     * to repaint the screen.
     */
    (void) sigemptyset(&mask);
#ifdef SIGALRM
    (void) sigaddset(&mask, SIGALRM);
#endif
#if USE_SIGWINCH
    (void) sigaddset(&mask, SIGWINCH);
#endif
    (void) sigprocmask(SIG_BLOCK, &mask, &omask);

#ifdef SIGTTOU
    sigttou_blocked = sigismember(&omask, SIGTTOU);
    if (!sigttou_blocked) {
	(void) sigemptyset(&mask);
	(void) sigaddset(&mask, SIGTTOU);
	(void) sigprocmask(SIG_BLOCK, &mask, NULL);
    }
#endif

    /*
     * End window mode, which also resets the terminal state to the
     * original (pre-curses) modes.
     */
    NCURSES_SP_NAME(endwin) (NCURSES_SP_ARG);

    /* Unblock SIGTSTP. */
    (void) sigemptyset(&mask);
    (void) sigaddset(&mask, SIGTSTP);
#ifdef SIGTTOU
    if (!sigttou_blocked) {
	/* Unblock this too if it wasn't blocked on entry */
	(void) sigaddset(&mask, SIGTTOU);
    }
#endif
    (void) sigprocmask(SIG_UNBLOCK, &mask, NULL);

    /* Now we want to resend SIGSTP to this process and suspend it */
    act.sa_handler = SIG_DFL;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
#ifdef SA_RESTART
    act.sa_flags |= SA_RESTART;
#endif /* SA_RESTART */
    sigaction(SIGTSTP, &act, &oact);
    kill(getpid(), SIGTSTP);

    /* Process gets suspended...time passes...process resumes */

    T(("SIGCONT received"));
    sigaction(SIGTSTP, &oact, NULL);
    NCURSES_SP_NAME(flushinp) (NCURSES_SP_ARG);

    /*
     * If the user modified the tty state while suspended, he wants
     * those changes to stick.  So save the new "default" terminal state.
     */
    NCURSES_SP_NAME(def_shell_mode) (NCURSES_SP_ARG);

    /*
     * This relies on the fact that doupdate() will restore the
     * program-mode tty state, and issue enter_ca_mode if need be.
     */
    NCURSES_SP_NAME(doupdate) (NCURSES_SP_ARG);

    /* Reset the signals. */
    (void) sigprocmask(SIG_SETMASK, &omask, NULL);
}
Esempio n. 3
0
void UnistdGetpgrp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
    ReturnValue->Val->Integer = getpgrp();
}
Esempio n. 4
0
static void
background(void)
{
    /*
     * A process is a process group leader if its process ID
     * (getpid()) and its process group ID (getpgrp()) are the same.
     */

    /*
     * To create a new session (and thereby lose our controlling
     * terminal) we cannot be a process group leader.
     *
     * To guarantee we are not a process group leader, we fork and
     * let the parent process exit.
     */

    if (getpid() == getpgrp()) {
	pid_t pid;
	pid = fork();
	switch (pid) {
	case -1:
	    abort();		/* leave footprints */
	    break;
	case 0:		/* child */
	    break;
	default:		/* parent */
	    exit(0);
	    break;
	}
    }

    /*
     * By here, we are not a process group leader, so we can make a
     * new session and become the session leader.
     */

    {
	pid_t sid = setsid();

	if (sid == -1) {
	    static char err[] = "bosserver: WARNING: setsid() failed\n";
	    write(STDERR_FILENO, err, sizeof err - 1);
	}
    }

    /*
     * Once we create a new session, the current process is a
     * session leader without a controlling tty.
     *
     * On some systems, the first tty device the session leader
     * opens automatically becomes the controlling tty for the
     * session.
     *
     * So, to guarantee we do not acquire a controlling tty, we fork
     * and let the parent process exit.  The child process is not a
     * session leader, and so it will not acquire a controlling tty
     * even if it should happen to open a tty device.
     */

    if (getpid() == getpgrp()) {
	pid_t pid;
	pid = fork();
	switch (pid) {
	case -1:
	    abort();		/* leave footprints */
	    break;
	case 0:		/* child */
	    break;
	default:		/* parent */
	    exit(0);
	    break;
	}
    }

    /*
     * check that we no longer have a controlling tty
     */

    {
	int fd;

	fd = open("/dev/tty", O_RDONLY);

	if (fd >= 0) {
	    static char err[] =
		"bosserver: WARNING: /dev/tty still attached\n";
	    close(fd);
	    write(STDERR_FILENO, err, sizeof err - 1);
	}
    }
}
Esempio n. 5
0
void usage()
{
	fprintf(stderr,"Usage:\n\t%s cmd1 [arg1...] = cmd2 [arg2...]\n\n",progname);
	kill(getpgrp(),SIGTERM);
	exit (-1);
}
extern int 
main(int argc, char **argv)
{
  char req_buf[COMM_BUF_SIZE], resp_buf[COMM_BUF_SIZE];
                                /* The character string buffers passed from
				   and to client programs. The strings follow
				   a format defined in atm.h and the parameters
				   are read in and out using sptring processing
				   calls sprintf() and sscanf(). */
  int  conn;                    /* A handle on which connection (client)
                                   the request came from. Not used initially
                                   but included so that in the future different
				   requests could be processed cuncurrently. */
  int  trans_id;                /* The transaction type of the current 
				   request */
  int  done=0;

  DPRINTF(("SERVER: main() pid %d, ppid %d, pgrp %d\n",getpid(), getppid(), getpgrp()));

  atm_server_init(argc, argv);

  for(;;) {

    server_comm_get_request(&conn, req_buf);
    sscanf(req_buf, "%d", &trans_id);

    DPRINTF(("SERVER: main(), request received\n"));

    switch(trans_id) {

      case OPEN_ACCT_TRANS:
           open_account(resp_buf);
           break;

      case DEPOSIT_TRANS:
	   deposit(req_buf, resp_buf);
	   break;

      case WITHDRAW_TRANS:
	   withdraw(req_buf, resp_buf);
	   break;

      case BALANCE_TRANS:
	   balance(req_buf, resp_buf);
	   break;

      case SHUTDOWN:
	   if (shutdown_req(req_buf, resp_buf)) done = 1;
	   break;
      
      default: 
	   handle_bad_trans_id(req_buf, resp_buf);
	   break;

      }		

    server_comm_send_response(conn, resp_buf);
    
    DPRINTF(("SERVER: main(), response sent\n"));
    
    if(done) break;
    
  }

  DPRINTF(("SERVER: main(), shuting down\n"));

  server_comm_shutdown();

  return 0; 
}
Esempio n. 7
0
int main(int argc, char *argv[]) {
    int c;
    int fd;
    char path[PATH_MAX];
    int pid;
    int detach = 0;
    int netns = 0;
    int mountns = 0;
    int mountnspid = 0;
    int pidns = 0;
    int printpid = 0;
    int mountprocfs = 0;
    static struct sched_param sp;
    while ((c = getopt(argc, argv, "+cdnmiufpa:b:k:j:g:r:vh")) != -1)
        switch (c) {
        case 'c':
            /* close file descriptors except stdin/out/error */
            for (fd = getdtablesize(); fd > 2; fd--)
                close(fd);
            break;
        case 'd':
            /* detach from tty */
            detach = 1; /* delay setsid() incase new PID namespace */
            break;
        case 'n':
            /* run in network namespace */
            if (unshare(CLONE_NEWNET) == -1) {
                perror("unshare");
                return 1;
            }
            netns = NET_NS_CREATE;
            break;
        case 'm':
            /* run in mount namespace */
            if (unshare(CLONE_NEWNS) == -1) {
                perror("unshare");
                return 1;
            }
            /* mount sysfs to pick up the new network namespace */
            mountns = MOUNT_NS_CREATE; /* delay mount of /sysfs */
            break;
        case 'i':
            /* run in new PID namespace */
            if (unshare(CLONE_NEWPID) == -1) {
                perror("unshare");
                return 1;
            }
            pidns = PID_NS_CREATE; /* record creation of PID namespace */
            break;
        case 'u':
            /* run in new UTS namespace */
            if (unshare(CLONE_NEWUTS) == -1) {
                perror("unshare");
                return 1;
            }
            break;
        case 'f':
            /* mount procfs (for new PID namespaces) */
            mountprocfs = TRUE; /* delay mounting proc until new NS established */
            break;
        case 'p':
            /* print pid */
            printpid = TRUE; /* delay printing PID until after NS procesisng*/
            break;
        case 'a':
            /* Attach to pid's network namespace */
            pid = atoi(optarg);
            sprintf(path, "/proc/%d/ns/net", pid);
            if (attachToNS(path) != 0) {
                return 1;
            }
            netns = NET_NS_JOIN;
            break;
        case 'b':
            /* Attach to pid's mount namespace */
            mountns = MOUNT_NS_JOIN; /* delay joining mount namespace */
            mountnspid = atoi(optarg); /* record PID to join */
            break;
        case 'k':
            /* Attach to pid's PID namespace */
            pid = atoi(optarg);
            sprintf(path, "/proc/%d/ns/pid", pid);
            if (attachToNS(path) != 0) {
                return 1;
            }
            pidns = PID_NS_JOIN; /* record join of PID namespace */
            break;
        case 'j':
            /* Attach to pid's UTS namespace */
            pid = atoi(optarg);
            sprintf(path, "/proc/%d/ns/uts", pid);
            if (attachToNS(path) != 0) {
                return 1;
            }
            break;
        case 'g':
            /* Attach to cgroup */
            cgroup(optarg);
            break;
        case 'r':
            /* Set RT scheduling priority */
            sp.sched_priority = atoi(optarg);
            if (sched_setscheduler(getpid(), SCHED_RR, &sp) < 0) {
                perror("sched_setscheduler");
                return 1;
            }
            break;
        case 'v':
            printf("%s\n", VERSION);
            exit(0);
        case 'h':
            usage(argv[0]);
            exit(0);
        default:
            usage(argv[0]);
            exit(1);
        }

    /* fork to create / join PID namespace */
    if (pidns == PID_NS_CREATE || pidns == PID_NS_JOIN) {
        int status = 0;
        pid_t pid = fork();
        switch (pid) {
        case -1:
            perror("fork");
            return 1;
        case 0: /* child */
            break;
        default: /* parent */
            /* print global PID (not namespace PID)*/
            if (printpid == 1) {
                printf("\001%d\n", pid);
                fflush(stdout);
            }
            /* wait on the PID to handle attachment for 'mx'*/
            if (waitpid(pid, &status, 0) == -1)
                return 1;
            if (WIFEXITED(status))
                /* caught child exit, forward return code*/
                return WEXITSTATUS(status);
            else if (WIFSIGNALED(status))
                kill(getpid(), WTERMSIG(status));
            /* child exit failed, (although return won't distinguish) */
            return 1;
        }
    }

    /* if requested, we are in the new/requested PID namespace */
    /* completed performing other namespaces (PID/network) operations */

    /* go ahead and join the mount namespace if requested */
    if (mountns == MOUNT_NS_JOIN && mountnspid != FALSE) {
        sprintf(path, "/proc/%d/ns/mnt", pid);
        if (attachToNS(path) != 0) {
            return 1;
        }
    }

    /* if mount of procfs requested, check for pidns and mountns */
    if (mountprocfs && (pidns != PID_NS_CREATE || mountns != MOUNT_NS_CREATE)) {
        /* requested procfs, but required PID and/or mount namespace missing  */
        return 1;
    }

    /* mount procfs to pick up the new PID namespace */
    if (mountprocfs
            && (mount("none", "/proc", NULL, MS_PRIVATE | MS_REC, NULL) != 0
                    || mount("proc", "/proc", "proc",
                            MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL) != 0)) {
        perror("mount");
    }

    /* mount sysfs to pick up the new PID namespace */
    if (netns == NET_NS_CREATE && mountns == MOUNT_NS_CREATE) {
        if (mount("sysfs", "/sys", "sysfs", MS_MGC_VAL, NULL) == -1) {
            perror("mount");
            return 1;
        }
    }

    /* setsid() if requested & required (not needed if using PID namespace) */
    if (detach == 1 && pidns == FALSE) {
        if (getpgrp() == getpid()) {
            switch (fork()) {
            case -1:
                perror("fork");
                return 1;
            case 0: /* child */
                break;
            default: /* parent */
                return 0;
            }
        }
        setsid();
    }

    /* print pid if requested (if in new namespace, we don't print local PID) */
    if (printpid == 1 && pidns == 0) {
        printf("\001%d\n", getpid());
        fflush(stdout);
    }

    /* launch if requested */
    if (optind < argc) {
        execvp(argv[optind], &argv[optind]);
        perror(argv[optind]);
        return 1;
    }

    usage(argv[0]);

    return 0;
}
Esempio n. 8
0
void setosjobid(pid_t sid, gid_t *add_grp_id_ptr, struct passwd *pw)
{
   FILE *fp=NULL;

   shepherd_trace("setosjobid: uid = "pid_t_fmt", euid = "pid_t_fmt, getuid(), geteuid());

#  if defined(SOLARIS) || defined(ALPHA) || defined(LINUX) || defined(FREEBSD) || defined(DARWIN)
      /* Read SgeId from config-File and create Addgrpid-File */
      {  
         char *cp;
         if ((cp = search_conf_val("add_grp_id")))
            *add_grp_id_ptr = atol(cp);
         else
            *add_grp_id_ptr = 0;
      }
      if ((fp = fopen("addgrpid", "w")) == NULL) {
         shepherd_error(1, "can't open \"addgrpid\" file");   
      }
      fprintf(fp, gid_t_fmt"\n", *add_grp_id_ptr);
      FCLOSE(fp);   
# elif defined(HP1164) || defined(AIX)
    {
      if ((fp = fopen("addgrpid", "w")) == NULL) {
         shepherd_error(1, "can't open \"addgrpid\" file");
      }
      fprintf(fp, pid_t_fmt"\n", getpgrp());
      FCLOSE(fp);
    }
#  else
   {
      char osjobid[100];
      if ((fp = fopen("osjobid", "w")) == NULL) {
         shepherd_error(1, "can't open \"osjobid\" file");
      }

      if(sge_switch2start_user() == 0) {
#     if defined(IRIX)
      {
         /* The following block contains the operations necessary for
          * IRIX6.2 (and later) to set array session handles (ASHs) and
          * service provider info (SPI) records
          */
         struct acct_spi spi;
         int ret;
         char *cp;

         shepherd_trace("in irix code");
         /* get _local_ array session id */
         if ((ret=newarraysess())) {
            shepherd_error(1, "error: can't create ASH; errno=%d", ret);
         }

         /* retrieve array session id we just assigned to the process and
          * write it to the os-jobid file
          */
         sprintf(osjobid, "%lld", getash());
         shepherd_trace(osjobid); 
         /* set service provider information (spi) record */
         strncpy(spi.spi_company, "SGE", 8);
         strncpy(spi.spi_initiator, get_conf_val("spi_initiator"), 8);
         strncpy(spi.spi_origin, get_conf_val("queue"),16);
         strcpy(spi.spi_spi, "Job ");
         strncat(spi.spi_spi, get_conf_val("job_id"),11);
         if ((ret=setspinfo(&spi))) {
            shepherd_error(1, "error: can't set SPI; errno=%d", ret);
         }
         
         if ((cp = search_conf_val("acct_project"))) {
            prid_t proj; 
            if (strcasecmp(cp, "none") && ((proj = projid(cp)) >= 0)) {
               shepherd_trace("setting project \"%s\" to id %lld", cp, proj);
               if (setprid(proj) == -1)
                  shepherd_trace("failed setting project id");
            }
            else {   
               shepherd_trace("can't get id for project \"%s\"", cp);
            }
         } else {
            shepherd_trace("can't get configuration entry for projects");
         }
      }
#     elif defined(CRAY)
      {
         char *cp;
	      {
	         int jobid;

	         if ((jobid=setjob(pw->pw_uid, 0)) < 0) {
	            shepherd_error(1, "error: can't set job ID; errno = %d", errno);
	         }

	         if (sesscntl(jobid, S_ADDFL, S_BATCH) == -1) {
	            shepherd_error(1, "error: sesscntl(%d, S_ADDFL, S_BATCH) failed,"
		                        " errno = %d", sid, errno);
	         } 
	         sprintf(osjobid, "%d", jobid);
	      }

	      if ((cp = search_conf_val("acct_project"))) {
	         int proj; 
	         if (strcasecmp(cp, "none") && ((proj = nam2acid(cp)) >= 0)) {
	            shephed_trace("setting project \"%s\" to acid %d", cp, proj);
	            if (acctid(0, proj) == -1) {
		            shepherd_trace("failed setting project id (acctid)");
               }
	         } else {   
	            shepherd_trace("can't get id for project \"%s\"", cp);
	         }
	      } else {
	         shepherd_trace("can't get configuration entry for projects");
         }
      }
#     elif defined(NECSX4) || defined(NECSX5)
      {
         id_t jobid = 0;
		 	dispset2_t attr;	
			int value;

         /*
          * Create new Super-UX job
          */
         if (setjid() == -1) {
            shepherd_trace("ERROR: can't set jobid: %s[%d]", strerror(errno), errno);
         } else {
            jobid = getjid(0);
            shepherd_trace("Created job with id: "sge_u32, (u_long32) jobid);
         }  
         sprintf(osjobid, sge_u32, (u_long32) jobid); 

         /*
          * We will use limits for the whole job
          */
         set_rlimits_os_job_id(jobid);

         /*
          * The job will use the resources of the configured 
          * Resource Sharing Group (rsg)
          */ 
         {
            char *rsg_id_string;
            int rsg_id;
            char fsg_dev_string[256];

            rsg_id_string  = get_conf_val("processors");
            rsg_id = atoi(rsg_id_string);
            if (rsg_id) {
               int fd;

               sprintf(fsg_dev_string, "/dev/rsg/%d", rsg_id);
               fd = open(fsg_dev_string, O_RDONLY);
               if (fd <= 0) {
                  shepherd_trace("ERROR: can't switch to rsg%d because can't open"
                                 "device: %s[%d]", rsg_id, strerror(errno), errno);
               } else {
                  if (ioctl(fd, RSG_JUMP, NULL) == -1) {
                     close(fd);
                     shepherd_trace("ERROR: can't switch to rsg%d: %s[%d]", 
                                    rsg_id, strerror(errno), errno);
                     return;
                  } else {
                     close(fd);
                     shepherd_trace("switched to rsg%d", rsg_id);
                  }
               }
            } else {
               shepherd_trace("using default rsg", rsg_id);
            }
         } 

         /*
          * Set scheduling parameter for job
          */
         if (((attr.basepri = atoi(get_conf_val("nec_basepriority"))) != NEC_UNDEF_VALUE)
            && ((attr.modcpu = atoi(get_conf_val("nec_modcpu"))) != NEC_UNDEF_VALUE)
            && ((attr.tickcnt = atoi(get_conf_val("nec_tickcnt"))) != NEC_UNDEF_VALUE)
            && ((attr.dcyfctr = atoi(get_conf_val("nec_dcyfctr"))) != NEC_UNDEF_VALUE)
            && ((attr.dcyintvl = atoi(get_conf_val("nec_dcyintvl"))) != NEC_UNDEF_VALUE)
            && ((attr.tmslice = atoi(get_conf_val("nec_timeslice"))) != NEC_UNDEF_VALUE)
            && ((attr.mempri = atoi(get_conf_val("nec_memorypriority"))) != NEC_UNDEF_VALUE)
            && ((attr.szefctmrt = atoi(get_conf_val("nec_mrt_size_effct"))) != NEC_UNDEF_VALUE)
            && ((attr.priefctmrt = atoi(get_conf_val("nec_mrt_pri_effct"))) != NEC_UNDEF_VALUE)
            && ((attr.minmrt = atoi(get_conf_val("nec_mrt_minimum"))) != NEC_UNDEF_VALUE)
            && ((attr.agrange = atoi(get_conf_val("nec_aging_range"))) != NEC_UNDEF_VALUE)
            && ((attr.spinherit = atoi(get_conf_val("nec_slavepriority"))) != NEC_UNDEF_VALUE)
            && ((attr.concpu = atoi(get_conf_val("nec_cpu_count"))) != NEC_UNDEF_VALUE)) {
            if (dispcntl(SG_JID, getjid(0), DCNTL_SET2, &attr) == -1) {
               shepherd_trace("ERROR: can't set scheduling parameter: %s[%d]",
                              strerror(errno), errno);
            } else {
               shepherd_trace("control parameters for active process scheduling modified");
               print_scheduling_parameters(attr);
            }
         } else {
            shepherd_trace("we do not control active process scheduling");
         }
      }               
#     else
         /* write a default os-jobid to file */
         sprintf(osjobid, pid_t_fmt, sid);
#     endif
         sge_switch2admin_user();
      } 
      else /* not running as super user --> we want a default os-jobid */
         sprintf(osjobid, "0");
      
      if(fprintf(fp, "%s\n", osjobid) < 0)
         shepherd_trace("error writing osjobid file");
         
      FCLOSE(fp); /* Close os-jobid file */   
   }
#  endif
   return;
FCLOSE_ERROR:
   shepherd_error(1, "can't close file"); 
}
Esempio n. 9
0
/***
Return process group id of calling process.
@function getpgrp
@treturn int process group id of calling process
@see getpid
*/
static int
Pgetpgrp(lua_State *L)
{
	checknargs(L, 0);
	return pushintresult(getpgrp ());
}
/* 
 * 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;     /* if the pid is 0, it is the child. */
    int jid;       /* if the child runs in background, 
                      we should know the jid and print the infomation */

/*
 * Use new_mask to mask three signals.
 * Before the child process execve(), we should unblock these signals.
 * When it comes to parent process, we should set the old_mask set to
 * it after we add the job in job_list.
 */
    sigset_t new_mask, old_mask;

    /* Parse command line */
    bg = parseline(cmdline, &tok); 
/*
 * Maybe there are some more errors that we should return.
 * I did not meet them. If I met an error condition, I will
 * make an improvement as soon as possible.
 */
    if (bg == -1) return;               /* parsing error */
    if (tok.argv[0] == NULL)  return;   /* ignore empty lines */

/*
 * As it is said in the writeup, If the first word is a built-in command, the
 * shell immediately executes the command in the current process. Otherwise, 
 * the word is assumed to be the pathname of an executable program. In this 
 * case, the shell forks a child process, then loads and runs the program in
 * the context of the child.
 * 1. If it is a built-in command, builtinCommand function will handle it.
 * 2. If it is a executable program, the function returns 0.
 * 3. Then, we should block the signals before we fork a child.
 * 4. Put the child in a new process group.
 * 5. Set the I/O Redirection and make the signal default.
 * 6. Execute the program and exit.
 * 7. Add the job and unblock the signals in parent.
 * 8. If the child runs in foreground, wait for it.  
 */
    if (!builtinCommand(tok)) {
        Sigemptyset(&new_mask);
        Sigaddset(&new_mask, SIGCHLD);
        Sigaddset(&new_mask, SIGINT);
        Sigaddset(&new_mask, SIGTSTP);
        Sigprocmask(SIG_BLOCK, &new_mask, &old_mask);

        if (0 == (pid = Fork())) {
            int fdout, fdin;
            Setpgid(0, 0);
            dup2(fdout = getfd(OUT, tok.outfile), STDOUT_FILENO);
            dup2(fdin = getfd(IN, tok.infile), STDIN_FILENO);
            if (!bg) {
                tcsetpgrp(STDIN_FILENO, getpgrp());
            }
            Signal(SIGCHLD, SIG_DFL);
            Signal(SIGINT, SIG_DFL);
            Signal(SIGTSTP, SIG_DFL);
            Sigprocmask(SIG_UNBLOCK, &new_mask, NULL);
            if (execve(tok.argv[0], tok.argv, environ) < 0) {
                printf("%s: Command not found.\n", tok.argv[0]);
                exit(0);
            }
            if (STDOUT_FILENO != fdout) {
                close(fdout);
            }
            if (STDIN_FILENO != fdin) {
                close(fdin);
            }
            exit(0);
        }
        if (bg) {
            addjob(job_list, pid, BG, cmdline);
            Sigprocmask(SIG_SETMASK, &old_mask, NULL);
            jid = pid2jid(pid);
            printf("[%d] (%d) %s\n", jid, pid, cmdline);
        }
        else {
            addjob(job_list, pid, FG, cmdline);
            Sigprocmask(SIG_SETMASK, &old_mask, NULL);
/*
 * If the child runs in foreground, we should wait for it. I think it is
 * the most tricky thing in this shell lab. I test everything I know. Then,
 * I found the sigsuspend() function had the best performance.
 * 1. pause(). 
 *    It is the first way I think about. When I do manually from the
 *    command line, It is OK. However, when it comes to trace file, sometimes
 *    it is OK, sometimes it will cause an error.
 * 2. sleep(1), usleep(n), or something like these.
 *    Although Michael said that we cannot use sleep, I do not know what to do
 *    and what the performance is. So, I test it. When I ran it from the 
 *    command line, I could not find any wrong. When it comes to the trace 
 *    files, there are lots of errors. It seems that it is not a good way. -_-b
 * 3. sleep(0), sleep(0), sleep(0)...
 *    When I found the information in the Internet, someone said 3 or more 
 *    sleep(0) could be a good choice for wait. The fact is that it can pass
 *    a lot of trace files, but the performance is not stable. Also, I think 
 *    it will waste the CPU resource.
 * sigsuspend() is the only way that I found could pass the ./sdriver. If there
 * is annother better way, I will be very interested in it. If you would like 
 * to tell a better solution, I will be very happy.
 */
            while (fgpid(job_list)) {
                sigsuspend(&old_mask);
            }
        }
    }
    return;
}
Esempio n. 11
0
void
setjobctl(int on)
{
	int i;

	if (on == jobctl || rootshell == 0)
		return;
	if (on) {
		if (ttyfd != -1)
			close(ttyfd);
		if ((ttyfd = open(_PATH_TTY, O_RDWR | O_CLOEXEC)) < 0) {
			i = 0;
			while (i <= 2 && !isatty(i))
				i++;
			if (i > 2 ||
			    (ttyfd = fcntl(i, F_DUPFD_CLOEXEC, 10)) < 0) {
				jobctl_notty();
				return;
			}
		}
		if (ttyfd < 10) {
			/*
			 * Keep our TTY file descriptor out of the way of
			 * the user's redirections.
			 */
			if ((i = fcntl(ttyfd, F_DUPFD_CLOEXEC, 10)) < 0) {
				jobctl_notty();
				return;
			}
			close(ttyfd);
			ttyfd = i;
		}
		do { /* while we are in the background */
			initialpgrp = tcgetpgrp(ttyfd);
			if (initialpgrp < 0) {
				jobctl_notty();
				return;
			}
			if (initialpgrp != getpgrp()) {
				if (!iflag) {
					initialpgrp = -1;
					jobctl_notty();
					return;
				}
				kill(0, SIGTTIN);
				continue;
			}
		} while (0);
		setsignal(SIGTSTP);
		setsignal(SIGTTOU);
		setsignal(SIGTTIN);
		setpgid(0, rootpid);
		tcsetpgrp(ttyfd, rootpid);
	} else { /* turning job control off */
		setpgid(0, initialpgrp);
		if (ttyfd >= 0) {
			tcsetpgrp(ttyfd, initialpgrp);
			close(ttyfd);
			ttyfd = -1;
		}
		setsignal(SIGTSTP);
		setsignal(SIGTTOU);
		setsignal(SIGTTIN);
	}
	jobctl = on;
}
/*
 * main - The shell's main routine 
 */
int 
main(int argc, char **argv) 
{
    char c;
    char cmdline[MAXLINE];    /* cmdline for fgets */
    int emit_prompt = 1; /* emit prompt (default) */

    /* Redirect stderr to stdout (so that driver will get all output
     * on the pipe connected to stdout) */
    dup2(1, 2);

    /* Parse the command line */
    while ((c = getopt(argc, argv, "hvp")) != EOF) {
        switch (c) {
        case 'h':             /* print help message */
            usage();
            break;
        case 'v':             /* emit additional diagnostic info */
            verbose = 1;
            break;
        case 'p':             /* don't print a prompt */
            emit_prompt = 0;  /* handy for automatic testing */
            break;
        default:
            usage();
        }
    }

    /* Install the signal handlers */

    /* These are the ones you will need to implement */
    Signal(SIGINT,  sigint_handler);   /* ctrl-c */
    Signal(SIGTSTP, sigtstp_handler);  /* ctrl-z */
    Signal(SIGCHLD, sigchld_handler);  /* Terminated or stopped child */
    Signal(SIGTTIN, SIG_IGN);
    Signal(SIGTTOU, SIG_IGN);

    /* This one provides a clean way to kill the shell */
    Signal(SIGQUIT, sigquit_handler); 

    /* Initialize the job list */
    initjobs(job_list);

    /* Execute the shell's read/eval loop */
    while (1) {
        if (tcgetpgrp(STDIN_FILENO) != getpgrp()) {
            tcsetpgrp(STDIN_FILENO, getpgrp());
        }
        if (emit_prompt) {
            printf("%s", prompt);
            fflush(stdout);
        }
        if ((fgets(cmdline, MAXLINE, stdin) == NULL) && ferror(stdin))
            app_error("fgets error");
        if (feof(stdin)) { 
            /* End of file (ctrl-d) */
            printf ("\n");
            fflush(stdout);
            fflush(stderr);
            exit(0);
        }
        
        /* Remove the trailing newline */
        cmdline[strlen(cmdline)-1] = '\0';
        
        /* Evaluate the command line */
        eval(cmdline);
        
        fflush(stdout);
        fflush(stdout);
    } 
    
    exit(0); /* control never reaches here */
}
Esempio n. 13
0
int main(int argc, char *argv[]) {
    printf("hello,main()\n");
    printf("test group id: %d pid : %d ppid: %d \n",getpgrp(),getpid(),getppid());
    //sleep(5);
    return 0;
}
int main()
{
    pid_t pid1,pid2;
    pid_t pid;
    int status;

    if((pid1 = fork()) < 0)
    {
        perror("Fail to fork");
        exit(EXIT_FAILURE);

    }else if(pid1 == 0){

        setpgrp(); // 自己创建一个组,PGID == PID
        printf("Create child process  pid1 (PID : %d  PGID : %d).\n",getpid(),getpgrp());
        while(1);

    }else{

        if((pid2 = fork()) < 0)
        {
            perror("Fail to fork");
            exit(EXIT_FAILURE);

        }else if(pid2 == 0){

            printf("Create child process pid2 (PID : %d  PGID : %d).\n",getpid(),getpgrp());
            while(1);
            //	printf("Child process (PID : %d  PGID :%d) exit.\n",getpid(),getpgrp());	

        }else{
            sleep(1);
            printf("Father PID : %d.\n",getpid());
            while(1)
            {
                printf("The father waitpid .\n");
                pid = waitpid(-1,&status,WUNTRACED | WCONTINUED | WNOHANG);

                if(pid == -1)
                    break;

                printf("CHILD PID : %d.\n",pid);

                if(WIFEXITED(status))
                {
                    printf("Normal exit.\n");

                }else if(WIFSIGNALED(status)){

                    printf("EXIT by signal(%d).\n",WTERMSIG(status));

                }else if(WIFSTOPPED(status)){

                    printf("Stop by signal(%d).\n",WSTOPSIG(status));
                }else if(WIFCONTINUED(status)){
                    printf("Continue bys SIGCONT.\n");

                }else{

                    printf("Unknown.\n");
                }

            }
        }

    }

    return 0;
}
void
OsInit(void)
{
    static Bool been_here = FALSE;
    static char* admpath = ADMPATH;
    static char* devnull = "/dev/null";
    char fname[PATH_MAX];

#ifdef macII
    set42sig();
#endif

    if (!been_here) {
#if !defined(__SCO__) && !defined(__CYGWIN__) && !defined(__UNIXWARE__)
        fclose(stdin);
        fclose(stdout);
#endif
        /*
         * If a write of zero bytes to stderr returns non-zero, i.e. -1,
         * then writing to stderr failed, and we'll write somewhere else
         * instead. (Apparently this never happens in the Real World.)
         */
        if (write (2, fname, 0) == -1)
        {
            FILE *err;

            if (strlen (display) + strlen (admpath) + 1 < sizeof fname)
                sprintf (fname, admpath, display);
            else
                strcpy (fname, devnull);
            /*
             * uses stdio to avoid os dependencies here,
             * a real os would use
             *  open (fname, O_WRONLY|O_APPEND|O_CREAT, 0666)
             */
            if (!(err = fopen (fname, "a+")))
                err = fopen (devnull, "w");
            if (err && (fileno(err) != 2)) {
                dup2 (fileno (err), 2);
                fclose (err);
            }
#if defined(SYSV) || defined(SVR4) || defined(WIN32) || defined(__CYGWIN__)
            {
                static char buf[BUFSIZ];
                setvbuf (stderr, buf, _IOLBF, BUFSIZ);
            }
#else
            setlinebuf(stderr);
#endif
        }

#ifndef X_NOT_POSIX
        if (getpgrp () == 0)
            setpgid (0, 0);
#else
#if !defined(SYSV) && !defined(WIN32)
        if (getpgrp (0) == 0)
            setpgrp (0, getpid ());
#endif
#endif

#ifdef RLIMIT_DATA
        if (limitDataSpace >= 0)
        {
            struct rlimit	rlim;

            if (!getrlimit(RLIMIT_DATA, &rlim))
            {
                if ((limitDataSpace > 0) && (limitDataSpace < rlim.rlim_max))
                    rlim.rlim_cur = limitDataSpace;
                else
                    rlim.rlim_cur = rlim.rlim_max;
                (void)setrlimit(RLIMIT_DATA, &rlim);
            }
        }
#endif
#ifdef RLIMIT_STACK
        if (limitStackSpace >= 0)
        {
            struct rlimit	rlim;

            if (!getrlimit(RLIMIT_STACK, &rlim))
            {
                if ((limitStackSpace > 0) && (limitStackSpace < rlim.rlim_max))
                    rlim.rlim_cur = limitStackSpace;
                else
                    rlim.rlim_cur = rlim.rlim_max;
                (void)setrlimit(RLIMIT_STACK, &rlim);
            }
        }
#endif
#ifdef RLIMIT_NOFILE
        if (limitNoFile >= 0)
        {
            struct rlimit	rlim;

            if (!getrlimit(RLIMIT_NOFILE, &rlim))
            {
                if ((limitNoFile > 0) && (limitNoFile < rlim.rlim_max))
                    rlim.rlim_cur = limitNoFile;
                else
                    rlim.rlim_cur = rlim.rlim_max;
#if 0
                if (rlim.rlim_cur > MAXSOCKS)
                    rlim.rlim_cur = MAXSOCKS;
#endif
                (void)setrlimit(RLIMIT_NOFILE, &rlim);
            }
        }
#endif
#ifdef SERVER_LOCK
        LockServer();
#endif
        been_here = TRUE;
    }
    TimerInit();
#ifdef DDXOSINIT
    OsVendorInit();
#endif
    /*
     * No log file by default.  OsVendorInit() should call LogInit() with the
     * log file name if logging to a file is desired.
     */
    LogInit(NULL, NULL);
#ifdef SMART_SCHEDULE
    if (!SmartScheduleDisable)
        if (!SmartScheduleInit ())
            SmartScheduleDisable = TRUE;
#endif
    OsInitAllocator();
    if (!OsDelayInitColors) OsInitColors();
}
Esempio n. 16
0
File: main.c Progetto: actility/ong
int main(int argc, char **argv)
{
  int masterr, masterw, slaver, slavew, pid;
  char ptyname[FILENAME_MAX];
  bufchain tochild, tostdout;
  int tochild_active, tostdout_active, fromstdin_active, fromchild_active;
  int exitcode = -1;
  pid_t childpid = -1;

        --argc, ++argv;         /* point at argument after "--" */

  /*
   * Allocate the pipe for transmitting signals back to the
   * top-level select loop.
   */
  if (pipe(signalpipe) < 0) {
    perror("pipe");
    return 1;
  }

  /*
   * Now that pipe exists, we can set up the SIGCHLD handler to
   * write to one end of it. We needn't already know details like
   * which child pid we're waiting for, because we don't need that
   * until we respond to reading the far end of the pipe in the
   * main select loop.
   */
  signal(SIGCHLD, sigchld);

  /*
   * Allocate the pty or pipes.
   */
  masterr = pty_get(ptyname);
  masterw = dup(masterr);
  slaver = open(ptyname, O_RDWR);
  slavew = dup(slaver);
  if (slaver < 0) {
    perror("slave pty: open");
    return 1;
  }

  bufchain_init(&tochild);
  bufchain_init(&tostdout);
  tochild_active = tostdout_active = TRUE;
  fromchild_active = fromstdin_active = TRUE;

  /*
   * Fork and execute the command.
   */
  pid = fork();
  if (pid < 0) {
    perror("fork");
    return 1;
  }

  if (pid == 0) {
    int i;
    /*
     * We are the child.
     */
    close(masterr);
    close(masterw);

    fcntl(slaver, F_SETFD, 0);    /* don't close on exec */
    fcntl(slavew, F_SETFD, 0);    /* don't close on exec */
    close(0);
    dup2(slaver, 0);
    close(1);
    dup2(slavew, 1);
    int fd;
    close(2);
    dup2(slavew, 2);
    setsid();
    setpgid(0, 0);
    tcsetpgrp(0, getpgrp());
    if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
      ioctl(fd, TIOCNOTTY);
      close(fd);
    }
    ioctl(slavew, TIOCSCTTY);
    
    /* Close everything _else_, for tidiness. */
    for (i = 3; i < 1024; i++)
      close(i);
    if (argc > 0) {
      execvp(argv[0], argv);     /* assumes argv has trailing NULL */
    } else {
      execl(getenv("SHELL"), getenv("SHELL"), NULL);
    }
    /*
     * If we're here, exec has gone badly foom.
     */
    perror("exec");
    exit(127);
  }

  /*
   * Now we're the parent. Close the slave fds and start copying
   * stuff back and forth.
   */
  close(slaver);
  close(slavew);
  childpid = pid;

  tcgetattr(0, &oldattrs);
  newattrs = oldattrs;
  newattrs.c_iflag &= ~(IXON | IXOFF | ICRNL | INLCR);
  newattrs.c_oflag &= ~(ONLCR | OCRNL);
  newattrs.c_lflag &= ~(ISIG | ICANON | ECHO);
  atexit(attrsonexit);
  tcsetattr(0, TCSADRAIN, &newattrs);
  

  while (1) {
    fd_set rset, wset;
    char buf[65536];
    int maxfd, ret;

    FD_ZERO(&rset);
    FD_ZERO(&wset);
    maxfd = 0;

    FD_SET(signalpipe[0], &rset);
    maxfd = max(signalpipe[0]+1, maxfd);

    if (tochild_active && bufchain_size(&tochild)) {
      FD_SET(masterw, &wset);
      maxfd = max(masterw+1, maxfd);
    }
    if (tostdout_active && bufchain_size(&tostdout)) {
      FD_SET(1, &wset);
      maxfd = max(1+1, maxfd);
    }
    if (fromstdin_active && bufchain_size(&tochild) < LOCALBUF_LIMIT) {
      FD_SET(0, &rset);
      maxfd = max(0+1, maxfd);
    }
    if (fromchild_active && bufchain_size(&tostdout) < LOCALBUF_LIMIT) {
      FD_SET(masterr, &rset);
      maxfd = max(masterr+1, maxfd);
    }

    do {
      ret = select(maxfd, &rset, &wset, NULL, NULL);
    } while (ret < 0 && (errno == EINTR || errno == EAGAIN));

    if (ret < 0) {
      perror("select");
      return 1;
    }

    if (FD_ISSET(masterr, &rset)) {

      if (FD_ISSET(masterr, &rset)) {
        ret = read(masterr, buf, sizeof(buf));
        if (ret <= 0) {
          /*
           * EIO from a pty master just means end of
           * file, annoyingly. Why can't it report
           * ordinary EOF?
           */
          if (errno == EIO)
            ret = 0;
          if (ret < 0) {
            perror("child process: read");
          }
          close(masterr);
          fromchild_active = FALSE;
          ret = 0;
        }
      } else
        ret = 0;

      if (ret) {
        bufchain_add(&tostdout, buf, ret);
      }
    }
    if (FD_ISSET(0, &rset)) {

      if (FD_ISSET(0, &rset)) {
        ret = read(0, buf, sizeof(buf));
        if (ret <= 0) {
          if (ret < 0) {
            perror("stdin: read");
          }
          close(0);
          fromstdin_active = FALSE;
          ret = 0;
        }
      } else
        ret = 0;

      if (ret) {
        bufchain_add(&tochild, buf, ret);
      }
    }
    if (FD_ISSET(1, &wset)) {
      void *data;
      int len, ret;
      bufchain_prefix(&tostdout, &data, &len);
      if ((ret = write(1, data, len)) < 0) {
        perror("stdout: write");
        close(1);
        close(masterr);
        tostdout_active = fromchild_active = FALSE;
      } else
        bufchain_consume(&tostdout, ret);
    }
    if (FD_ISSET(masterw, &wset)) {
      void *data;
      int len;
      bufchain_prefix(&tochild, &data, &len);
      if ((ret = write(masterw, data, len)) < 0) {
        perror("child process: write");
        close(0);
        close(masterw);
        tochild_active = fromstdin_active = FALSE;
      } else
        bufchain_consume(&tochild, ret);
    }
    if (FD_ISSET(signalpipe[0], &rset)) {
      ret = read(signalpipe[0], buf, 1);
      if (ret == 1 && buf[0] == 'C') {
        int pid, code;
        pid = wait(&code);     /* reap the exit code */
        if (pid == childpid)
          exitcode = code;
      }
    }

    /*
     * If there can be no further data from a direction (the
     * input fd has been closed and the buffered data is used
     * up) but its output fd is still open, close it.
     */
    if (!fromstdin_active && !bufchain_size(&tochild) && tochild_active) {
      tochild_active = FALSE;
      close(masterw);
    }
    if (!fromchild_active && !bufchain_size(&tostdout) && tostdout_active){
      tostdout_active = FALSE;
      close(1);
    }

    /*
     * Termination condition with pipes is that there's still
     * data flowing in at least one direction.
     * 
     * Termination condition for a pty-based run is that the
     * child process hasn't yet terminated and/or there is
     * still buffered data to send.
     */
    if (exitcode < 0)
      /* process is still active */;
    else if (tochild_active && bufchain_size(&tochild))
      /* data still to be sent to child's children */;
    else if (tostdout_active && bufchain_size(&tostdout))
      /* data still to be sent to stdout */;
    else
      break;           /* terminate */
  }

  close(masterw);
  close(masterr);

  if (exitcode < 0) {
    int pid, code;
    pid = wait(&code);
    exitcode = code;
  }

  return (WIFEXITED(exitcode) ? WEXITSTATUS(exitcode) :
      128 | WTERMSIG(exitcode));
}
Esempio n. 17
0
static int G__posix__0_35(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash)
{
      G__letint(result7, 105, (long) getpgrp());
   return(1 || funcname || hash || result7 || libp) ;
}
Esempio n. 18
0
/*---------------------------------------------------------------------------*/
void matar_procesos_propios()
{
   killpg(getpgrp(),SIGINT);
   killpg(getpgrp(),SIGQUIT);
   killpg(getpgrp(),SIGKILL);
}
Esempio n. 19
0
/*
 * do_child_1()
 */
void
do_child_1(void)
{
	int kid_count, fork_kid_pid[MAXKIDS];
	int ret_val;
	int i, j, k, found;
	int group1, group2;
	int wait_kid_pid[MAXKIDS], status;

	setup_sigint();

	group1 = getpgrp();
	for (kid_count = 0; kid_count < MAXKIDS; kid_count++) {
		if (kid_count == (MAXKIDS / 2)) {
			group2 = setpgrp();
		}
		intintr = 0;
		ret_val = FORK_OR_VFORK();
		if (ret_val == 0) {	/* child */
#ifdef UCLINUX
			if (self_exec(argv0, "n", 2) < 0) {
				tst_resm(TFAIL, "Fork kid %d failed. "
					 "errno = %d", kid_count,
					 errno);
				exit(ret_val);
			}
#else
			do_exit();
#endif
			/*NOTREACHED*/
		} else if (ret_val < 0) {
			tst_resm(TFAIL, "Fork kid %d failed. "
				 "errno = %d", kid_count,
				 errno);
			exit(ret_val);
		}

		/* parent */
		fork_kid_pid[kid_count] = ret_val;
	}

#ifdef UCLINUX
	/* Give the kids a chance to setup SIGINT again, since this is
	 * cleared by exec().
	 */
	sleep(3);
#endif

	/* Now send all the kids a SIGINT to tell them to
	 * proceed
	 */
	for (i = 0; i < MAXKIDS; i++) {
		if (kill(fork_kid_pid[i], SIGINT) < 0) {
			tst_resm(TFAIL, "Kill of child %d "
				 "failed, errno = %d", i, errno);
			exit(-1);
		}
	}

	/*
	 * Wait till all kids have terminated.  Stash away their
	 * pid's in an array.
	 */
	kid_count = 0;
	errno = 0;
	while (((ret_val = waitpid(-1, &status, 0)) != -1) ||
	       (errno == EINTR)) {
		if (ret_val == -1) {
			continue;
		}

		if (!WIFEXITED(status)) {
			tst_resm(TFAIL, "Child %d did not exit "
				 "normally", ret_val);
			flag = FAILED;
			printf("status: %d\n", status);
		} else {
			if (WEXITSTATUS(status) != 3) {
				tst_resm(TFAIL, "Child %d"
					 "exited with wrong "
					 "status", ret_val);
				tst_resm(TFAIL, "Expected 3 "
					 "got %d ",
					 WEXITSTATUS(status));
				flag = FAILED;
			}
		}
		wait_kid_pid[kid_count++] = ret_val;
	}

	/*
	 * Check that for every entry in the fork_kid_pid array,
	 * there is a matching pid in the wait_kid_pid array. If
	 * not, it's an error.
	 */
	for (i = 0; i < kid_count; i++) {
		found = 0;
		for (j = 0; j < MAXKIDS; j++) {
			if (fork_kid_pid[j] == wait_kid_pid[i]){
				found = 1;
				break;
			}
		}

		if (!found) {
			tst_resm(TFAIL, "Did not find a "
				 "wait_kid_pid for the "
				 "fork_kid_pid of %d",
				 fork_kid_pid[j]);
			for (k = 0; k < MAXKIDS; k++) {
				tst_resm(TFAIL,
					 "fork_kid_pid[%d] = "
					 "%d", k,
					 fork_kid_pid[k]);
			}
			for (k = 0; k < kid_count; k++) {
				tst_resm(TFAIL,
					 "wait_kid_pid[%d] = "
					 "%d", k,
					 wait_kid_pid[k]);
			}
			flag = FAILED;
		}
	}

	if (flag) {
		exit(1);
	} else {
		exit(0);
	}
}
Esempio n. 20
0
/*
 * Start up the process with the given args
 */
INTERNAL int
start_agent(AGENT_REQ *areq, char *cmd, char *args, int *retpid) {
	int   argc;
	char *argv[MAX_ARGS];
	char  hostname[AGENTD_NAMELEN];
	int   childpid;
	int   pid, exitstat;
	int   pipeout[2], pipeerr[2];
	int   rc;
	EVENT_AGENTD_STAT estat;
	EVENT_AGENTD_LOG  elogout, elogerr;
	char  msg[200];
	char  cmdpath[PATHLEN];

	if (WorkDir) make_path(cmdpath, ExecPath, cmd);
	else         strcpy(cmdpath, cmd);

	argv[0] = cmd;
	argc    = 1;

	if (Verbose) printf("0: %s (%s)\n", argv[0], cmdpath);
	rc = parse_args(args, argv, 1);
	if (rc < 0) {
		return(0);
	}
	argc = rc;

/**************************/
/****** START DEBUG *******/
#ifdef FAKE_THIS_FOR_DEBUGGING
printf("start_agent: sleeping\n");
	if (areq) {
		areq->status = AGENTD_AGENT_RUNNING;
		areq->pid    = 9999999;

		estat.reqseq  = EventSeq(areq->ereq);
		estat.tag     = areq->ereq.tag;
		estat.reqtype = AGENTD_CTL_START;
		estat.result  = 9999999;
		estat.rstatus = AGENTD_STATUS_OK;
		SEND(EventFrom(areq->ereq), AGENTD_STAT, estat);
	}
sleep(10);
	if (areq) {
		areq->status = AGENTD_AGENT_EXIT;

		estat.result  = 0;
		estat.rstatus = AGENTD_AGENT_EXIT;
		SEND(EventFrom(areq->ereq), AGENTD_STAT, estat);
	}
printf("start_agent: exiting\n");
return(AGENTD_STATUS_OK);
#endif
/******** END DEBUG *******/
/**************************/

	if (pipe(pipeout) != SYS_OK) {
		fprintf(stderr, "start_agent: couldn't create stdout pipe\n");
		perror("start_agent");
		return(AGENTD_STATUS_RUNERR);
	}
	if (pipe(pipeerr) != SYS_OK) {
		fprintf(stderr, "start_agent: couldn't create stderr pipe\n");
		perror("start_agent");
		return(AGENTD_STATUS_RUNERR);
	}

	childpid = fork();
	if (childpid < 0) {        /* Error occurred */
		fprintf(stderr, "start_agent: fork failed\n");
		perror("start_agent");

		close(pipeout[0]);
		close(pipeout[1]);
		close(pipeerr[0]);
		close(pipeerr[1]);

		return(AGENTD_STATUS_RUNERR);
	}

	/*
	 * Exec command from newly forked process
	 */
	if (childpid == 0) {       /* Child process */
		int   fdin;
		int   argc;
		int   rc;

	   /****
		event_exit_();
	    ****/

		if (WorkDir) chdir(WorkPath);

		/* stdin */
		fdin = open("/dev/null", O_RDONLY);
		dup2(fdin, 0);
		close(fdin);

		/* stdout */
		rc = dup2(pipeout[1], 1);
		close(pipeout[0]);
		close(pipeout[1]);
		if (rc < 0) printf("start_agent: couldn't dup pipe as stdout");

		/* stderr */
		rc = dup2(pipeerr[1], 2);
		close(pipeerr[0]);
		close(pipeerr[1]);
		if (rc < 0) printf("start_agent: couldn't dup pipe as stderr");

		/* Create a new process group */
		setpgrp();

		fprintf(stderr,
			"agentd: child proc %d, pgrp %d execing %s\n",
			 getpid(), getpgrp(), cmd);

		execv(cmdpath, argv);

		/* If exec returns it means an error occurred */
		close(0);
		close(1);
		close(2);

		exit(AGENTD_STATUS_RUNERR);
	}

	signal(SIGABRT, SIG_IGN);

	if (Verbose) printf("start_agent: created child process %d\n", childpid);

	/* Report startup status to requester */
	if (areq) {
		areq->status = AGENTD_AGENT_RUNNING;
		areq->pid    = childpid;

		estat.reqseq  = EventSeq(areq->ereq);
		estat.tag     = areq->ereq.tag;
		estat.reqtype = AGENTD_CTL_START;
		estat.result  = childpid;
		estat.rstatus = AGENTD_STATUS_OK;
		SEND(EventFrom(areq->ereq), AGENTD_STAT, estat);
	}

	gethostname(hostname, sizeof(hostname));

	/* Set up stderr */
	elogerr.head.to = EVENT_BCAST_NOTME;
	elogerr.type    = AGENTD_LOG_STDERR;
	elogerr.flags   = pipeerr[0];
	elogerr.pid     = childpid;
	strcpy(elogerr.hostname, hostname);
	strcpy(elogerr.program,  cmd);

	/* Start reader thread and wait for it to initialize */
	if (Verbose) printf("start_agent: starting reader thread for stderr\n");
	mp_task(reader, &elogerr, 0);
	mp_decsema(ReadInit);

	/* Broadcast a message */
	sprintf(elogerr.msg, "agentd: agent started as pid %d\n", childpid);
	SEND(EVENT_BCAST_NOTME, AGENTD_LOG, elogerr);

	/* Now do the same for stdout */
	elogout.head.to = EVENT_BCAST_NOTME;
	elogout.type    = AGENTD_LOG_STDOUT;
	elogout.flags   = pipeout[0];
	elogout.pid     = childpid;
	strcpy(elogout.hostname, hostname);
	strcpy(elogout.program,  cmd);

	if (Verbose) printf("start_agent: starting reader thread for stdout\n");
	mp_task(reader, &elogout, 0);
	mp_decsema(ReadInit);

	/* Wait for child (agent) process to exit */
	if (Verbose) printf("start_agent: waiting for agent proc %d\n", childpid);
	pid = waitpid(childpid, &exitstat, 0);
	if (pid <= 0) {
		perror("start_agent: waitpid");
	}

	if (WIFSIGNALED(exitstat))
	   sprintf(msg, "agent %d exited on signal %s with rc %d",
		childpid,
		signame(WTERMSIG(exitstat)),
		WEXITSTATUS(exitstat));
	else
	   sprintf(msg, "agent %d exited normally with rc %d",
		childpid, WEXITSTATUS(exitstat));

	if (Verbose) printf("start_agent: %s\n", msg);

	/* Set exit and write to pipe to wake up readers */
	mp_lock(Exitlock);

	Exit = childpid;

	sleep(5); /* delay to let things quiesce */

	write(pipeout[1], EofStr, strlen(EofStr)+1);
	write(pipeerr[1], EofStr, strlen(EofStr)+1);

	if (Verbose) printf("start_agent: %d.%d waiting for 2 %d.readers to exit\n", getpid(), mp_gettid(), childpid);
	mp_decsema(Exitwait);
	if (Verbose) printf("start_agent: %d.%d waiting for 1 %d.reader to exit\n", getpid(), mp_gettid(), childpid);
	mp_decsema(Exitwait);
	if (Verbose) printf("start_agent: %d.%d all %d.readers exited\n", getpid(), mp_gettid(), childpid);

	Exit = 0;
	mp_unlock(Exitlock);

	/* Broadcast a message */
	sprintf(elogerr.msg, "agentd: %s\n", msg);
	SEND(EVENT_BCAST_NOTME, AGENTD_LOG, elogerr);

	close(pipeout[0]);
	close(pipeout[1]);
	close(pipeerr[0]);
	close(pipeerr[1]);

	/*
	 * Report exit status back to requester
	 */
	if (areq) {
		areq->status = AGENTD_AGENT_EXIT;

		estat.result  = exitstat;
		estat.rstatus = AGENTD_AGENT_EXIT;
		SEND(EventFrom(areq->ereq), AGENTD_STAT, estat);
	}

	if (retpid) *retpid = childpid;

	return(AGENTD_STATUS_OK);
}
Esempio n. 21
0
pid_t Getpgrp(void) {
    return getpgrp();
}
Esempio n. 22
0
status_t
Shell::_Spawn(int row, int col, const char *encoding, int argc, const char **argv)
{
	const char *kDefaultShellCommand[] = { "/bin/sh", "--login", NULL };

	if (argv == NULL || argc == 0) {
		argv = kDefaultShellCommand;
		argc = 2;
	}

	signal(SIGTTOU, SIG_IGN);

#ifdef __HAIKU__
	// get a pseudo-tty
	int master = posix_openpt(O_RDWR | O_NOCTTY);
	const char *ttyName;
#else /* __HAIKU__ */
	/*
	 * Get a pseudo-tty. We do this by cycling through files in the
	 * directory. The operating system will not allow us to open a master
	 * which is already in use, so we simply go until the open succeeds.
	 */
	char ttyName[B_PATH_NAME_LENGTH];
	int master = -1;
	DIR *dir = opendir("/dev/pt/");
	if (dir != NULL) {
		struct dirent *dirEntry;
		while ((dirEntry = readdir(dir)) != NULL) {
			// skip '.' and '..'
			if (dirEntry->d_name[0] == '.')
				continue;

			char ptyName[B_PATH_NAME_LENGTH];
			snprintf(ptyName, sizeof(ptyName), "/dev/pt/%s", dirEntry->d_name);

			master = open(ptyName, O_RDWR);
			if (master >= 0) {
				// Set the tty that corresponds to the pty we found
				snprintf(ttyName, sizeof(ttyName), "/dev/tt/%s", dirEntry->d_name);
				break;
			} else {
				// B_BUSY is a normal case
				if (errno != B_BUSY)
					fprintf(stderr, B_TRANSLATE("could not open %s: %s\n"),
						ptyName, strerror(errno));
			}
		}
		closedir(dir);
	}
#endif /* __HAIKU__ */

	if (master < 0) {
    	fprintf(stderr, B_TRANSLATE("Didn't find any available pseudo ttys."));
    	return errno;
	}

#ifdef __HAIKU__
	if (grantpt(master) != 0 || unlockpt(master) != 0
		|| (ttyName = ptsname(master)) == NULL) {
		close(master);
    	fprintf(stderr, B_TRANSLATE("Failed to init pseudo tty."));
		return errno;
	}
#endif /* __HAIKU__ */

	/*
	 * Get the modes of the current terminal. We will duplicates these
	 * on the pseudo terminal.
	 */

	thread_id terminalThread = find_thread(NULL);

	/* Fork a child process. */
	if ((fProcessID = fork()) < 0) {
		close(master);
		return B_ERROR;
	}

	handshake_t handshake;

	if (fProcessID == 0) {
		// Now in child process.

		// close the PTY master side
		close(master);

		/*
		 * Make our controlling tty the pseudo tty. This hapens because
		 * we cleared our original controlling terminal above.
		 */

		/* Set process session leader */
		if (setsid() < 0) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				B_TRANSLATE("could not set session leader."));
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		/* open slave pty */
		int slave = -1;
		if ((slave = open(ttyName, O_RDWR)) < 0) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				B_TRANSLATE("can't open tty (%s)."), ttyName);
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		/* set signal default */
		signal(SIGCHLD, SIG_DFL);
		signal(SIGHUP, SIG_DFL);
		signal(SIGQUIT, SIG_DFL);
		signal(SIGTERM, SIG_DFL);
		signal(SIGINT, SIG_DFL);
		signal(SIGTTOU, SIG_DFL);

		struct termios tio;
		/* get tty termios (not necessary).
		 * TODO: so why are we doing it ?
		 */
		tcgetattr(slave, &tio);

		initialize_termios(tio);

		/*
		 * change control tty.
		 */

		dup2(slave, 0);
		dup2(slave, 1);
		dup2(slave, 2);

		/* close old slave fd. */
		if (slave > 2)
			close(slave);

		/*
		 * set terminal interface.
		 */
		if (tcsetattr(0, TCSANOW, &tio) == -1) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				B_TRANSLATE("failed set terminal interface (TERMIOS)."));
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		/*
		 * set window size.
		 */

		handshake.status = PTY_WS;
		send_handshake_message(terminalThread, handshake);
		receive_handshake_message(handshake);

		if (handshake.status != PTY_WS) {
			handshake.status = PTY_NG;
			snprintf(handshake.msg, sizeof(handshake.msg),
				B_TRANSLATE("mismatch handshake."));
			send_handshake_message(terminalThread, handshake);
			exit(1);
		}

		struct winsize ws = { handshake.row, handshake.col };

		ioctl(0, TIOCSWINSZ, &ws);

		tcsetpgrp(0, getpgrp());
			// set this process group ID as the controlling terminal
#ifndef __HAIKU__
		ioctl(0, 'pgid', getpid());
#endif
		set_thread_priority(find_thread(NULL), B_NORMAL_PRIORITY);

		/* pty open and set termios successful. */
		handshake.status = PTY_OK;
		send_handshake_message(terminalThread, handshake);

		/*
		 * setenv TERM and TTY.
		 */
		setenv("TERM", "xterm", true);
		setenv("TTY", ttyName, true);
		setenv("TTYPE", encoding, true);

		execve(argv[0], (char * const *)argv, environ);

		// Exec failed.
		// TODO: This doesn't belong here.

		sleep(1);

		BString alertCommand = "alert --stop '";
		alertCommand += B_TRANSLATE("Cannot execute \"%command\":\n\t%error");
		alertCommand += "' '";
		alertCommand += B_TRANSLATE("Use default shell");
		alertCommand += "' '";
		alertCommand += B_TRANSLATE("Abort");
		alertCommand += "'";
		alertCommand.ReplaceFirst("%command", argv[0]);
		alertCommand.ReplaceFirst("%error", strerror(errno));

		int returnValue = system(alertCommand.String());
		if (returnValue == 0) {
			execl(kDefaultShellCommand[0], kDefaultShellCommand[0],
				kDefaultShellCommand[1], NULL);
		}

		exit(1);
	}

	/*
	 * In parent Process, Set up the input and output file pointers so
	 * that they can write and read the pseudo terminal.
	 */

	/*
	 * close parent control tty.
	 */

	int done = 0;
	while (!done) {
		receive_handshake_message(handshake);

		switch (handshake.status) {
			case PTY_OK:
				done = 1;
				break;

			case PTY_NG:
				fprintf(stderr, "%s\n", handshake.msg);
				done = -1;
				break;

			case PTY_WS:
				handshake.row = row;
				handshake.col = col;
				handshake.status = PTY_WS;
				send_handshake_message(fProcessID, handshake);
				break;
		}
	}

	if (done <= 0)
		return B_ERROR;

	fFd = master;

	return B_OK;
}
Esempio n. 23
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))) {
Esempio n. 24
0
int spawn(char *program, char *argv[], int sin, int sout, int serr,
          int search, char *envp[], char *pty_name, int wait)
{
    int pid = fork();
    int fd;
    sigset_t sset;

    if (pid != 0)
        return pid;

    /* Put us in our own process group, but only if we need not
     * share stdin with our parent. In the latter case we claim
     * control of the terminal. */
    if (sin >= 0) {
#if defined(LISP_FEATURE_HPUX) || defined(LISP_FEATURE_OPENBSD)
      setsid();
#elif defined(LISP_FEATURE_DARWIN)
      setpgid(0, getpid());
#elif defined(SVR4) || defined(__linux__) || defined(__osf__)
      setpgrp();
#else
      setpgrp(0, getpid());
#endif
    } else {
      tcsetpgrp(0, getpgrp());
    }

    /* unblock signals */
    sigemptyset(&sset);
    sigprocmask(SIG_SETMASK, &sset, NULL);

    /* If we are supposed to be part of some other pty, go for it. */
    if (pty_name)
        set_pty(pty_name);
    else {
    /* Set up stdin, stdout, and stderr */
    if (sin >= 0)
        dup2(sin, 0);
    if (sout >= 0)
        dup2(sout, 1);
    if (serr >= 0)
        dup2(serr, 2);
    }
    /* Close all other fds. */
#ifdef SVR4
    for (fd = sysconf(_SC_OPEN_MAX)-1; fd >= 3; fd--)
        close(fd);
#else
    for (fd = getdtablesize()-1; fd >= 3; fd--)
        close(fd);
#endif

    environ = envp;
    /* Exec the program. */
    if (search)
      execvp(program, argv);
    else
      execv(program, argv);

    exit (1);
}
Esempio n. 25
0
/*
 * Terminal I/O
 */
void
initterm(void)
{
	char		buf[TBUFSIZ];
	static char	clearbuf[TBUFSIZ];
	char		*clearptr, *padstr;
	char		*term;
	int		tgrp;
	struct winsize	win;

retry:
	if (!(no_tty = tcgetattr(STDOUT_FILENO, &otty))) {
		docrterase = (otty.c_cc[VERASE] != _POSIX_VDISABLE);
		docrtkill =  (otty.c_cc[VKILL] != _POSIX_VDISABLE);
		/*
		 * Wait until we're in the foreground before we save the
		 * the terminal modes.
		 */
		if ((tgrp = tcgetpgrp(STDOUT_FILENO)) < 0) {
			perror("tcgetpgrp");
			exit(1);
		}
		if (tgrp != getpgrp()) {
			kill(0, SIGTTOU);
			goto retry;
		}
		if ((term = getenv("TERM")) == 0 || tgetent(buf, term) <= 0) {
			dumb++; ul_opt = 0;
		} else {
			if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) < 0) {
				Lpp = tgetnum("li");
				Mcol = tgetnum("co");
			} else {
				if ((Lpp = win.ws_row) == 0)
					Lpp = tgetnum("li");
				if ((Mcol = win.ws_col) == 0)
					Mcol = tgetnum("co");
			}
			if (Lpp <= 0 || tgetflag("hc")) {
				hard++;		/* Hard copy terminal */
				Lpp = 24;
			}
			if (tgetflag("xn")) {
				/* Eat newline at last column + 1 */
				eatnl++;
			}
			if (Mcol <= 0)
				Mcol = 80;

			if (strcmp(__progname, "page") == 0 ||
			    (!hard && tgetflag("ns")))
				noscroll++;
			Wrap = tgetflag("am");
			bad_so = tgetflag ("xs");
			clearptr = clearbuf;
			eraseln = tgetstr("ce", &clearptr);
			Clear = tgetstr("cl", &clearptr);
			Senter = tgetstr("so", &clearptr);
			Sexit = tgetstr("se", &clearptr);
			if ((soglitch = tgetnum("sg")) < 0)
				soglitch = 0;

			/*
			 * Setup for underlining.  Some terminals don't need it,
			 * others have start/stop sequences, still others have
			 * an underline char sequence which is assumed to move
			 * the cursor forward one character.  If underline seq
			 * isn't available, settle for standout sequence.
			 */
			if (tgetflag("ul") || tgetflag("os"))
				ul_opt = 0;
			if ((chUL = tgetstr("uc", &clearptr)) == NULL)
				chUL = "";
			if (((ULenter = tgetstr("us", &clearptr)) == NULL ||
			    (ULexit = tgetstr("ue", &clearptr)) == NULL) &&
			    !*chUL) {
				if ((ULenter = Senter) == NULL ||
				    (ULexit = Sexit) == NULL) {
					ULenter = "";
					ULexit = "";
				} else
					ulglitch = soglitch;
			} else {
				if ((ulglitch = tgetnum("ug")) < 0)
					ulglitch = 0;
			}

			if ((padstr = tgetstr("pc", &clearptr)))
				PC = *padstr;
			Home = tgetstr("ho", &clearptr);
			if (Home == 0 || *Home == '\0') {
				cursorm = tgetstr("cm", &clearptr);
				if (cursorm != NULL) {
					strlcpy(cursorhome,
					    tgoto(cursorm, 0, 0),
					    sizeof(cursorhome));
					Home = cursorhome;
				}
			}
			EodClr = tgetstr("cd", &clearptr);
			if ((chBS = tgetstr("bc", &clearptr)) == NULL)
				chBS = "\b";
			if (tgetstr("te", &clearptr) != NULL &&
			    tgetstr("ti", &clearptr) != NULL)
				altscr = 1;
		}
		if ((shell = getenv("SHELL")) == NULL)
			shell = _PATH_BSHELL;
	}
	no_intty = !isatty(STDIN_FILENO);
	tcgetattr(STDERR_FILENO, &otty);
	slow_tty = cfgetospeed(&otty) < B1200;
	hardtabs = !(otty.c_oflag & OXTABS);
	ntty = otty;
	if (!no_tty) {
		ntty.c_lflag &= ~(ICANON|ECHO);
		ntty.c_cc[VMIN] = 1;	/* read at least 1 char */
		ntty.c_cc[VTIME] = 0;	/* no timeout */
	}
}
Esempio n. 26
0
int
main(int argc, char *argv[], char *envp[])
{
	extern int mdb_kvm_is_compressed_dump(mdb_io_t *);
	mdb_tgt_ctor_f *tgt_ctor = NULL;
	const char **tgt_argv = alloca(argc * sizeof (char *));
	int tgt_argc = 0;
	mdb_tgt_t *tgt;

	char object[MAXPATHLEN], execname[MAXPATHLEN];
	mdb_io_t *in_io, *out_io, *err_io, *null_io;
	struct termios tios;
	int status, c;
	char *p;

	const char *Iflag = NULL, *Lflag = NULL, *Vflag = NULL, *pidarg = NULL;
	int fflag = 0, Kflag = 0, Rflag = 0, Sflag = 0, Oflag = 0, Uflag = 0;

	int ttylike;
	int longmode = 0;

	stack_t sigstack;

	if (realpath(getexecname(), execname) == NULL) {
		(void) strncpy(execname, argv[0], MAXPATHLEN);
		execname[MAXPATHLEN - 1] = '\0';
	}

	mdb_create(execname, argv[0]);
	bzero(tgt_argv, argc * sizeof (char *));
	argv[0] = (char *)mdb.m_pname;
	_mdb_self_fd = open("/proc/self/as", O_RDONLY);

	mdb.m_env = envp;

	out_io = mdb_fdio_create(STDOUT_FILENO);
	mdb.m_out = mdb_iob_create(out_io, MDB_IOB_WRONLY);

	err_io = mdb_fdio_create(STDERR_FILENO);
	mdb.m_err = mdb_iob_create(err_io, MDB_IOB_WRONLY);
	mdb_iob_clrflags(mdb.m_err, MDB_IOB_AUTOWRAP);

	null_io = mdb_nullio_create();
	mdb.m_null = mdb_iob_create(null_io, MDB_IOB_WRONLY);

	in_io = mdb_fdio_create(STDIN_FILENO);
	if ((mdb.m_termtype = getenv("TERM")) != NULL) {
		mdb.m_termtype = strdup(mdb.m_termtype);
		mdb.m_flags |= MDB_FL_TERMGUESS;
	}
	mdb.m_term = NULL;

	mdb_dmode(mdb_dstr2mode(getenv("MDB_DEBUG")));
	mdb.m_pgid = getpgrp();

	if (getenv("_MDB_EXEC") != NULL)
		mdb.m_flags |= MDB_FL_EXEC;

	/*
	 * Setup an alternate signal stack.  When tearing down pipelines in
	 * terminate(), we may have to destroy the stack of the context in
	 * which we are currently executing the signal handler.
	 */
	sigstack.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
	    MAP_PRIVATE | MAP_ANON, -1, 0);
	if (sigstack.ss_sp == MAP_FAILED)
		die("could not allocate signal stack");
	sigstack.ss_size = SIGSTKSZ;
	sigstack.ss_flags = 0;
	if (sigaltstack(&sigstack, NULL) != 0)
		die("could not set signal stack");

	(void) mdb_signal_sethandler(SIGPIPE, SIG_IGN, NULL);
	(void) mdb_signal_sethandler(SIGQUIT, SIG_IGN, NULL);

	(void) mdb_signal_sethandler(SIGILL, flt_handler, NULL);
	(void) mdb_signal_sethandler(SIGTRAP, flt_handler, NULL);
	(void) mdb_signal_sethandler(SIGIOT, flt_handler, NULL);
	(void) mdb_signal_sethandler(SIGEMT, flt_handler, NULL);
	(void) mdb_signal_sethandler(SIGFPE, flt_handler, NULL);
	(void) mdb_signal_sethandler(SIGBUS, flt_handler, NULL);
	(void) mdb_signal_sethandler(SIGSEGV, flt_handler, NULL);

	(void) mdb_signal_sethandler(SIGHUP, (mdb_signal_f *)terminate, NULL);
	(void) mdb_signal_sethandler(SIGTERM, (mdb_signal_f *)terminate, NULL);

	for (mdb.m_rdvers = RD_VERSION; mdb.m_rdvers > 0; mdb.m_rdvers--) {
		if (rd_init(mdb.m_rdvers) == RD_OK)
			break;
	}

	for (mdb.m_ctfvers = CTF_VERSION; mdb.m_ctfvers > 0; mdb.m_ctfvers--) {
		if (ctf_version(mdb.m_ctfvers) != -1)
			break;
	}

	if ((p = getenv("HISTSIZE")) != NULL && strisnum(p)) {
		mdb.m_histlen = strtoi(p);
		if (mdb.m_histlen < 1)
			mdb.m_histlen = 1;
	}

	while (optind < argc) {
		while ((c = getopt(argc, argv,
		    "fkmo:p:s:uwyACD:FI:KL:MOP:R:SUV:W")) != (int)EOF) {
			switch (c) {
			case 'f':
				fflag++;
				tgt_ctor = mdb_rawfile_tgt_create;
				break;
			case 'k':
				tgt_ctor = mdb_kvm_tgt_create;
				break;
			case 'm':
				mdb.m_tgtflags |= MDB_TGT_F_NOLOAD;
				mdb.m_tgtflags &= ~MDB_TGT_F_PRELOAD;
				break;
			case 'o':
				if (!mdb_set_options(optarg, TRUE))
					terminate(2);
				break;
			case 'p':
				tgt_ctor = mdb_proc_tgt_create;
				pidarg = optarg;
				break;
			case 's':
				if (!strisnum(optarg)) {
					warn("expected integer following -s\n");
					terminate(2);
				}
				mdb.m_symdist = (size_t)(uint_t)strtoi(optarg);
				break;
			case 'u':
				tgt_ctor = mdb_proc_tgt_create;
				break;
			case 'w':
				mdb.m_tgtflags |= MDB_TGT_F_RDWR;
				break;
			case 'y':
				mdb.m_flags |= MDB_FL_USECUP;
				break;
			case 'A':
				(void) mdb_set_options("nomods", TRUE);
				break;
			case 'C':
				(void) mdb_set_options("noctf", TRUE);
				break;
			case 'D':
				mdb_dmode(mdb_dstr2mode(optarg));
				break;
			case 'F':
				mdb.m_tgtflags |= MDB_TGT_F_FORCE;
				break;
			case 'I':
				Iflag = optarg;
				break;
			case 'L':
				Lflag = optarg;
				break;
			case 'K':
				Kflag++;
				break;
			case 'M':
				mdb.m_tgtflags |= MDB_TGT_F_PRELOAD;
				mdb.m_tgtflags &= ~MDB_TGT_F_NOLOAD;
				break;
			case 'O':
				Oflag++;
				break;
			case 'P':
				if (!mdb_set_prompt(optarg))
					terminate(2);
				break;
			case 'R':
				(void) strncpy(mdb.m_root, optarg, MAXPATHLEN);
				mdb.m_root[MAXPATHLEN - 1] = '\0';
				Rflag++;
				break;
			case 'S':
				Sflag++;
				break;
			case 'U':
				Uflag++;
				break;
			case 'V':
				Vflag = optarg;
				break;
			case 'W':
				mdb.m_tgtflags |= MDB_TGT_F_ALLOWIO;
				break;
			case '?':
				if (optopt == '?')
					usage(0);
				/* FALLTHROUGH */
			default:
				usage(2);
			}
		}

		if (optind < argc) {
			const char *arg = argv[optind++];

			if (arg[0] == '+' && strlen(arg) == 2) {
				if (arg[1] != 'o') {
					warn("illegal option -- %s\n", arg);
					terminate(2);
				}
				if (optind >= argc) {
					warn("option requires an argument -- "
					    "%s\n", arg);
					terminate(2);
				}
				if (!mdb_set_options(argv[optind++], FALSE))
					terminate(2);
			} else
				tgt_argv[tgt_argc++] = arg;
		}
	}

	if (rd_ctl(RD_CTL_SET_HELPPATH, (void *)mdb.m_root) != RD_OK) {
		warn("cannot set librtld_db helper path to %s\n", mdb.m_root);
		terminate(2);
	}

	if (mdb.m_debug & MDB_DBG_HELP)
		terminate(0); /* Quit here if we've printed out the tokens */


	if (Iflag != NULL && strchr(Iflag, ';') != NULL) {
		warn("macro path cannot contain semicolons\n");
		terminate(2);
	}

	if (Lflag != NULL && strchr(Lflag, ';') != NULL) {
		warn("module path cannot contain semicolons\n");
		terminate(2);
	}

	if (Kflag || Uflag) {
		char *nm;

		if (tgt_ctor != NULL || Iflag != NULL) {
			warn("neither -f, -k, -p, -u, nor -I "
			    "may be used with -K\n");
			usage(2);
		}

		if (Lflag != NULL)
			mdb_set_lpath(Lflag);

		if ((nm = ttyname(STDIN_FILENO)) == NULL ||
		    strcmp(nm, "/dev/console") != 0) {
			/*
			 * Due to the consequences of typing mdb -K instead of
			 * mdb -k on a tty other than /dev/console, we require
			 * -F when starting kmdb from a tty other than
			 * /dev/console.
			 */
			if (!(mdb.m_tgtflags & MDB_TGT_F_FORCE)) {
				die("-F must also be supplied to start kmdb "
				    "from non-console tty\n");
			}

			if (mdb.m_termtype == NULL || (mdb.m_flags &
			    MDB_FL_TERMGUESS)) {
				if (mdb.m_termtype != NULL)
					strfree(mdb.m_termtype);

				if ((mdb.m_termtype = mdb_scf_console_term()) !=
				    NULL)
					mdb.m_flags |= MDB_FL_TERMGUESS;
			}
		} else {
			/*
			 * When on console, $TERM (if set) takes precedence over
			 * the SMF setting.
			 */
			if (mdb.m_termtype == NULL && (mdb.m_termtype =
			    mdb_scf_console_term()) != NULL)
				mdb.m_flags |= MDB_FL_TERMGUESS;
		}

		control_kmdb(Kflag);
		terminate(0);
		/*NOTREACHED*/
	}

	/*
	 * If standard input appears to have tty attributes, attempt to
	 * initialize a terminal i/o backend on top of stdin and stdout.
	 */
	ttylike = (IOP_CTL(in_io, TCGETS, &tios) == 0);
	if (ttylike) {
		if ((mdb.m_term = mdb_termio_create(mdb.m_termtype,
		    in_io, out_io)) == NULL) {
			if (!(mdb.m_flags & MDB_FL_EXEC)) {
				warn("term init failed: command-line editing "
				    "and prompt will not be available\n");
			}
		} else {
			in_io = mdb.m_term;
		}
	}

	mdb.m_in = mdb_iob_create(in_io, MDB_IOB_RDONLY);
	if (mdb.m_term != NULL) {
		mdb_iob_setpager(mdb.m_out, mdb.m_term);
		if (mdb.m_flags & MDB_FL_PAGER)
			mdb_iob_setflags(mdb.m_out, MDB_IOB_PGENABLE);
		else
			mdb_iob_clrflags(mdb.m_out, MDB_IOB_PGENABLE);
	} else if (ttylike)
		mdb_iob_setflags(mdb.m_in, MDB_IOB_TTYLIKE);
	else
		mdb_iob_setbuf(mdb.m_in, mdb_alloc(1, UM_SLEEP), 1);

	mdb_pservice_init();
	mdb_lex_reset();

	if ((mdb.m_shell = getenv("SHELL")) == NULL)
		mdb.m_shell = "/bin/sh";

	/*
	 * If the debugger state is to be inherited from a previous instance,
	 * restore it now prior to path evaluation so that %R is updated.
	 */
	if ((p = getenv(MDB_CONFIG_ENV_VAR)) != NULL) {
		mdb_set_config(p);
		(void) unsetenv(MDB_CONFIG_ENV_VAR);
	}

	/*
	 * Path evaluation part 1: Create the initial module path to allow
	 * the target constructor to load a support module.  Then expand
	 * any command-line arguments that modify the paths.
	 */
	if (Iflag != NULL)
		mdb_set_ipath(Iflag);
	else
		mdb_set_ipath(MDB_DEF_IPATH);

	if (Lflag != NULL)
		mdb_set_lpath(Lflag);
	else
		mdb_set_lpath(MDB_DEF_LPATH);

	if (mdb_get_prompt() == NULL && !(mdb.m_flags & MDB_FL_ADB))
		(void) mdb_set_prompt(MDB_DEF_PROMPT);

	if (tgt_ctor == mdb_kvm_tgt_create) {
		if (pidarg != NULL) {
			warn("-p and -k options are mutually exclusive\n");
			terminate(2);
		}

		if (tgt_argc == 0)
			tgt_argv[tgt_argc++] = "/dev/ksyms";
		if (tgt_argc == 1 && strisnum(tgt_argv[0]) == 0) {
			if (mdb.m_tgtflags & MDB_TGT_F_ALLOWIO)
				tgt_argv[tgt_argc++] = "/dev/allkmem";
			else
				tgt_argv[tgt_argc++] = "/dev/kmem";
		}
	}

	if (pidarg != NULL) {
		if (tgt_argc != 0) {
			warn("-p may not be used with other arguments\n");
			terminate(2);
		}
		if (proc_arg_psinfo(pidarg, PR_ARG_PIDS, NULL, &status) == -1) {
			die("cannot attach to %s: %s\n",
			    pidarg, Pgrab_error(status));
		}
		if (strchr(pidarg, '/') != NULL)
			(void) mdb_iob_snprintf(object, MAXPATHLEN,
			    "%s/object/a.out", pidarg);
		else
			(void) mdb_iob_snprintf(object, MAXPATHLEN,
			    "/proc/%s/object/a.out", pidarg);
		tgt_argv[tgt_argc++] = object;
		tgt_argv[tgt_argc++] = pidarg;
	}

	/*
	 * Find the first argument that is not a special "-" token.  If one is
	 * found, we will examine this file and make some inferences below.
	 */
	for (c = 0; c < tgt_argc && strcmp(tgt_argv[c], "-") == 0; c++)
		continue;

	if (c < tgt_argc) {
		Elf32_Ehdr ehdr;
		mdb_io_t *io;

		/*
		 * If special "-" tokens preceded an argument, shift the entire
		 * argument list to the left to remove the leading "-" args.
		 */
		if (c > 0) {
			bcopy(&tgt_argv[c], tgt_argv,
			    sizeof (const char *) * (tgt_argc - c));
			tgt_argc -= c;
		}

		if (fflag)
			goto tcreate; /* skip re-exec and just create target */

		/*
		 * If we just have an object file name, and that file doesn't
		 * exist, and it's a string of digits, infer it to be a
		 * sequence number referring to a pair of crash dump files.
		 */
		if (tgt_argc == 1 && access(tgt_argv[0], F_OK) == -1 &&
		    strisnum(tgt_argv[0])) {

			size_t len = strlen(tgt_argv[0]) + 8;
			const char *object = tgt_argv[0];

			tgt_argv[0] = mdb_alloc(len, UM_SLEEP);
			tgt_argv[1] = mdb_alloc(len, UM_SLEEP);

			(void) strcpy((char *)tgt_argv[0], "unix.");
			(void) strcat((char *)tgt_argv[0], object);
			(void) strcpy((char *)tgt_argv[1], "vmcore.");
			(void) strcat((char *)tgt_argv[1], object);

			if (access(tgt_argv[0], F_OK) == -1 &&
			    access(tgt_argv[1], F_OK) == -1) {
				(void) strcpy((char *)tgt_argv[1], "vmdump.");
				(void) strcat((char *)tgt_argv[1], object);
				if (access(tgt_argv[1], F_OK) == 0) {
					mdb_iob_printf(mdb.m_err,
					    "cannot open compressed dump; "
					    "decompress using savecore -f %s\n",
					    tgt_argv[1]);
					terminate(0);
				}
			}

			tgt_argc = 2;
		}

		/*
		 * We need to open the object file in order to determine its
		 * ELF class and potentially re-exec ourself.
		 */
		if ((io = mdb_fdio_create_path(NULL, tgt_argv[0],
		    O_RDONLY, 0)) == NULL)
			die("failed to open %s", tgt_argv[0]);

		/*
		 * Check for a single vmdump.N compressed dump file,
		 * and give a helpful message.
		 */
		if (tgt_argc == 1) {
			if (mdb_kvm_is_compressed_dump(io)) {
				mdb_iob_printf(mdb.m_err,
				    "cannot open compressed dump; "
				    "decompress using savecore -f %s\n",
				    tgt_argv[0]);
				terminate(0);
			}
		}

		/*
		 * If the target is unknown or is not the rawfile target, do
		 * a gelf_check to determine if the file is an ELF file.  If
		 * it is not and the target is unknown, use the rawfile tgt.
		 * Otherwise an ELF-based target is needed, so we must abort.
		 */
		if (mdb_gelf_check(io, &ehdr, ET_NONE) == -1) {
			if (tgt_ctor != NULL) {
				(void) mdb_gelf_check(io, &ehdr, ET_EXEC);
				mdb_io_destroy(io);
				terminate(1);
			} else
				tgt_ctor = mdb_rawfile_tgt_create;
		}

		mdb_io_destroy(io);

		if (identify_xvm_file(tgt_argv[0], &longmode) == 1) {
#ifdef _LP64
			if (!longmode)
				goto reexec;
#else
			if (longmode)
				goto reexec;
#endif
			tgt_ctor = mdb_kvm_tgt_create;
			goto tcreate;
		}

		/*
		 * The object file turned out to be a user core file (ET_CORE),
		 * and no other arguments were specified, swap 0 and 1.  The
		 * proc target will infer the executable for us.
		 */
		if (ehdr.e_type == ET_CORE) {
			tgt_argv[tgt_argc++] = tgt_argv[0];
			tgt_argv[0] = NULL;
			tgt_ctor = mdb_proc_tgt_create;
		}

		/*
		 * If tgt_argv[1] is filled in, open it up and determine if it
		 * is a vmcore file.  If it is, gelf_check will fail and we
		 * set tgt_ctor to 'kvm'; otherwise we use the default.
		 */
		if (tgt_argc > 1 && strcmp(tgt_argv[1], "-") != 0 &&
		    tgt_argv[0] != NULL && pidarg == NULL) {
			Elf32_Ehdr chdr;

			if (access(tgt_argv[1], F_OK) == -1)
				die("failed to access %s", tgt_argv[1]);

			/* *.N case: drop vmdump.N from the list */
			if (tgt_argc == 3) {
				if ((io = mdb_fdio_create_path(NULL,
				    tgt_argv[2], O_RDONLY, 0)) == NULL)
					die("failed to open %s", tgt_argv[2]);
				if (mdb_kvm_is_compressed_dump(io))
					tgt_argv[--tgt_argc] = NULL;
				mdb_io_destroy(io);
			}

			if ((io = mdb_fdio_create_path(NULL, tgt_argv[1],
			    O_RDONLY, 0)) == NULL)
				die("failed to open %s", tgt_argv[1]);

			if (mdb_gelf_check(io, &chdr, ET_NONE) == -1)
				tgt_ctor = mdb_kvm_tgt_create;

			mdb_io_destroy(io);
		}

		/*
		 * At this point, we've read the ELF header for either an
		 * object file or core into ehdr.  If the class does not match
		 * ours, attempt to exec the mdb of the appropriate class.
		 */
#ifdef _LP64
		if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
			goto reexec;
#else
		if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
			goto reexec;
#endif
	}

tcreate:
	if (tgt_ctor == NULL)
		tgt_ctor = mdb_proc_tgt_create;

	tgt = mdb_tgt_create(tgt_ctor, mdb.m_tgtflags, tgt_argc, tgt_argv);

	if (tgt == NULL) {
		if (errno == EINVAL)
			usage(2); /* target can return EINVAL to get usage */
		if (errno == EMDB_TGT)
			terminate(1); /* target already printed error msg */
		die("failed to initialize target");
	}

	mdb_tgt_activate(tgt);

	mdb_create_loadable_disasms();

	if (Vflag != NULL && mdb_dis_select(Vflag) == -1)
		warn("invalid disassembler mode -- %s\n", Vflag);


	if (Rflag && mdb.m_term != NULL)
		warn("Using proto area %s\n", mdb.m_root);

	/*
	 * If the target was successfully constructed and -O was specified,
	 * we now attempt to enter piggy-mode for debugging jurassic problems.
	 */
	if (Oflag) {
		pcinfo_t pci;

		(void) strcpy(pci.pc_clname, "RT");

		if (priocntl(P_LWPID, P_MYID, PC_GETCID, (caddr_t)&pci) != -1) {
			pcparms_t pcp;
			rtparms_t *rtp = (rtparms_t *)pcp.pc_clparms;

			rtp->rt_pri = 35;
			rtp->rt_tqsecs = 0;
			rtp->rt_tqnsecs = RT_TQDEF;

			pcp.pc_cid = pci.pc_cid;

			if (priocntl(P_LWPID, P_MYID, PC_SETPARMS,
			    (caddr_t)&pcp) == -1) {
				warn("failed to set RT parameters");
				Oflag = 0;
			}
		} else {
			warn("failed to get RT class id");
			Oflag = 0;
		}

		if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
			warn("failed to lock address space");
			Oflag = 0;
		}

		if (Oflag)
			mdb_printf("%s: oink, oink!\n", mdb.m_pname);
	}

	/*
	 * Path evaluation part 2: Re-evaluate the path now that the target
	 * is ready (and thus we have access to the real platform string).
	 * Do this before reading ~/.mdbrc to allow path modifications prior
	 * to performing module auto-loading.
	 */
	mdb_set_ipath(mdb.m_ipathstr);
	mdb_set_lpath(mdb.m_lpathstr);

	if (!Sflag && (p = getenv("HOME")) != NULL) {
		char rcpath[MAXPATHLEN];
		mdb_io_t *rc_io;
		int fd;

		(void) mdb_iob_snprintf(rcpath, MAXPATHLEN, "%s/.mdbrc", p);
		fd = open64(rcpath, O_RDONLY);

		if (fd >= 0 && (rc_io = mdb_fdio_create_named(fd, rcpath))) {
			mdb_iob_t *iob = mdb_iob_create(rc_io, MDB_IOB_RDONLY);
			mdb_iob_t *old = mdb.m_in;

			mdb.m_in = iob;
			(void) mdb_run();
			mdb.m_in = old;
		}
	}

	if (!(mdb.m_flags & MDB_FL_NOMODS))
		mdb_module_load_all(0);

	(void) mdb_signal_sethandler(SIGINT, int_handler, NULL);
	while ((status = mdb_run()) == MDB_ERR_ABORT ||
	    status == MDB_ERR_OUTPUT) {
		/*
		 * If a write failed on stdout, give up.  A more informative
		 * error message will already have been printed by mdb_run().
		 */
		if (status == MDB_ERR_OUTPUT &&
		    mdb_iob_getflags(mdb.m_out) & MDB_IOB_ERR) {
			mdb_warn("write to stdout failed, exiting\n");
			break;
		}
		continue;
	}

	terminate((status == MDB_ERR_QUIT || status == 0) ? 0 : 1);
	/*NOTREACHED*/
	return (0);

reexec:
	if ((p = strrchr(execname, '/')) == NULL)
		die("cannot determine absolute pathname\n");
#ifdef _LP64
#ifdef __sparc
	(void) strcpy(p, "/../sparcv7/");
#else
	(void) strcpy(p, "/../i86/");
#endif
#else
#ifdef __sparc
	(void) strcpy(p, "/../sparcv9/");
#else
	(void) strcpy(p, "/../amd64/");
#endif
#endif
	(void) strcat(p, mdb.m_pname);

	if (mdb.m_term != NULL)
		(void) IOP_CTL(in_io, TCSETSW, &tios);

	(void) putenv("_MDB_EXEC=1");
	(void) execv(execname, argv);

	/*
	 * If execv fails, suppress ENOEXEC.  Experience shows the most common
	 * reason is that the machine is booted under a 32-bit kernel, in which
	 * case it is clearer to only print the message below.
	 */
	if (errno != ENOEXEC)
		warn("failed to exec %s", execname);
#ifdef _LP64
	die("64-bit %s cannot debug 32-bit program %s\n",
	    mdb.m_pname, tgt_argv[0] ?
	    tgt_argv[0] : tgt_argv[1]);
#else
	die("32-bit %s cannot debug 64-bit program %s\n",
	    mdb.m_pname, tgt_argv[0] ?
	    tgt_argv[0] : tgt_argv[1]);
#endif

	goto tcreate;
}
Esempio n. 27
0
int main(int argc, char **argv) {
    int i, n;
    char **origenv;
    char **newenv;
    char *cwd;
    FILE *log = fopen(abs_builddir "/commandhelper.log", "w");

    if (!log)
        goto error;

    for (i = 1 ; i < argc ; i++) {
        fprintf(log, "ARG:%s\n", argv[i]);
    }

    origenv = environ;
    n = 0;
    while (*origenv != NULL) {
        n++;
        origenv++;
    }

    if (VIR_ALLOC_N(newenv, n) < 0) {
        exit(EXIT_FAILURE);
    }

    origenv = environ;
    n = i = 0;
    while (*origenv != NULL) {
        newenv[i++] = *origenv;
        n++;
        origenv++;
    }
    qsort(newenv, n, sizeof(newenv[0]), envsort);

    for (i = 0 ; i < n ; i++) {
        /* Ignore the variables used to instruct the loader into
         * behaving differently, as they could throw the tests off. */
        if (!STRPREFIX(newenv[i], "LD_"))
            fprintf(log, "ENV:%s\n", newenv[i]);
    }

    for (i = 0 ; i < sysconf(_SC_OPEN_MAX) ; i++) {
        int f;
        int closed;
        if (i == fileno(log))
            continue;
        closed = fcntl(i, F_GETFD, &f) == -1 &&
            errno == EBADF;
        if (!closed)
            fprintf(log, "FD:%d\n", i);
    }

    fprintf(log, "DAEMON:%s\n", getpgrp() == getsid(0) ? "yes" : "no");
    if (!(cwd = getcwd(NULL, 0)))
        return EXIT_FAILURE;
    if (strlen(cwd) > strlen(".../commanddata") &&
        STREQ(cwd + strlen(cwd) - strlen("/commanddata"), "/commanddata"))
        strcpy(cwd, ".../commanddata");
    fprintf(log, "CWD:%s\n", cwd);
    VIR_FREE(cwd);

    VIR_FORCE_FCLOSE(log);

    char buf[1024];
    ssize_t got;

    fprintf(stdout, "BEGIN STDOUT\n");
    fflush(stdout);
    fprintf(stderr, "BEGIN STDERR\n");
    fflush(stderr);

    for (;;) {
        got = read(STDIN_FILENO, buf, sizeof(buf));
        if (got < 0)
            goto error;
        if (got == 0)
            break;
        if (safewrite(STDOUT_FILENO, buf, got) != got)
            goto error;
        if (safewrite(STDERR_FILENO, buf, got) != got)
            goto error;
    }

    fprintf(stdout, "END STDOUT\n");
    fflush(stdout);
    fprintf(stderr, "END STDERR\n");
    fflush(stderr);

    return EXIT_SUCCESS;

error:
    return EXIT_FAILURE;
}
Esempio n. 28
0
/*
 *  stress_ptrace()
 *	stress ptracing
 */
static int stress_ptrace(const args_t *args)
{
	pid_t pid;

	pid = fork();
	if (pid < 0) {
		pr_fail_dbg("fork");
		return EXIT_FAILURE;
	} else if (pid == 0) {
		(void)setpgid(0, g_pgrp);
		stress_parent_died_alarm();

		/*
		 * Child to be traced, we abort if we detect
		 * we are already being traced by someone else
		 * as this makes life way too complex
		 */
		if (ptrace(PTRACE_TRACEME) != 0) {
			pr_fail("%s: ptrace child being traced "
				"already, aborting\n", args->name);
			_exit(0);
		}
		/* Wait for parent to start tracing me */
		(void)kill(getpid(), SIGSTOP);

		/*
		 *  A simple mix of system calls
		 */
		while (g_keep_stressing_flag) {
			pid_t pidtmp;
			gid_t gidtmp;
			uid_t uidtmp;
			time_t ttmp;

			pidtmp = getppid();
			(void)pidtmp;

#if defined(HAVE_GETPGRP)
			pidtmp = getpgrp();
			(void)pidtmp;
#endif

			gidtmp = getgid();
			(void)gidtmp;

			gidtmp = getegid();
			(void)gidtmp;

			uidtmp = getuid();
			(void)uidtmp;

			uidtmp = geteuid();
			(void)uidtmp;

			ttmp = time(NULL);
			(void)ttmp;
		}
		_exit(0);
	} else {
		/* Parent to do the tracing */
		int status;

		(void)setpgid(pid, g_pgrp);

		if (shim_waitpid(pid, &status, 0) < 0) {
			if (errno != EINTR) {
				pr_fail_dbg("waitpid");
				return EXIT_FAILURE;
			}
			return EXIT_SUCCESS;
		}
		if (ptrace(PTRACE_SETOPTIONS, pid,
			0, PTRACE_O_TRACESYSGOOD) < 0) {
			pr_fail_dbg("ptrace");
			return EXIT_FAILURE;
		}

		do {
			/*
			 *  We do two of the following per syscall,
			 *  one at the start, and one at the end to catch
			 *  the return.  In this stressor we don't really
			 *  care which is which, we just care about counting
			 *  them
			 */
			if (stress_syscall_wait(args, pid))
				break;
			inc_counter(args);
		} while (keep_stressing());

		/* Terminate child */
		(void)kill(pid, SIGKILL);
		if (shim_waitpid(pid, &status, 0) < 0)
			pr_fail_dbg("waitpid");
	}
	return EXIT_SUCCESS;
}
Esempio n. 29
0
int
physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
             int *auxfd, int *nauxfd)
{
  struct device *h;
  int sz;

  h = NULL;
  if (p) {
    hdlc_StopTimer(&p->hdlc);
    lqr_StopTimer(p);
    timer_Stop(&p->link.lcp.fsm.FsmTimer);
    timer_Stop(&p->link.ccp.fsm.FsmTimer);
    timer_Stop(&p->link.lcp.fsm.OpenTimer);
    timer_Stop(&p->link.ccp.fsm.OpenTimer);
    timer_Stop(&p->link.lcp.fsm.StoppedTimer);
    timer_Stop(&p->link.ccp.fsm.StoppedTimer);
    if (p->handler) {
      h = p->handler;
      p->handler = (struct device *)(long)p->handler->type;
    }

    if (Enabled(p->dl->bundle, OPT_KEEPSESSION) ||
        tcgetpgrp(p->fd) == getpgrp())
      p->session_owner = getpid();      /* So I'll eventually get HUP'd */
    else
      p->session_owner = (pid_t)-1;
    timer_Stop(&p->link.stats.total.Timer);
  }

  if (*niov + 2 >= maxiov) {
    log_Printf(LogERROR, "physical2iov: No room for physical + throughput"
               " + device !\n");
    if (p)
      free(p);
    return -1;
  }

  iov[*niov].iov_base = (void *)p;
  iov[*niov].iov_len = sizeof *p;
  (*niov)++;

  iov[*niov].iov_base = p ? (void *)p->link.stats.total.in.SampleOctets : NULL;
  iov[*niov].iov_len = SAMPLE_PERIOD * sizeof(long long);
  (*niov)++;
  iov[*niov].iov_base = p ? (void *)p->link.stats.total.out.SampleOctets : NULL;
  iov[*niov].iov_len = SAMPLE_PERIOD * sizeof(long long);
  (*niov)++;

  sz = physical_MaxDeviceSize();
  if (p) {
    if (h && h->device2iov)
      (*h->device2iov)(h, iov, niov, maxiov, auxfd, nauxfd);
    else {
      iov[*niov].iov_base = malloc(sz);
      if (h)
        memcpy(iov[*niov].iov_base, h, sizeof *h);
      iov[*niov].iov_len = sz;
      (*niov)++;
    }
  } else {
    iov[*niov].iov_base = NULL;
    iov[*niov].iov_len = sz;
    (*niov)++;
  }

  return p ? p->fd : 0;
}
Esempio n. 30
0
int os_getpgrp(void)
{
	return getpgrp();
}