Exemplo n.º 1
0
static cv::Mat generateRadianceMap(const cv::Mat& rc)
{
  cv::Size size = getImage(0).size();
  
  cv::Mat_<cv::Vec3f> radiance(size);
  
  for (int y = 0; y < size.height; ++y) {
    for (int x = 0; x < size.width; ++x) {
      cv::Vec3f sum(0,0,0), wsum(0,0,0);
      
      for (int p = 0, n = numImages(); p < n; ++p) {
        const cv::Mat& img = getImage(p);
        cv::Vec3b c = img.at<cv::Vec3b>(y, x);
        float exptime = getExposureTime(p);
        
        cv::Vec3f tmp, wtmp(weight(c[0]), weight(c[1]), weight(c[2]));
        tmp[0] = (rc.at<float>(c[0], 0) - std::log(exptime)) * wtmp[0];
        tmp[1] = (rc.at<float>(c[1], 1) - std::log(exptime)) * wtmp[1];
        tmp[2] = (rc.at<float>(c[2], 2) - std::log(exptime)) * wtmp[2];
        sum += tmp;
        wsum += wtmp;
      }
      
      cv::Vec3f tmp;
      tmp[0] = std::exp( sum[0] / wsum[0] );
      tmp[1] = std::exp( sum[1] / wsum[1] );
      tmp[2] = std::exp( sum[2] / wsum[2] );
      
      radiance.at<cv::Vec3f>(y, x) = tmp;
    }
  }
  
  return radiance;
}
Exemplo n.º 2
0
int
main(int argc, char **argv) {
	extern int	optind;
	extern char	*optarg;
	int	ch;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	while ((ch = getopt(argc, argv, "0123456789yli:f:h:t:")) != -1)
		switch((char)ch) {
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			/*
			 * kludge: last was originally designed to take
			 * a number after a dash.
			 */
			if (!maxrec)
				maxrec = atol(argv[optind - 1] + 1);
			break;
		case 'f':
			file = optarg;
			break;
		case 'h':
			hostconv(optarg);
			addarg(HOST_TYPE, optarg);
			break;
		case 't':
			addarg(TTY_TYPE, ttyconv(optarg));
			break;
		case 'y':
			doyear = 1;
			break;
		case 'l':
			dolong = 1;
			break;
		case 'i':
			addarg(INET_TYPE, optarg);
			break;
		case '?':
		default:
			fputs(_("usage: last [-#] [-f file] [-t tty] [-h hostname] [user ...]\n"), stderr);
			exit(1);
		}
	for (argv += optind; *argv; ++argv) {
#define	COMPATIBILITY
#ifdef	COMPATIBILITY
		/* code to allow "last p5" to work */
		addarg(TTY_TYPE, ttyconv(*argv));
#endif
		addarg(USER_TYPE, *argv);
	}
	wtmp();
	exit(0);
}
Exemplo n.º 3
0
Topology::Topology(const RuntimeEnvironment *renv) :
	RR(renv),
	_amRoot(false)
{
	std::string alls(RR->node->dataStoreGet("peers.save"));
	const uint8_t *all = reinterpret_cast<const uint8_t *>(alls.data());
	RR->node->dataStoreDelete("peers.save");

	Buffer<ZT_PEER_SUGGESTED_SERIALIZATION_BUFFER_SIZE> *deserializeBuf = new Buffer<ZT_PEER_SUGGESTED_SERIALIZATION_BUFFER_SIZE>();
	unsigned int ptr = 0;
	while ((ptr + 4) < alls.size()) {
		try {
			const unsigned int reclen = ( // each Peer serialized record is prefixed by a record length
					((((unsigned int)all[ptr]) & 0xff) << 24) |
					((((unsigned int)all[ptr + 1]) & 0xff) << 16) |
					((((unsigned int)all[ptr + 2]) & 0xff) << 8) |
					(((unsigned int)all[ptr + 3]) & 0xff)
				);
			unsigned int pos = 0;
			deserializeBuf->copyFrom(all + ptr,reclen + 4);
			SharedPtr<Peer> p(Peer::deserializeNew(RR,RR->identity,*deserializeBuf,pos));
			ptr += pos;
			if (!p)
				break; // stop if invalid records
			if (p->address() != RR->identity.address())
				_peers.set(p->address(),p);
		} catch ( ... ) {
			break; // stop if invalid records
		}
	}
	delete deserializeBuf;

	clean(RR->node->now());

	std::string dsWorld(RR->node->dataStoreGet("world"));
	World cachedWorld;
	if (dsWorld.length() > 0) {
		try {
			Buffer<ZT_WORLD_MAX_SERIALIZED_LENGTH> dswtmp(dsWorld.data(),(unsigned int)dsWorld.length());
			cachedWorld.deserialize(dswtmp,0);
		} catch ( ... ) {
			cachedWorld = World(); // clear if cached world is invalid
		}
	}
	World defaultWorld;
	{
		Buffer<ZT_DEFAULT_WORLD_LENGTH> wtmp(ZT_DEFAULT_WORLD,ZT_DEFAULT_WORLD_LENGTH);
		defaultWorld.deserialize(wtmp,0); // throws on error, which would indicate a bad static variable up top
	}
	if (cachedWorld.shouldBeReplacedBy(defaultWorld,false)) {
		_setWorld(defaultWorld);
		if (dsWorld.length() > 0)
			RR->node->dataStoreDelete("world");
	} else _setWorld(cachedWorld);
}
Exemplo n.º 4
0
int
main(int argc, char *argv[])
{
	const char *errstr;
	int ch, lastch = '\0', newarg = 1, prevoptind = 1;

	while ((ch = getopt(argc, argv, "0123456789cf:h:n:st:d:T")) != -1) {
		switch (ch) {
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			/*
			 * kludge: last was originally designed to take
			 * a number after a dash.
			 */
			if (newarg || !isdigit(lastch))
				maxrec = 0;
			else if (maxrec > INT_MAX / 10)
				usage();
			maxrec = (maxrec * 10) + (ch - '0');
			break;
		case 'c':
			calculate++;
			break;
		case 'f':
			file = optarg;
			break;
		case 'h':
			hostconv(optarg);
			addarg(HOST_TYPE, optarg);
			break;
		case 'n':
			maxrec = strtonum(optarg, 0, LONG_MAX, &errstr);
			if (errstr != NULL)
				errx(1, "number of lines is %s: %s", errstr,
				    optarg);
			if (maxrec == 0)
				exit(0);
			break;
		case 's':
			seconds++;
			break;
		case 't':
			addarg(TTY_TYPE, ttyconv(optarg));
			break;
		case 'd':
			snaptime = dateconv(optarg);
			break;
		case 'T':
			fulltime = 1;
			break;
		default:
			usage();
		}
		lastch = ch;
		newarg = optind != prevoptind;
		prevoptind = optind;
	}
	if (maxrec == 0)
		exit(0);

	if (argc) {
		setlinebuf(stdout);
		for (argv += optind; *argv; ++argv) {
#define	COMPATIBILITY
#ifdef	COMPATIBILITY
			/* code to allow "last p5" to work */
			addarg(TTY_TYPE, ttyconv(*argv));
#endif
			addarg(USER_TYPE, *argv);
		}
	}

	checkargs();
	wtmp();
	exit(0);
}
Exemplo n.º 5
0
Arquivo: last.c Projeto: Hooman3/minix
int
main(int argc, char *argv[])
{
	int ch;
	char *p;
	const char *file = NULL;
	int namesize = UT_NAMESIZE;
	int linesize = UT_LINESIZE;
	int hostsize = UT_HOSTSIZE;
	int numeric = 0;

	maxrec = -1;

	while ((ch = getopt(argc, argv, "0123456789f:H:h:L:nN:Tt:x")) != -1)
		switch (ch) {
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			/*
			 * kludge: last was originally designed to take
			 * a number after a dash.
			 */
			if (maxrec == -1) {
				p = argv[optind - 1];
				if (p[0] == '-' && p[1] == ch && !p[2])
					maxrec = atol(++p);
				else if (optind < argc)
					maxrec = atol(argv[optind] + 1);
				else
					usage();
				if (!maxrec)
					return 0;
			}
			break;
		case 'f':
			file = optarg;
			if ('\0' == file[0])
				usage();
			break;
		case 'H':
			hostsize = atoi(optarg);
			if (hostsize < 1)
				usage();
			break;
		case 'h':
			hostconv(optarg);
			addarg(HOST_TYPE, optarg);
			break;
		case 'L':
			linesize = atoi(optarg);
			if (linesize < 1)
				usage();
			break;
		case 'N':
			namesize = atoi(optarg);
			if (namesize < 1)
				usage();
			break;
		case 'n':
			numeric = 1;
			break;
		case 'T':
			fulltime = 1;
			break;
		case 't':
			addarg(TTY_TYPE, ttyconv(optarg));
			break;
		case 'x':
			xflag = 1;
			break;
		case '?':
		default:
			usage();
		}

	if (argc) {
		setlinebuf(stdout);
		for (argv += optind; *argv; ++argv) {
#define	COMPATIBILITY
#ifdef	COMPATIBILITY
			/* code to allow "last p5" to work */
			addarg(TTY_TYPE, ttyconv(*argv));
#endif
			addarg(USER_TYPE, *argv);
		}
	}
	if (file == NULL) {
#ifdef SUPPORT_UTMPX
		if (access(_PATH_WTMPX, R_OK) == 0)
			file = _PATH_WTMPX;
		else
#endif
#ifdef SUPPORT_UTMP
		if (access(_PATH_WTMP, R_OK) == 0)
			file = _PATH_WTMP;
#endif
		if (file == NULL)
#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
			errx(EXIT_FAILURE, "Cannot access `%s' or `%s'", _PATH_WTMPX,
			    _PATH_WTMP);
#elif defined(SUPPORT_UTMPX)
			errx(EXIT_FAILURE, "Cannot access `%s'", _PATH_WTMPX);
#elif defined(SUPPORT_UTMP)
			errx(EXIT_FAILURE, "Cannot access `%s'", _PATH_WTMP);
#else
			errx(EXIT_FAILURE, "No utmp or utmpx support compiled in.");
#endif
	}
#if defined(SUPPORT_UTMPX) && defined(SUPPORT_UTMP)
	if (file[strlen(file) - 1] == 'x' || xflag)
		wtmpx(file, namesize, linesize, hostsize, numeric);
	else
		wtmp(file, namesize, linesize, hostsize, numeric);
#elif defined(SUPPORT_UTMPX)
	wtmpx(file, namesize, linesize, hostsize, numeric);
#elif defined(SUPPORT_UTMP)
	wtmp(file, namesize, linesize, hostsize, numeric);
#else
	errx(EXIT_FAILURE, "No utmp or utmpx support compiled in.");
#endif
	exit(EXIT_SUCCESS);
}
Exemplo n.º 6
0
void nmf(viennacl::matrix_base<NumericT> const & V,
         viennacl::matrix_base<NumericT>       & W,
         viennacl::matrix_base<NumericT>       & H,
         viennacl::linalg::nmf_config const & conf)
{
  viennacl::hsa::context & ctx = const_cast<viennacl::hsa::context &>(viennacl::traits::hsa_context(V));

  const std::string NMF_MUL_DIV_KERNEL = "el_wise_mul_div";

  viennacl::linalg::opencl::kernels::nmf<NumericT, viennacl::hsa::context>::init(ctx);

  vcl_size_t k = W.size2();
  conf.iters_ = 0;

  if (viennacl::linalg::norm_frobenius(W) <= 0)
    W = viennacl::scalar_matrix<NumericT>(W.size1(), W.size2(), NumericT(1), ctx);

  if (viennacl::linalg::norm_frobenius(H) <= 0)
    H = viennacl::scalar_matrix<NumericT>(H.size1(), H.size2(), NumericT(1), ctx);

  viennacl::matrix_base<NumericT> wn(V.size1(), k, W.row_major(), ctx);
  viennacl::matrix_base<NumericT> wd(V.size1(), k, W.row_major(), ctx);
  viennacl::matrix_base<NumericT> wtmp(V.size1(), V.size2(), W.row_major(), ctx);

  viennacl::matrix_base<NumericT> hn(k, V.size2(), H.row_major(), ctx);
  viennacl::matrix_base<NumericT> hd(k, V.size2(), H.row_major(), ctx);
  viennacl::matrix_base<NumericT> htmp(k, k, H.row_major(), ctx);

  viennacl::matrix_base<NumericT> appr(V.size1(), V.size2(), V.row_major(), ctx);

  NumericT last_diff = 0;
  NumericT diff_init = 0;
  bool stagnation_flag = false;

  for (vcl_size_t i = 0; i < conf.max_iterations(); i++)
  {
    conf.iters_ = i + 1;
    {
      hn = viennacl::linalg::prod(trans(W), V);
      htmp = viennacl::linalg::prod(trans(W), W);
      hd = viennacl::linalg::prod(htmp, H);

      viennacl::hsa::kernel & mul_div_kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::nmf<NumericT>::program_name(), NMF_MUL_DIV_KERNEL);
      viennacl::hsa::enqueue(mul_div_kernel(H, hn, hd, cl_uint(H.internal_size1() * H.internal_size2())));
    }
    {
      wn = viennacl::linalg::prod(V, trans(H));
      wtmp = viennacl::linalg::prod(W, H);
      wd = viennacl::linalg::prod(wtmp, trans(H));

      viennacl::hsa::kernel & mul_div_kernel = ctx.get_kernel(viennacl::linalg::opencl::kernels::nmf<NumericT>::program_name(), NMF_MUL_DIV_KERNEL);

      viennacl::hsa::enqueue(mul_div_kernel(W, wn, wd, cl_uint(W.internal_size1() * W.internal_size2())));
    }

    if (i % conf.check_after_steps() == 0)  //check for convergence
    {
      appr = viennacl::linalg::prod(W, H);

      appr -= V;
      NumericT diff_val = viennacl::linalg::norm_frobenius(appr);

      if (i == 0)
        diff_init = diff_val;

      if (conf.print_relative_error())
        std::cout << diff_val / diff_init << std::endl;

      // Approximation check
      if (diff_val / diff_init < conf.tolerance())
        break;

      // Stagnation check
      if (std::fabs(diff_val - last_diff) / (diff_val * NumericT(conf.check_after_steps())) < conf.stagnation_tolerance()) //avoid situations where convergence stagnates
      {
        if (stagnation_flag)    // iteration stagnates (two iterates with no notable progress)
          break;
        else
          // record stagnation in this iteration
          stagnation_flag = true;
      } else
        // good progress in this iteration, so unset stagnation flag
        stagnation_flag = false;

      // prepare for next iterate:
      last_diff = diff_val;
    }
  }
}
Exemplo n.º 7
0
    void nmf(viennacl::matrix<ScalarType> const & v,
             viennacl::matrix<ScalarType> & w,
             viennacl::matrix<ScalarType> & h,
             std::size_t k,
             ScalarType eps = 0.000001,
             std::size_t max_iter = 10000,
             std::size_t check_diff_every_step = 100)
    {
      viennacl::linalg::kernels::nmf<ScalarType, 1>::init();
      
      w.resize(v.size1(), k);
      h.resize(k, v.size2());

      std::vector<ScalarType> stl_w(w.internal_size1() * w.internal_size2());
      std::vector<ScalarType> stl_h(h.internal_size1() * h.internal_size2());

      for (std::size_t j = 0; j < stl_w.size(); j++)
          stl_w[j] = static_cast<ScalarType>(rand()) / RAND_MAX;

      for (std::size_t j = 0; j < stl_h.size(); j++)
          stl_h[j] = static_cast<ScalarType>(rand()) / RAND_MAX;

      viennacl::matrix<ScalarType> wn(v.size1(), k);
      viennacl::matrix<ScalarType> wd(v.size1(), k);
      viennacl::matrix<ScalarType> wtmp(v.size1(), v.size2());

      viennacl::matrix<ScalarType> hn(k, v.size2());
      viennacl::matrix<ScalarType> hd(k, v.size2());
      viennacl::matrix<ScalarType> htmp(k, k);

      viennacl::matrix<ScalarType> appr(v.size1(), v.size2());
      viennacl::vector<ScalarType> diff(v.size1() * v.size2());

      viennacl::fast_copy(&stl_w[0], &stl_w[0] + stl_w.size(), w);
      viennacl::fast_copy(&stl_h[0], &stl_h[0] + stl_h.size(), h);

      ScalarType last_diff = 0.0f;


      
      for (std::size_t i = 0; i < max_iter; i++)
      {
        {
          hn = viennacl::linalg::prod(trans(w), v);
          htmp = viennacl::linalg::prod(trans(w), w);
          hd = viennacl::linalg::prod(htmp, h);

          viennacl::ocl::kernel & mul_div_kernel = viennacl::ocl::get_kernel(viennacl::linalg::kernels::nmf<ScalarType, 1>::program_name(), 
                                                                             NMF_MUL_DIV_KERNEL);
          viennacl::ocl::enqueue(mul_div_kernel(h, hn, hd, cl_uint(stl_h.size())));
        }
        {
          wn = viennacl::linalg::prod(v, trans(h));
          wtmp = viennacl::linalg::prod(w, h);
          wd = viennacl::linalg::prod(wtmp, trans(h));

          viennacl::ocl::kernel & mul_div_kernel = viennacl::ocl::get_kernel(viennacl::linalg::kernels::nmf<ScalarType, 1>::program_name(), 
                                                                             NMF_MUL_DIV_KERNEL);
          
          viennacl::ocl::enqueue(mul_div_kernel(w, wn, wd, cl_uint(stl_w.size())));
        }

        if (i % check_diff_every_step == 0)
        {
          appr = viennacl::linalg::prod(w, h);

         viennacl::ocl::kernel & sub_kernel = viennacl::ocl::get_kernel(viennacl::linalg::kernels::nmf<ScalarType, 1>::program_name(), 
                                                                        NMF_SUB_KERNEL);
          //this is a cheat. i.e save difference of two matrix into vector to get norm_2
          viennacl::ocl::enqueue(sub_kernel(appr, v, diff, cl_uint(v.size1() * v.size2())));
          ScalarType diff_val = viennacl::linalg::norm_2(diff);

          if((diff_val < eps) || (fabs(diff_val - last_diff) < eps))
          {
              //std::cout << "Breaked at diff - " << diff_val << "\n";
              break;
          }

          last_diff = diff_val;

          //printf("Iteration #%lu - %.5f \n", i, diff_val);
        }
      }
      
      
    }
Exemplo n.º 8
0
Arquivo: init.c Projeto: Ga-vin/MINIX3
int main(void)
{
  pid_t pid;			/* pid of child process */
  int fd;			/* generally useful */
  int linenr;			/* loop variable */
  int check;			/* check if a new process must be spawned */
  int sn;			/* signal number */
  struct slotent *slotp;	/* slots[] pointer */
  struct ttyent *ttyp;		/* ttytab entry */
  struct sigaction sa;
  struct stat stb;

#define OPENFDS						\
  if (fstat(0, &stb) < 0) {				\
	/* Open standard input, output & error. */	\
	(void) open("/dev/null", O_RDONLY);		\
	(void) open("/dev/log", O_WRONLY);		\
	dup(1);						\
  }

  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;

  /* Default: Ignore every signal (except those that follow). */
  sa.sa_handler = SIG_IGN;
  for (sn = 1; sn < _NSIG; sn++) {
      sigaction(sn, &sa, NULL);
  }

  /* Hangup: Reexamine /etc/ttytab for newly enabled terminal lines. */
  sa.sa_handler = onhup;
  sigaction(SIGHUP, &sa, NULL);

  /* Terminate: Stop spawning login processes, shutdown is near. */
  sa.sa_handler = onterm;
  sigaction(SIGTERM, &sa, NULL);

  /* Abort: Sent by the kernel on CTRL-ALT-DEL; shut the system down. */
  sa.sa_handler = onabrt;
  sigaction(SIGABRT, &sa, NULL);

  /* Execute the /etc/rc file. */
  if ((pid = fork()) != 0) {
	/* Parent just waits. */
	while (wait(NULL) != pid) {
		if (gotabrt) reboot(RBT_HALT);
	}
  } else {
#if ! SYS_GETKENV
	struct sysgetenv sysgetenv;
#endif
	char bootopts[16];
	static char *rc_command[] = { "sh", "/etc/rc", NULL, NULL, NULL };
	char **rcp = rc_command + 2;

	/* Get the boot options from the boot environment. */
	sysgetenv.key = "bootopts";
	sysgetenv.keylen = 8+1;
	sysgetenv.val = bootopts;
	sysgetenv.vallen = sizeof(bootopts);
	if (svrctl(PMGETPARAM, &sysgetenv) == 0) *rcp++ = bootopts;
	*rcp = "start";

	execute(rc_command);
	report(2, "sh /etc/rc");
	_exit(1);	/* impossible, we hope */
  }

  OPENFDS;

  /* Clear /etc/utmp if it exists. */
  if ((fd = open(PATH_UTMP, O_WRONLY | O_TRUNC)) >= 0) close(fd);

  /* Log system reboot. */
  wtmp(BOOT_TIME, 0, NULL, 0);

  /* Main loop. If login processes have already been started up, wait for one
   * to terminate, or for a HUP signal to arrive. Start up new login processes
   * for all ttys which don't have them. Note that wait() also returns when
   * somebody's orphan dies, in which case ignore it.  If the TERM signal is
   * sent then stop spawning processes, shutdown time is near.
   */

  check = 1;
  while (1) {
	while ((pid = waitpid(-1, NULL, check ? WNOHANG : 0)) > 0) {
		/* Search to see which line terminated. */
		for (linenr = 0; linenr < PIDSLOTS; linenr++) {
			slotp = &slots[linenr];
			if (slotp->pid == pid) {
				/* Record process exiting. */
				wtmp(DEAD_PROCESS, linenr, NULL, pid);
				slotp->pid = NO_PID;
				check = 1;
			}
		}
	}

	/* If a signal 1 (SIGHUP) is received, simply reset error counts. */
	if (gothup) {
		gothup = 0;
		for (linenr = 0; linenr < PIDSLOTS; linenr++) {
			slots[linenr].errct = 0;
		}
		check = 1;
	}

	/* Shut down on signal 6 (SIGABRT). */
	if (gotabrt) {
		gotabrt = 0;
		startup(0, &TT_REBOOT);
	}

	if (spawn && check) {
		/* See which lines need a login process started up. */
		for (linenr = 0; linenr < PIDSLOTS; linenr++) {
			slotp = &slots[linenr];
			if ((ttyp = getttyent()) == NULL) break;

			if (ttyp->ty_getty != NULL
				/* ty_getty is a string, and TTY_ON is
				 * the way to check for enabled ternimanls. */
				&& (ttyp->ty_status & TTY_ON)
				&& slotp->pid == NO_PID
				&& slotp->errct < ERRCT_DISABLE)
			{
				startup(linenr, ttyp);
			}
		}
		endttyent();
	}
	check = 0;
  }
}
Exemplo n.º 9
0
Arquivo: init.c Projeto: Ga-vin/MINIX3
void startup(int linenr, struct ttyent *ttyp)
{
  /* Fork off a process for the indicated line. */

  struct slotent *slotp;		/* pointer to ttyslot */
  pid_t pid;				/* new pid */
  int err[2];				/* error reporting pipe */
  char line[32];			/* tty device name */
  int status;
  char **ty_getty_argv;

  slotp = &slots[linenr];

  /* Error channel for between fork and exec. */
  if (pipe(err) < 0) err[0] = err[1] = -1;

  if ((pid = fork()) == -1 ) {
	report(2, "fork()");
	sleep(10);
	return;
  }

  if (pid == 0) {
	/* Child */
	close(err[0]);
	fcntl(err[1], F_SETFD, fcntl(err[1], F_GETFD) | FD_CLOEXEC);

	/* A new session. */
	setsid();

	/* Construct device name. */
	strcpy(line, "/dev/");
	strncat(line, ttyp->ty_name, sizeof(line) - 6);

	/* Open the line for standard input and output. */
	close(0);
	close(1);
	if (open(line, O_RDWR) < 0 || dup(0) < 0) {
		write(err[1], &errno, sizeof(errno));
		_exit(1);
	}

	/* ty_init not present. */

	/* Redirect standard error too. */
	dup2(0, 2);

	/* Construct argv for execute() */
	ty_getty_argv = construct_argv(ttyp->ty_getty);
	if (ty_getty_argv == NULL)
		report(2, "construct_argv");

	/* Execute the getty process. */
	execute(ty_getty_argv);

	/* Oops, disaster strikes. */
	fcntl(2, F_SETFL, fcntl(2, F_GETFL) | O_NONBLOCK);
	if (linenr != 0) report(2, ty_getty_argv[0]);
	write(err[1], &errno, sizeof(errno));
	_exit(1);
  }

  /* Parent */
  if (ttyp != &TT_REBOOT) slotp->pid = pid;

  close(err[1]);
  if (read(err[0], &errno, sizeof(errno)) != 0) {
	/* If an errno value goes down the error pipe: Problems. */

	switch (errno) {
	case ENOENT:
	case ENODEV:
	case ENXIO:
		/* Device nonexistent, no driver, or no minor device. */
		slotp->errct = ERRCT_DISABLE;
		close(err[0]);
		return;
	case 0:
		/* Error already reported. */
		break;
	default:
		/* Any other error on the line. */
		report(2, ttyp->ty_name);
	}
	close(err[0]);

	if (++slotp->errct >= ERRCT_DISABLE) {
		tell(2, "init: ");
		tell(2, ttyp->ty_name);
		tell(2, ": excessive errors, shutting down\n");
	} else {
		sleep(5);
	}
	return;
  }
  close(err[0]);

  if (ttyp != &TT_REBOOT) wtmp(LOGIN_PROCESS, linenr, ttyp->ty_name, pid);
  slotp->errct = 0;
}
Exemplo n.º 10
0
Arquivo: init.c Projeto: 54niyu/minix
int main(void)
{
  pid_t pid;			/* pid of child process */
  int fd;			/* generally useful */
  int linenr;			/* loop variable */
  int check;			/* check if a new process must be spawned */
  struct slotent *slotp;	/* slots[] pointer */
  struct ttyent *ttyp;		/* ttytab entry */
  struct sigaction sa;
  struct stat stb;

  if (fstat(0, &stb) < 0) {
	/* Open standard input, output & error. */
	(void) open("/dev/null", O_RDONLY);
	(void) open("/dev/log", O_WRONLY);
	dup(1);
  }

  sigemptyset(&sa.sa_mask);
  sa.sa_flags = 0;

  /* Hangup: Reexamine /etc/ttytab for newly enabled terminal lines. */
  sa.sa_handler = onhup;
  sigaction(SIGHUP, &sa, NULL);

  /* Terminate: Stop spawning login processes, shutdown is near. */
  sa.sa_handler = onterm;
  sigaction(SIGTERM, &sa, NULL);

  /* Abort: Sent by the kernel on CTRL-ALT-DEL; shut the system down. */
  sa.sa_handler = onabrt;
  sigaction(SIGABRT, &sa, NULL);

  /* Execute the /etc/rc file. */
  if ((pid = fork()) != 0) {
	/* Parent just waits. */
	while (wait(NULL) != pid) {
		if (gotabrt) reboot(RBT_HALT);
	}
  } else {
	static char *rc_command[] = { "sh", "/etc/rc", NULL, NULL };

#if __minix_vmd
	/* Minix-vmd: Get the boot options from the boot environment. */
	rc_command[2] = getenv("bootopts");
#else
	/* Minix: Input from the console. */
	close(0);
	(void) open("/dev/console", O_RDONLY);
#endif

	execute(rc_command);
	report(2, "sh /etc/rc");
	_exit(1);	/* impossible, we hope */
  }

  /* Clear /etc/utmp if it exists. */
  if ((fd = open(PATH_UTMP, O_WRONLY | O_TRUNC)) >= 0) close(fd);

  /* Log system reboot. */
  wtmp(BOOT_TIME, 0, NULL, 0);

  /* Main loop. If login processes have already been started up, wait for one
   * to terminate, or for a HUP signal to arrive. Start up new login processes
   * for all ttys which don't have them. Note that wait() also returns when
   * somebody's orphan dies, in which case ignore it.  If the TERM signal is
   * sent then stop spawning processes, shutdown time is near.
   */

  check = 1;
  while (1) {
	while ((pid = waitpid(-1, NULL, check ? WNOHANG : 0)) > 0) {
		/* Search to see which line terminated. */
		for (linenr = 0; linenr < PIDSLOTS; linenr++) {
			slotp = &slots[linenr];
			if (slotp->pid == pid) {
				/* Record process exiting. */
				wtmp(DEAD_PROCESS, linenr, NULL, pid);
				slotp->pid = NO_PID;
				check = 1;
			}
		}
	}

	/* If a signal 1 (SIGHUP) is received, simply reset error counts. */
	if (gothup) {
		gothup = 0;
		for (linenr = 0; linenr < PIDSLOTS; linenr++) {
			slots[linenr].errct = 0;
		}
		check = 1;
	}

	/* Shut down on signal 6 (SIGABRT). */
	if (gotabrt) {
		gotabrt = 0;
		startup(0, &TT_REBOOT);
	}

	if (spawn && check) {
		/* See which lines need a login process started up. */
		for (linenr = 0; linenr < PIDSLOTS; linenr++) {
			slotp = &slots[linenr];
			if ((ttyp = getttyent()) == NULL) break;

			if (ttyp->ty_getty != NULL
				&& ttyp->ty_getty[0] != NULL
				&& slotp->pid == NO_PID
				&& slotp->errct < ERRCT_DISABLE)
			{
				startup(linenr, ttyp);
			}
		}
		endttyent();
	}
	check = 0;
  }
}
Exemplo n.º 11
0
main()
{
  int pid;			/* pid of child process */
  int fd;			/* fd of console for error messages */
  int i;			/* loop variable */
  int status;			/* return status from child process */
  struct slotent *slotp;	/* slots[] pointer */
  void onhup();			/* SIGHUP interrupt catch routine */

  sync();			/* force buffers out onto disk */

  /* Execute the /etc/rc file. */
  if(fork()) {
	/* Parent just waits. */
	wait(&status);
  } else {
	/* Child exec's the shell to do the work. */
	if(open("/etc/rc", 0) < 0) exit(EXIT_OPENFAIL);
	dup(open(CONSOLE, 1));	/* std output, error */
	execle(SHELL1, SHELL1, (char *)0, env);
	execle(SHELL2, SHELL2, (char *)0, env);
	exit(EXIT_EXECFAIL);	/* impossible, we hope */
  }

  /* Log system reboot. */
  wtmp("reboot", "~~", "~", 0, BOOT_TIME, -1);

  /* Read the /etc/ttys file. */
  readttys();
  
  /* Main loop. If login processes have already been started up, wait for one
   * to terminate, or for a HUP signal to arrive. Start up new login processes
   * for all ttys which don't have them. Note that wait() also returns when
   * somebody's orphan dies, in which case ignore it.
   * First set up the signals.
   */

  for (i = 1; i <= _NSIG; i++) signal(i, SIG_IGN);
  signal(SIGHUP, onhup);

  while(1) {
	sync();

	if( pidct && (pid = wait(&status)) > 0 ) {
		/* Search to see which line terminated. */
		for(slotp = slots; slotp < &slots[PIDSLOTS]; ++slotp) {
			if(slotp->pid == pid) {
			    pidct--;
			    slotp->pid = 0;	/* now no login process */
			    slotp->exit = status;

			    if(((status >> 8) & 0xFF) == EXIT_TTYFAIL) {
				fd = open(CONSOLE, 1);
				write(fd, "init: tty problems, shutting down ", 39);
				write(fd, slotp->name, sizeof slotp->name);
				write(fd, "\n", 1);

				close(fd);
				slotp->onflag = 0;
			    }
			    break;
			}
	      }
	}

	/* If a signal 1 (SIGHUP) is received, reread /etc/ttys. */
	if(gothup) {
		readttys();
		gothup = 0;
	}

	/* See which lines need a login process started up. */
	for(slotp = slots; slotp < &slots[PIDSLOTS]; ++slotp) {
		if(slotp->onflag && slotp->pid <= 0)
			startup(slotp - slots, DEAD_PROCESS, LOGIN_PROCESS);
	}
  }