Пример #1
0
 void start()
 {
     g_client_count++;
     //set_socket_recv_bufsize(MAX_PACKET_SIZE);
     do_read();
 }
Пример #2
0
static int read_30 ( struct net_device *dev)
{
	lt_command c;
	c.getflags.command = LT_GETFLAGS;
	return do_read(dev, &c, sizeof(c.getflags),&c,0);
}
Пример #3
0
static int do_command(cmd_request_t cmd)
{
	char *buf;
	struct boothc_header *h, reply;
	int buflen;
	uint32_t force = 0;
	int fd, rv;

	buflen = sizeof(struct boothc_header) + 
		 sizeof(cl.site) + sizeof(cl.ticket);
	buf = malloc(buflen);
	if (!buf) {
		rv = -ENOMEM;
		goto out;
	}
	h = (struct boothc_header *)buf;
	if (cl.force)
		force = BOOTHC_OPT_FORCE;
	init_header(h, cmd, force, 0,
		    sizeof(cl.site) + sizeof(cl.ticket));
	strcpy(buf + sizeof(struct boothc_header), cl.site);
	strcpy(buf + sizeof(struct boothc_header) + sizeof(cl.site), cl.ticket);

        fd = do_connect(BOOTHC_SOCK_PATH);
        if (fd < 0) {
                rv = fd;
                goto out_free;
        }

        rv = do_write(fd, buf, buflen);
        if (rv < 0)
                goto out_close;

	rv = do_read(fd, &reply, sizeof(struct boothc_header));
	if (rv < 0)
		goto out_close;

	if (reply.result == BOOTHC_RLT_INVALID_ARG) {
		log_info("invalid argument!");
		rv = -1;
		goto out_close;
	}
	
	if (reply.result == BOOTHC_RLT_REMOTE_OP) {
		struct booth_node to;
		int s;

		memset(&to, 0, sizeof(struct booth_node));
		to.family = BOOTH_PROTO_FAMILY;
		strcpy(to.addr, cl.site);

		s = booth_transport[TCP].open(&to);
		if (s < 0)
			goto out_close;

		rv = booth_transport[TCP].send(s, buf, buflen);
		if (rv < 0) {
			booth_transport[TCP].close(s);
			goto out_close;
		}
		rv = booth_transport[TCP].recv(s, &reply,
					       sizeof(struct boothc_header));
		if (rv < 0) {	
			booth_transport[TCP].close(s);
			goto out_close;
		}
		booth_transport[TCP].close(s);
	}
 
	if (reply.result == BOOTHC_RLT_ASYNC) {
		if (cmd == BOOTHC_CMD_GRANT)
			log_info("grant command sent, result will be returned "
				 "asynchronously, you can get the result from "
				 "the log files");
		else if (cmd == BOOTHC_CMD_REVOKE)
			log_info("revoke command sent, result will be returned "
				 "asynchronously, you can get the result from "
				 "the log files after the ticket expiry time.");
		else
			log_error("internal error reading reply result!");
		rv = 0;
	} else if (reply.result == BOOTHC_RLT_SYNC_SUCC) {
		if (cmd == BOOTHC_CMD_GRANT)
			log_info("grant succeeded!");
		else if (cmd == BOOTHC_CMD_REVOKE)
			log_info("revoke succeeded!");
		rv = 0;
	} else if (reply.result == BOOTHC_RLT_SYNC_FAIL) {
		if (cmd == BOOTHC_CMD_GRANT)
			log_info("grant failed!");
		else if (cmd == BOOTHC_CMD_REVOKE)
			log_info("revoke failed!");
		rv = 0;
	} else {
		log_error("internal error!");
		rv = -1;
	}

out_close:
	close(fd);
out_free:
	free(buf);
out:
	return rv;
}
Пример #4
0
void connection::do_read()
{
  auto self(shared_from_this());
  socket_.async_read_some(boost::asio::buffer(buffer_),
      [this, self](boost::system::error_code ec, std::size_t bytes_transferred)
      {
        if (!ec)
        {
			if (ws_connected)
			{
				ws_frame frame;

				frame.fin = 0x80 & buffer_[0];
				frame.masking = 0x80 & buffer_[1];

				frame.payload_len = (unsigned int)(buffer_[1] & 0x7F);
				int masking_key_offset = 0;
				// If 126, the following 2 bytes interpreted as a 16 - bit unsigned integer are the payload length.
				if (frame.payload_len == 126)
				{
					masking_key_offset = 2;
					unsigned short s = ((buffer_[2] << 8) | buffer_[3]);
					frame.payload_len = s;
				}
				// If 127, the following 8 bytes interpreted as a 64 - bit unsigned integer(the most significant bit MUST be 0) are the payload length.
				else if (frame.payload_len == 127)
				{
					unsigned long long int s = 
					(
						(buffer_[2] << 64) | (buffer_[3] << 56) | (buffer_[4] << 48) |
						(buffer_[5] << 40) | (buffer_[6] << 32) | (buffer_[7] << 24) | 
						(buffer_[8] << 12) | (buffer_[9] << 4) | buffer_[10]
					);
					frame.payload_len = s;
					masking_key_offset = 8;
				}

				if (frame.masking)
				{
					frame.masking_key[0] = (buffer_[2] + masking_key_offset);
					frame.masking_key[1] = (buffer_[3] + masking_key_offset);
					frame.masking_key[2] = (buffer_[4] + masking_key_offset);
					frame.masking_key[3] = (buffer_[5] + masking_key_offset);
				}
				else
				{
					frame.masking_key[0] = 0;
					frame.masking_key[1] = 0;
					frame.masking_key[2] = 0;
					frame.masking_key[3] = 0;
				}

				frame.payload = std::vector<unsigned char>();

	
				for (int i = 0; i < frame.payload_len; ++i)
				{
					unsigned char original = buffer_[6 + masking_key_offset + i];
					frame.payload.push_back(original ^ frame.masking_key[i % 4]);
				}
				
				printf("masking: %s\n payload: %d bytes\n", frame.masking ? "True" : "False", frame.payload_len);
				printf("Data: %s\n", frame.payload.data());

				//do_write("Data: %s\n", 5);
				do_read();
				return;
			}

          request_parser::result_type result;
          std::tie(result, std::ignore) = request_parser_.parse(
              request_, buffer_.data(), buffer_.data() + bytes_transferred);

          if (result == request_parser::good)
          {
            request_handler_.handle_request(request_, reply_);
			if (reply_.status == reply::switching_protocols)
			{
				ws_connected = true;
			}
			do_write_http();
          }
          else if (result == request_parser::bad)
          {
            reply_ = reply::stock_reply(reply::bad_request);
			do_write_http();
          }
          else
          {
            do_read();
          }
        }
        else if (ec != boost::asio::error::operation_aborted)
        {
          connection_manager_.stop(shared_from_this());
        }
      });
}
Пример #5
0
gf8 read_op(char op, char * s, int * index) {
  gf8 left = do_read(s,index);
  gf8 right = do_read(s,index);
  return do_op(op, left, right);
}
Пример #6
0
void tcpip_task( void *dummy)
{
	/* wait for an IO signal, find out what is happening and
	 * call the right routine to handle the situation.
	 */
	fd_set	rfds, *pfds;
#ifndef __linux__
	fd_set efds;
#endif
	int	conn_id, ret, count;
#ifndef WIN32
	int data;
#endif
	if(dummy){}
	while(1)
	{
		while(!DIM_IO_valid)
			dim_usleep(1000);

		list_to_fds( &rfds );
		MY_FD_ZERO(&efds);
#ifdef WIN32
		pfds = &efds;
#else
		pfds = &rfds;
#endif
		MY_FD_SET( DIM_IO_path[0], pfds );
#ifdef __linux__
		ret = poll(Pollfds, Pollfd_size, -1);
#else
		ret = select(FD_SETSIZE, &rfds, NULL, &efds, NULL);
#endif
		if(ret <= 0)
		{
		    printf("poll returned %d, errno %d\n", ret, errno);
		}
		if(ret > 0)
		{
			if(MY_FD_ISSET(DIM_IO_path[0], pfds) )
			{
#ifndef WIN32
				read(DIM_IO_path[0], &data, 4);
				DIM_IO_Done = 0;
#endif
				MY_FD_CLR( (unsigned)DIM_IO_path[0], pfds );
			}
/*
			{
			DISABLE_AST
*/
			conn_id = 0;
			while( (ret = fds_get_entry( &rfds, &conn_id )) > 0 ) 
			{
				if( Net_conns[conn_id].reading )
				{
					count = 0;
					do
					{
						DISABLE_AST
						if(Net_conns[conn_id].channel)
						{
							do_read( conn_id );
							count = get_bytes_to_read(conn_id);
						}
						else
						{
							count = 0;
						}
						ENABLE_AST
					}while(count > 0 );
				}
				else
				{
					DISABLE_AST
					do_accept( conn_id );
					ENABLE_AST
				}
				MY_FD_CLR( (unsigned)Net_conns[conn_id].channel, &rfds );
			}
/*
			ENABLE_AST
			}
*/
#ifndef WIN32
			return;
#endif
		}
Пример #7
0
static void
rshd_loop (int from0, int to0,
	   int to1,   int from1,
	   int to2,   int from2,
	   int have_errsock)
{
    fd_set real_readset;
    int max_fd;
    int count = 2;
    char *buf;

    if(from0 >= FD_SETSIZE || from1 >= FD_SETSIZE || from2 >= FD_SETSIZE)
	errx (1, "fd too large");

#ifdef KRB5
    if(auth_method == AUTH_KRB5 && protocol_version == 2)
	init_ivecs(0, have_errsock);
#endif

    FD_ZERO(&real_readset);
    FD_SET(from0, &real_readset);
    FD_SET(from1, &real_readset);
    FD_SET(from2, &real_readset);
    max_fd = max(from0, max(from1, from2)) + 1;

    buf = malloc(max(RSHD_BUFSIZ, RSH_BUFSIZ));
    if (buf == NULL)
	syslog_and_die("out of memory");

    for (;;) {
	int ret;
	fd_set readset = real_readset;

	ret = select (max_fd, &readset, NULL, NULL, NULL);
	if (ret < 0) {
	    if (errno == EINTR)
		continue;
	    else
		syslog_and_die ("select: %s", strerror(errno));
	}
	if (FD_ISSET(from0, &readset)) {
	    ret = do_read (from0, buf, RSHD_BUFSIZ, ivec_in[0]);
	    if (ret < 0)
		syslog_and_die ("read: %s", strerror(errno));
	    else if (ret == 0) {
		close (from0);
		close (to0);
		FD_CLR(from0, &real_readset);
	    } else
		net_write (to0, buf, ret);
	}
	if (FD_ISSET(from1, &readset)) {
	    ret = read (from1, buf, RSH_BUFSIZ);
	    if (ret < 0)
		syslog_and_die ("read: %s", strerror(errno));
	    else if (ret == 0) {
		close (from1);
		close (to1);
		FD_CLR(from1, &real_readset);
		if (--count == 0)
		    exit (0);
	    } else
		do_write (to1, buf, ret, ivec_out[0]);
	}
	if (FD_ISSET(from2, &readset)) {
	    ret = read (from2, buf, RSH_BUFSIZ);
	    if (ret < 0)
		syslog_and_die ("read: %s", strerror(errno));
	    else if (ret == 0) {
		close (from2);
		close (to2);
		FD_CLR(from2, &real_readset);
		if (--count == 0)
		    exit (0);
	    } else
		do_write (to2, buf, ret, ivec_out[1]);
	}
   }
}
Пример #8
0
void run(EpmdVars *g)
{
  struct EPMD_SOCKADDR_IN iserv_addr[MAX_LISTEN_SOCKETS];
  int listensock[MAX_LISTEN_SOCKETS];
  int num_sockets = 0;
  int i;
  int opt;
  unsigned short sport = g->port;
  int bound = 0;

  node_init(g);
  g->conn = conn_init(g);

#ifdef HAVE_SYSTEMD_DAEMON
  if (g->is_systemd)
    {
      int n;
      
      dbg_printf(g,2,"try to obtain sockets from systemd");

      n = sd_listen_fds(0);
      if (n < 0)
        {
          dbg_perror(g,"cannot obtain sockets from systemd");
          epmd_cleanup_exit(g,1);
        }
      else if (n == 0)
        {
          dbg_tty_printf(g,0,"systemd provides no sockets");
          epmd_cleanup_exit(g,1);
      }
      else if (n > MAX_LISTEN_SOCKETS)
      {
          dbg_tty_printf(g,0,"cannot listen on more than %d IP addresses", MAX_LISTEN_SOCKETS);
          epmd_cleanup_exit(g,1);
      } 
      num_sockets = n;
      for (i = 0; i < num_sockets; i++)
        {
          g->listenfd[i] = listensock[i] = SD_LISTEN_FDS_START + i;
        }
    }
  else
    {
#endif /* HAVE_SYSTEMD_DAEMON */

  dbg_printf(g,2,"try to initiate listening port %d", g->port);

  if (g->addresses != NULL && /* String contains non-separator characters if: */
      g->addresses[strspn(g->addresses," ,")] != '\000')
    {
      char *tmp = NULL;
      char *token = NULL;

      /* Always listen on the loopback. */
      SET_ADDR(iserv_addr[num_sockets],htonl(INADDR_LOOPBACK),sport);
      num_sockets++;
#if defined(EPMD6)
      SET_ADDR6(iserv_addr[num_sockets],in6addr_loopback,sport);
      num_sockets++;
#endif

	  if ((tmp = strdup(g->addresses)) == NULL)
	{
	  dbg_perror(g,"cannot allocate memory");
	  epmd_cleanup_exit(g,1);
	}

      for(token = strtok(tmp,", ");
	  token != NULL;
	  token = strtok(NULL,", "))
	{
	  struct in_addr addr;
#if defined(EPMD6)
	  struct in6_addr addr6;
	  struct sockaddr_storage *sa = &iserv_addr[num_sockets];

	  if (inet_pton(AF_INET6,token,&addr6) == 1)
	    {
	      SET_ADDR6(iserv_addr[num_sockets],addr6,sport);
	    }
	  else if (inet_pton(AF_INET,token,&addr) == 1)
	    {
	      SET_ADDR(iserv_addr[num_sockets],addr.s_addr,sport);
	    }
	  else
#else
	  if ((addr.s_addr = inet_addr(token)) != INADDR_NONE)
	    {
	      SET_ADDR(iserv_addr[num_sockets],addr.s_addr,sport);
	    }
	  else
#endif
	    {
	      dbg_tty_printf(g,0,"cannot parse IP address \"%s\"",token);
	      epmd_cleanup_exit(g,1);
	    }

#if defined(EPMD6)
	  if (sa->ss_family == AF_INET6 && IN6_IS_ADDR_LOOPBACK(&addr6))
	      continue;

	  if (sa->ss_family == AF_INET)
#endif
	  if (IS_ADDR_LOOPBACK(addr))
	    continue;

	  num_sockets++;

	  if (num_sockets >= MAX_LISTEN_SOCKETS)
	    {
	      dbg_tty_printf(g,0,"cannot listen on more than %d IP addresses",
			     MAX_LISTEN_SOCKETS);
	      epmd_cleanup_exit(g,1);
	    }
	}

      free(tmp);
    }
  else
    {
      SET_ADDR(iserv_addr[num_sockets],htonl(INADDR_ANY),sport);
      num_sockets++;
#if defined(EPMD6)
      SET_ADDR6(iserv_addr[num_sockets],in6addr_any,sport);
      num_sockets++;
#endif
    }
#ifdef HAVE_SYSTEMD_DAEMON
    }
#endif /* HAVE_SYSTEMD_DAEMON */

#if !defined(__WIN32__)
  /* We ignore the SIGPIPE signal that is raised when we call write
     twice on a socket closed by the other end. */
  signal(SIGPIPE, SIG_IGN);
#endif

  /*
   * Initialize number of active file descriptors.
   * Stdin, stdout, and stderr are still open.
   */
  g->active_conn = 3 + num_sockets;
  g->max_conn -= num_sockets;

  FD_ZERO(&g->orig_read_mask);
  g->select_fd_top = 0;

#ifdef HAVE_SYSTEMD_DAEMON
  if (g->is_systemd)
      for (i = 0; i < num_sockets; i++)
          select_fd_set(g, listensock[i]);
  else
    {
#endif /* HAVE_SYSTEMD_DAEMON */
  for (i = 0; i < num_sockets; i++)
    {
      struct sockaddr *sa = (struct sockaddr *)&iserv_addr[i];
#if defined(EPMD6)
      size_t salen = (sa->sa_family == AF_INET6 ?
              sizeof(struct sockaddr_in6) :
              sizeof(struct sockaddr_in));
#else
      size_t salen = sizeof(struct sockaddr_in);
#endif

      if ((listensock[i] = socket(sa->sa_family,SOCK_STREAM,0)) < 0)
	{
	  switch (errno) {
	      case EAFNOSUPPORT:
	      case EPROTONOSUPPORT:
	          continue;
	      default:
	          dbg_perror(g,"error opening stream socket");
	          epmd_cleanup_exit(g,1);
	  }
	}
      g->listenfd[bound++] = listensock[i];

#if HAVE_DECL_IPV6_V6ONLY
      opt = 1;
      if (sa->sa_family == AF_INET6 &&
          setsockopt(listensock[i],IPPROTO_IPV6,IPV6_V6ONLY,&opt,
              sizeof(opt)) <0)
	{
	  dbg_perror(g,"can't set IPv6 only socket option");
	  epmd_cleanup_exit(g,1);
	}
#endif

      /*
       * Note that we must not enable the SO_REUSEADDR on Windows,
       * because addresses will be reused even if they are still in use.
       */
  
#if !defined(__WIN32__)
      opt = 1;
      if (setsockopt(listensock[i],SOL_SOCKET,SO_REUSEADDR,(char* ) &opt,
		     sizeof(opt)) <0)
	{
	  dbg_perror(g,"can't set sockopt");
	  epmd_cleanup_exit(g,1);
	}
#endif
  
      /* In rare cases select returns because there is someone
	 to accept but the request is withdrawn before the
	 accept function is called. We set the listen socket
	 to be non blocking to prevent us from being hanging
	 in accept() waiting for the next request. */
#if (defined(__WIN32__) || defined(NO_FCNTL))
      opt = 1;
      /* Gives warning in VxWorks */
      if (ioctl(listensock[i], FIONBIO, &opt) != 0)
#else
      opt = fcntl(listensock[i], F_GETFL, 0);
      if (fcntl(listensock[i], F_SETFL, opt | O_NONBLOCK) == -1)
#endif /* __WIN32__ || VXWORKS */
	dbg_perror(g,"failed to set non-blocking mode of listening socket %d",
		   listensock[i]);

      if (bind(listensock[i], (struct sockaddr*) &iserv_addr[i], salen) < 0)
	{
	  if (errno == EADDRINUSE)
	    {
	      dbg_tty_printf(g,1,"there is already a epmd running at port %d",
			     g->port);
	      epmd_cleanup_exit(g,0);
	    }
	  else
	    {
	      dbg_perror(g,"failed to bind socket");
	      epmd_cleanup_exit(g,1);
	    }
	}

      if(listen(listensock[i], SOMAXCONN) < 0) {
          dbg_perror(g,"failed to listen on socket");
          epmd_cleanup_exit(g,1);
      }
      select_fd_set(g, listensock[i]);
    }
  if (bound == 0) {
      dbg_perror(g,"unable to bind any address");
      epmd_cleanup_exit(g,1);
  }
  num_sockets = bound;
#ifdef HAVE_SYSTEMD_DAEMON
    }
    sd_notifyf(0, "READY=1\n"
                  "STATUS=Processing port mapping requests...\n"
                  "MAINPID=%lu", (unsigned long) getpid());
#endif /* HAVE_SYSTEMD_DAEMON */

  dbg_tty_printf(g,2,"entering the main select() loop");

 select_again:
  while(1)
    {
      fd_set read_mask = g->orig_read_mask;
      struct timeval timeout;
      int ret;

      /* If we are idle we time out now and then to enable the code
	 below to close connections that are old and probably
	 hanging. Make sure that select will return often enough. */

      timeout.tv_sec = (g->packet_timeout < IDLE_TIMEOUT) ? 1 : IDLE_TIMEOUT;
      timeout.tv_usec = 0;

      if ((ret = select(g->select_fd_top,
			&read_mask, (fd_set *)0,(fd_set *)0,&timeout)) < 0) {
	dbg_perror(g,"error in select ");
        switch (errno) {
          case EAGAIN:
          case EINTR:
            break;
          default:
            epmd_cleanup_exit(g,1);
        }
      }
      else {
	time_t now;
	if (ret == 0) {
	  FD_ZERO(&read_mask);
	}
	if (g->delay_accept) {		/* Test of busy server */
	  sleep(g->delay_accept);
	}

	for (i = 0; i < num_sockets; i++)
	  if (FD_ISSET(g->listenfd[i],&read_mask)) {
	    if (do_accept(g, g->listenfd[i]) && g->active_conn < g->max_conn) {
	      /*
	       * The accept() succeeded, and we have at least one file
	       * descriptor still free, which means that another accept()
	       * could succeed. Go do do another select(), in case there
	       * are more incoming connections waiting to be accepted.
	       */
	      goto select_again;
	    }
	  }
	  
	/* Check all open streams marked by select for data or a
	   close.  We also close all open sockets except ALIVE
	   with no activity for a long period */

	now = current_time(g);
	for (i = 0; i < g->max_conn; i++) {
	  if (g->conn[i].open == EPMD_TRUE) {
	    if (FD_ISSET(g->conn[i].fd,&read_mask))
	      do_read(g,&g->conn[i]);
	    else if ((g->conn[i].keep == EPMD_FALSE) &&
		     ((g->conn[i].mod_time + g->packet_timeout) < now)) {
	      dbg_tty_printf(g,1,"closing because timed out on receive");
	      epmd_conn_close(g,&g->conn[i]);
	    }
	  }
	}
      }
    }
}
Пример #9
0
static unsigned int test_rw(HANDLE hDrive, blk_t last_block, size_t block_size, blk_t first_block,
	size_t blocks_at_once, int nb_passes)
{
	unsigned char *buffer = NULL, *read_buffer;
	const unsigned int pattern[] = {0xaa, 0x55, 0xff, 0x00};
	int i, pat_idx;
	unsigned int bb_count = 0;
	blk_t got, tryout, recover_block = ~0, *blk_id;
	size_t id_offset;

	if ((nb_passes < 1) || (nb_passes > 4)) {
		uprintf("%sInvalid number of passes\n", bb_prefix);
		cancel_ops = -1;
		return 0;
	}

	buffer = allocate_buffer(2 * blocks_at_once * block_size);
	read_buffer = buffer + blocks_at_once * block_size;

	if (!buffer) {
		uprintf("%sError while allocating buffers\n", bb_prefix);
		cancel_ops = -1;
		return 0;
	}

	uprintf("%sChecking from block %lu to %lu\n", bb_prefix,
		(unsigned long) first_block, (unsigned long) last_block - 1);
	nr_pattern = nb_passes;
	cur_pattern = 0;

	for (pat_idx = 0; pat_idx < nb_passes; pat_idx++) {
		if (cancel_ops) goto out;
		srand((unsigned int)GetTickCount());
		id_offset = rand()* (block_size-sizeof(blk_t)) / RAND_MAX;
		pattern_fill(buffer, pattern[pat_idx], blocks_at_once * block_size);
		uprintf("%sUsing offset %d for fake device check\n", bb_prefix, id_offset);
		num_blocks = last_block - 1;
		currently_testing = first_block;
		if (s_flag | v_flag)
			uprintf("%sWriting test pattern 0x%02X\n", bb_prefix, pattern[pat_idx]);
		cur_op = OP_WRITE;
		tryout = blocks_at_once;
		while (currently_testing < last_block) {
			if (cancel_ops) goto out;
			if (max_bb && bb_count >= max_bb) {
				if (s_flag || v_flag) {
					uprintf(abort_msg);
					fprintf(log_fd, abort_msg);
					fflush(log_fd);
				}
				cancel_ops = -1;
				goto out;
			}
			if (currently_testing + tryout > last_block)
				tryout = last_block - currently_testing;
			if (detect_fakes) {
				/* Add the block number at a fixed (random) offset during each pass to
				   allow for the detection of 'fake' media (eg. 2GB USB masquerading as 16GB) */
				for (i=0; i<(int)blocks_at_once; i++) {
					blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size);
					*blk_id = (blk_t)(currently_testing + i);
				}
			}
			got = do_write(hDrive, buffer, tryout, block_size, currently_testing);
			if (v_flag > 1)
				print_status();

			if (got == 0 && tryout == 1)
				bb_count += bb_output(currently_testing++, WRITE_ERROR);
			currently_testing += got;
			if (got != tryout) {
				tryout = 1;
				if (recover_block == ~0)
					recover_block = currently_testing -
						got + blocks_at_once;
				continue;
			} else if (currently_testing == recover_block) {
				tryout = blocks_at_once;
				recover_block = ~0;
			}
		}

		num_blocks = 0;
		if (s_flag | v_flag)
			uprintf("%sReading and comparing\n", bb_prefix);
		cur_op = OP_READ;
		num_blocks = last_block;
		currently_testing = first_block;

		tryout = blocks_at_once;
		while (currently_testing < last_block) {
			if (cancel_ops) goto out;
			if (max_bb && bb_count >= max_bb) {
				if (s_flag || v_flag) {
					uprintf(abort_msg);
					fprintf(log_fd, abort_msg);
					fflush(log_fd);
				}
				cancel_ops = -1;
				goto out;
			}
			if (currently_testing + tryout > last_block)
				tryout = last_block - currently_testing;
			if (detect_fakes) {
				for (i=0; i<(int)blocks_at_once; i++) {
					blk_id = (blk_t*)(intptr_t)(buffer + id_offset+ i*block_size);
					*blk_id = (blk_t)(currently_testing + i);
				}
			}
			got = do_read(hDrive, read_buffer, tryout, block_size,
				       currently_testing);
			if (got == 0 && tryout == 1)
				bb_count += bb_output(currently_testing++, READ_ERROR);
			currently_testing += got;
			if (got != tryout) {
				tryout = 1;
				if (recover_block == ~0)
					recover_block = currently_testing -
						got + blocks_at_once;
				continue;
			} else if (currently_testing == recover_block) {
				tryout = blocks_at_once;
				recover_block = ~0;
			}
			for (i=0; i < got; i++) {
				if (memcmp(read_buffer + i * block_size,
					   buffer + i * block_size,
					   block_size))
					bb_count += bb_output(currently_testing+i-got, CORRUPTION_ERROR);
			}
			if (v_flag > 1)
				print_status();
		}

		num_blocks = 0;
	}
out:
	free_buffer(buffer);
	return bb_count;
}
Пример #10
0
int main(int argc, char *argv[])
{
	const struct flashchip *chip = NULL;
	/* Probe for up to eight flash chips. */
	struct flashctx flashes[8] = {{0}};
	struct flashctx *fill_flash;
	const char *name;
	int namelen, opt, i, j;
	int startchip = -1, chipcount = 0, option_index = 0, force = 0, ifd = 0, fmap = 0;
#if CONFIG_PRINT_WIKI == 1
	int list_supported_wiki = 0;
#endif
	int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
	int dont_verify_it = 0, dont_verify_all = 0, list_supported = 0, operation_specified = 0;
	struct flashrom_layout *layout = NULL;
	enum programmer prog = PROGRAMMER_INVALID;
	enum {
		OPTION_IFD = 0x0100,
		OPTION_FMAP,
		OPTION_FMAP_FILE,
		OPTION_FLASH_CONTENTS,
	};
	int ret = 0;

	static const char optstring[] = "r:Rw:v:nNVEfc:l:i:p:Lzho:";
	static const struct option long_options[] = {
		{"read",		1, NULL, 'r'},
		{"write",		1, NULL, 'w'},
		{"erase",		0, NULL, 'E'},
		{"verify",		1, NULL, 'v'},
		{"noverify",		0, NULL, 'n'},
		{"noverify-all",	0, NULL, 'N'},
		{"chip",		1, NULL, 'c'},
		{"verbose",		0, NULL, 'V'},
		{"force",		0, NULL, 'f'},
		{"layout",		1, NULL, 'l'},
		{"ifd",			0, NULL, OPTION_IFD},
		{"fmap",		0, NULL, OPTION_FMAP},
		{"fmap-file",		1, NULL, OPTION_FMAP_FILE},
		{"image",		1, NULL, 'i'},
		{"flash-contents",	1, NULL, OPTION_FLASH_CONTENTS},
		{"list-supported",	0, NULL, 'L'},
		{"list-supported-wiki",	0, NULL, 'z'},
		{"programmer",		1, NULL, 'p'},
		{"help",		0, NULL, 'h'},
		{"version",		0, NULL, 'R'},
		{"output",		1, NULL, 'o'},
		{NULL,			0, NULL, 0},
	};

	char *filename = NULL;
	char *referencefile = NULL;
	char *layoutfile = NULL;
	char *fmapfile = NULL;
#ifndef STANDALONE
	char *logfile = NULL;
#endif /* !STANDALONE */
	char *tempstr = NULL;
	char *pparam = NULL;

	flashrom_set_log_callback((flashrom_log_callback *)&flashrom_print_cb);

	print_version();
	print_banner();

	if (selfcheck())
		exit(1);

	setbuf(stdout, NULL);
	/* FIXME: Delay all operation_specified checks until after command
	 * line parsing to allow --help overriding everything else.
	 */
	while ((opt = getopt_long(argc, argv, optstring,
				  long_options, &option_index)) != EOF) {
		switch (opt) {
		case 'r':
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			filename = strdup(optarg);
			read_it = 1;
			break;
		case 'w':
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			filename = strdup(optarg);
			write_it = 1;
			break;
		case 'v':
			//FIXME: gracefully handle superfluous -v
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			if (dont_verify_it) {
				fprintf(stderr, "--verify and --noverify are mutually exclusive. Aborting.\n");
				cli_classic_abort_usage();
			}
			filename = strdup(optarg);
			verify_it = 1;
			break;
		case 'n':
			if (verify_it) {
				fprintf(stderr, "--verify and --noverify are mutually exclusive. Aborting.\n");
				cli_classic_abort_usage();
			}
			dont_verify_it = 1;
			break;
		case 'N':
			dont_verify_all = 1;
			break;
		case 'c':
			chip_to_probe = strdup(optarg);
			break;
		case 'V':
			verbose_screen++;
			if (verbose_screen > FLASHROM_MSG_DEBUG2)
				verbose_logfile = verbose_screen;
			break;
		case 'E':
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			erase_it = 1;
			break;
		case 'f':
			force = 1;
			break;
		case 'l':
			if (layoutfile) {
				fprintf(stderr, "Error: --layout specified "
					"more than once. Aborting.\n");
				cli_classic_abort_usage();
			}
			if (ifd) {
				fprintf(stderr, "Error: --layout and --ifd both specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			if (fmap) {
				fprintf(stderr, "Error: --layout and --fmap-file both specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			layoutfile = strdup(optarg);
			break;
		case OPTION_IFD:
			if (layoutfile) {
				fprintf(stderr, "Error: --layout and --ifd both specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			if (fmap) {
				fprintf(stderr, "Error: --fmap-file and --ifd both specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			ifd = 1;
			break;
		case OPTION_FMAP_FILE:
			if (fmap) {
				fprintf(stderr, "Error: --fmap or --fmap-file specified "
					"more than once. Aborting.\n");
				cli_classic_abort_usage();
			}
			if (ifd) {
				fprintf(stderr, "Error: --fmap-file and --ifd both specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			if (layoutfile) {
				fprintf(stderr, "Error: --fmap-file and --layout both specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			fmapfile = strdup(optarg);
			fmap = 1;
			break;
		case OPTION_FMAP:
			if (fmap) {
				fprintf(stderr, "Error: --fmap or --fmap-file specified "
					"more than once. Aborting.\n");
				cli_classic_abort_usage();
			}
			if (ifd) {
				fprintf(stderr, "Error: --fmap and --ifd both specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			if (layoutfile) {
				fprintf(stderr, "Error: --layout and --fmap both specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			fmap = 1;
			break;
		case 'i':
			tempstr = strdup(optarg);
			if (register_include_arg(tempstr)) {
				free(tempstr);
				cli_classic_abort_usage();
			}
			break;
		case OPTION_FLASH_CONTENTS:
			referencefile = strdup(optarg);
			break;
		case 'L':
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			list_supported = 1;
			break;
		case 'z':
#if CONFIG_PRINT_WIKI == 1
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			list_supported_wiki = 1;
#else
			fprintf(stderr, "Error: Wiki output was not compiled "
				"in. Aborting.\n");
			cli_classic_abort_usage();
#endif
			break;
		case 'p':
			if (prog != PROGRAMMER_INVALID) {
				fprintf(stderr, "Error: --programmer specified "
					"more than once. You can separate "
					"multiple\nparameters for a programmer "
					"with \",\". Please see the man page "
					"for details.\n");
				cli_classic_abort_usage();
			}
			for (prog = 0; prog < PROGRAMMER_INVALID; prog++) {
				name = programmer_table[prog].name;
				namelen = strlen(name);
				if (strncmp(optarg, name, namelen) == 0) {
					switch (optarg[namelen]) {
					case ':':
						pparam = strdup(optarg + namelen + 1);
						if (!strlen(pparam)) {
							free(pparam);
							pparam = NULL;
						}
						break;
					case '\0':
						break;
					default:
						/* The continue refers to the
						 * for loop. It is here to be
						 * able to differentiate between
						 * foo and foobar.
						 */
						continue;
					}
					break;
				}
			}
			if (prog == PROGRAMMER_INVALID) {
				fprintf(stderr, "Error: Unknown programmer \"%s\". Valid choices are:\n",
					optarg);
				list_programmers_linebreak(0, 80, 0);
				msg_ginfo(".\n");
				cli_classic_abort_usage();
			}
			break;
		case 'R':
			/* print_version() is always called during startup. */
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			exit(0);
			break;
		case 'h':
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				cli_classic_abort_usage();
			}
			cli_classic_usage(argv[0]);
			exit(0);
			break;
		case 'o':
#ifdef STANDALONE
			fprintf(stderr, "Log file not supported in standalone mode. Aborting.\n");
			cli_classic_abort_usage();
#else /* STANDALONE */
			logfile = strdup(optarg);
			if (logfile[0] == '\0') {
				fprintf(stderr, "No log filename specified.\n");
				cli_classic_abort_usage();
			}
#endif /* STANDALONE */
			break;
		default:
			cli_classic_abort_usage();
			break;
		}
	}

	if (optind < argc) {
		fprintf(stderr, "Error: Extra parameter found.\n");
		cli_classic_abort_usage();
	}

	if ((read_it | write_it | verify_it) && check_filename(filename, "image")) {
		cli_classic_abort_usage();
	}
	if (layoutfile && check_filename(layoutfile, "layout")) {
		cli_classic_abort_usage();
	}
	if (fmapfile && check_filename(fmapfile, "fmap")) {
		cli_classic_abort_usage();
	}
	if (referencefile && check_filename(referencefile, "reference")) {
		cli_classic_abort_usage();
	}

#ifndef STANDALONE
	if (logfile && check_filename(logfile, "log"))
		cli_classic_abort_usage();
	if (logfile && open_logfile(logfile))
		cli_classic_abort_usage();
#endif /* !STANDALONE */

#if CONFIG_PRINT_WIKI == 1
	if (list_supported_wiki) {
		print_supported_wiki();
		goto out;
	}
#endif

	if (list_supported) {
		if (print_supported())
			ret = 1;
		goto out;
	}

#ifndef STANDALONE
	start_logging();
#endif /* !STANDALONE */

	print_buildinfo();
	msg_gdbg("Command line (%i args):", argc - 1);
	for (i = 0; i < argc; i++) {
		msg_gdbg(" %s", argv[i]);
	}
	msg_gdbg("\n");

	if (layoutfile && read_romlayout(layoutfile)) {
		ret = 1;
		goto out;
	}

	if (!ifd && !fmap && process_include_args(get_global_layout())) {
		ret = 1;
		goto out;
	}
	/* Does a chip with the requested name exist in the flashchips array? */
	if (chip_to_probe) {
		for (chip = flashchips; chip && chip->name; chip++)
			if (!strcmp(chip->name, chip_to_probe))
				break;
		if (!chip || !chip->name) {
			msg_cerr("Error: Unknown chip '%s' specified.\n", chip_to_probe);
			msg_gerr("Run flashrom -L to view the hardware supported in this flashrom version.\n");
			ret = 1;
			goto out;
		}
		/* Keep chip around for later usage in case a forced read is requested. */
	}

	if (prog == PROGRAMMER_INVALID) {
		if (CONFIG_DEFAULT_PROGRAMMER != PROGRAMMER_INVALID) {
			prog = CONFIG_DEFAULT_PROGRAMMER;
			/* We need to strdup here because we free(pparam) unconditionally later. */
			pparam = strdup(CONFIG_DEFAULT_PROGRAMMER_ARGS);
			msg_pinfo("Using default programmer \"%s\" with arguments \"%s\".\n",
				  programmer_table[CONFIG_DEFAULT_PROGRAMMER].name, pparam);
		} else {
			msg_perr("Please select a programmer with the --programmer parameter.\n"
				 "Previously this was not necessary because there was a default set.\n"
#if CONFIG_INTERNAL == 1
				 "To choose the mainboard of this computer use 'internal'. "
#endif
				 "Valid choices are:\n");
			list_programmers_linebreak(0, 80, 0);
			msg_ginfo(".\n");
			ret = 1;
			goto out;
		}
	}

	/* FIXME: Delay calibration should happen in programmer code. */
	myusec_calibrate_delay();

	if (programmer_init(prog, pparam)) {
		msg_perr("Error: Programmer initialization failed.\n");
		ret = 1;
		goto out_shutdown;
	}
	tempstr = flashbuses_to_text(get_buses_supported());
	msg_pdbg("The following protocols are supported: %s.\n", tempstr);
	free(tempstr);

	for (j = 0; j < registered_master_count; j++) {
		startchip = 0;
		while (chipcount < ARRAY_SIZE(flashes)) {
			startchip = probe_flash(&registered_masters[j], startchip, &flashes[chipcount], 0);
			if (startchip == -1)
				break;
			chipcount++;
			startchip++;
		}
	}

	if (chipcount > 1) {
		msg_cinfo("Multiple flash chip definitions match the detected chip(s): \"%s\"",
			  flashes[0].chip->name);
		for (i = 1; i < chipcount; i++)
			msg_cinfo(", \"%s\"", flashes[i].chip->name);
		msg_cinfo("\nPlease specify which chip definition to use with the -c <chipname> option.\n");
		ret = 1;
		goto out_shutdown;
	} else if (!chipcount) {
		msg_cinfo("No EEPROM/flash device found.\n");
		if (!force || !chip_to_probe) {
			msg_cinfo("Note: flashrom can never write if the flash chip isn't found "
				  "automatically.\n");
		}
		if (force && read_it && chip_to_probe) {
			struct registered_master *mst;
			int compatible_masters = 0;
			msg_cinfo("Force read (-f -r -c) requested, pretending the chip is there:\n");
			/* This loop just counts compatible controllers. */
			for (j = 0; j < registered_master_count; j++) {
				mst = &registered_masters[j];
				/* chip is still set from the chip_to_probe earlier in this function. */
				if (mst->buses_supported & chip->bustype)
					compatible_masters++;
			}
			if (!compatible_masters) {
				msg_cinfo("No compatible controller found for the requested flash chip.\n");
				ret = 1;
				goto out_shutdown;
			}
			if (compatible_masters > 1)
				msg_cinfo("More than one compatible controller found for the requested flash "
					  "chip, using the first one.\n");
			for (j = 0; j < registered_master_count; j++) {
				mst = &registered_masters[j];
				startchip = probe_flash(mst, 0, &flashes[0], 1);
				if (startchip != -1)
					break;
			}
			if (startchip == -1) {
				// FIXME: This should never happen! Ask for a bug report?
				msg_cinfo("Probing for flash chip '%s' failed.\n", chip_to_probe);
				ret = 1;
				goto out_shutdown;
			}
			if (map_flash(&flashes[0]) != 0) {
				free(flashes[0].chip);
				ret = 1;
				goto out_shutdown;
			}
			msg_cinfo("Please note that forced reads most likely contain garbage.\n");
			ret = read_flash_to_file(&flashes[0], filename);
			unmap_flash(&flashes[0]);
			free(flashes[0].chip);
			goto out_shutdown;
		}
		ret = 1;
		goto out_shutdown;
	} else if (!chip_to_probe) {
		/* repeat for convenience when looking at foreign logs */
		tempstr = flashbuses_to_text(flashes[0].chip->bustype);
		msg_gdbg("Found %s flash chip \"%s\" (%d kB, %s).\n",
			 flashes[0].chip->vendor, flashes[0].chip->name, flashes[0].chip->total_size, tempstr);
		free(tempstr);
	}

	fill_flash = &flashes[0];

	print_chip_support_status(fill_flash->chip);

	unsigned int limitexceeded = count_max_decode_exceedings(fill_flash);
	if (limitexceeded > 0 && !force) {
		enum chipbustype commonbuses = fill_flash->mst->buses_supported & fill_flash->chip->bustype;

		/* Sometimes chip and programmer have more than one bus in common,
		 * and the limit is not exceeded on all buses. Tell the user. */
		if ((bitcount(commonbuses) > limitexceeded)) {
			msg_pdbg("There is at least one interface available which could support the size of\n"
				 "the selected flash chip.\n");
		}
		msg_cerr("This flash chip is too big for this programmer (--verbose/-V gives details).\n"
			 "Use --force/-f to override at your own risk.\n");
		ret = 1;
		goto out_shutdown;
	}

	if (!(read_it | write_it | verify_it | erase_it)) {
		msg_ginfo("No operations were specified.\n");
		goto out_shutdown;
	}

	if (layoutfile) {
		layout = get_global_layout();
	} else if (ifd && (flashrom_layout_read_from_ifd(&layout, fill_flash, NULL, 0) ||
			   process_include_args(layout))) {
		ret = 1;
		goto out_shutdown;
	} else if (fmap && fmapfile) {
		struct stat s;
		if (stat(fmapfile, &s) != 0) {
			msg_gerr("Failed to stat fmapfile \"%s\"\n", fmapfile);
			ret = 1;
			goto out_shutdown;
		}

		size_t fmapfile_size = s.st_size;
		uint8_t *fmapfile_buffer = malloc(fmapfile_size);
		if (!fmapfile_buffer) {
			ret = 1;
			goto out_shutdown;
		}

		if (read_buf_from_file(fmapfile_buffer, fmapfile_size, fmapfile)) {
			ret = 1;
			free(fmapfile_buffer);
			goto out_shutdown;
		}

		if (flashrom_layout_read_fmap_from_buffer(&layout, fill_flash, fmapfile_buffer, fmapfile_size) ||
				process_include_args(layout)) {
			ret = 1;
			free(fmapfile_buffer);
			goto out_shutdown;
		}
		free(fmapfile_buffer);
	} else if (fmap && (flashrom_layout_read_fmap_from_rom(&layout, fill_flash, 0,
				fill_flash->chip->total_size * 1024) || process_include_args(layout))) {
		ret = 1;
		goto out_shutdown;
	}

	flashrom_layout_set(fill_flash, layout);
	flashrom_flag_set(fill_flash, FLASHROM_FLAG_FORCE, !!force);
#if CONFIG_INTERNAL == 1
	flashrom_flag_set(fill_flash, FLASHROM_FLAG_FORCE_BOARDMISMATCH, !!force_boardmismatch);
#endif
	flashrom_flag_set(fill_flash, FLASHROM_FLAG_VERIFY_AFTER_WRITE, !dont_verify_it);
	flashrom_flag_set(fill_flash, FLASHROM_FLAG_VERIFY_WHOLE_CHIP, !dont_verify_all);

	/* FIXME: We should issue an unconditional chip reset here. This can be
	 * done once we have a .reset function in struct flashchip.
	 * Give the chip time to settle.
	 */
	programmer_delay(100000);
	if (read_it)
		ret = do_read(fill_flash, filename);
	else if (erase_it)
		ret = do_erase(fill_flash);
	else if (write_it)
		ret = do_write(fill_flash, filename, referencefile);
	else if (verify_it)
		ret = do_verify(fill_flash, filename);

	flashrom_layout_release(layout);

out_shutdown:
	programmer_shutdown();
out:
	for (i = 0; i < chipcount; i++)
		free(flashes[i].chip);

	layout_cleanup();
	free(filename);
	free(fmapfile);
	free(referencefile);
	free(layoutfile);
	free(pparam);
	/* clean up global variables */
	free((char *)chip_to_probe); /* Silence! Freeing is not modifying contents. */
	chip_to_probe = NULL;
#ifndef STANDALONE
	free(logfile);
	ret |= close_logfile();
#endif /* !STANDALONE */
	return ret;
}
Пример #11
0
int main(int argc, char *argv[]){
	int quit;
	char buf[80], prev;

	if(argc < 2){
		printf("%s <semid>\n", argv[0]);
		return 1;
	}

	semid = atoi(argv[1]);
	quit = 0;

	while(!quit){
		printf("\n> ");
		fgets(buf, sizeof(buf), stdin);

		switch(buf[0]){
		case 'r':
		case 'R':
			prev = 'r';
			do_read(buf);
			break;

		case 'w':
		case 'W':
			prev = 'w';
			do_write(buf);
			break;

		case 'q':
		case 'Q':
			quit = 1;
			break;

		case 'h':
		case 'H':
			printf("Enter one of the following commands:\n");
			printf("\tr - read a semaphore\n");
			printf("\t\tsyntax r index[.level]\n");
			printf("\t\te.g. r 1\n");
			printf("\t\te.g. r 1.val\n");
			printf("\tw - write a value\n");
			printf("\t\tsyntax w index value\n");
			printf("\t\te.g. w 1 7\n");
			printf("\tq - quit\n");
			break;

		case '\r':
		case '\n':
			if(prev == 'r'){
				sprintf(buf, "r %d\n", ++idx);
				do_read(buf);
			}
			else if(prev == 'w'){
				sprintf(buf, "w %d %d\n", ++idx, val);
				do_write(buf);
			}
			break;
			
		default:
			break;
		}
	}

	return 0;
}
Пример #12
0
static int _elf32_load(const char *filename, int fd, char *const argv[],
                       char *const envp[], uint32_t *eip, uint32_t *esp)
{
        int err = 0;
        Elf32_Ehdr header;
        Elf32_Ehdr interpheader;

        /* variables to clean up on failure */
        vmmap_t *map = NULL;
        file_t *file = NULL;
        char *pht = NULL;
        char *interpname = NULL;
        int interpfd = -1;
        file_t *interpfile = NULL;
        char *interppht = NULL;
        Elf32_auxv_t *auxv = NULL;
        char *argbuf = NULL;

        uintptr_t entry;

        file = fget(fd);
        KASSERT(NULL != file);

        /* Load and verify the ELF header */
        if (0 > (err = _elf32_load_ehdr(fd, &header, 0))) {
                goto done;
        }

        if (NULL == (map = vmmap_create())) {
                err = -ENOMEM;
                goto done;
        }

        size_t phtsize = header.e_phentsize * header.e_phnum;
        if (NULL == (pht = kmalloc(phtsize))) {
                err = -ENOMEM;
                goto done;
        }
        /* Read in the program header table */
        if (0 > (err = _elf32_load_phtable(fd, &header, pht, phtsize))) {
                goto done;
        }
        /* Load the segments in the program header table */
        if (0 > (err = _elf32_map_progsegs(file->f_vnode, map, &header, pht, 0))) {
                goto done;
        }

        Elf32_Phdr *phinterp = NULL;
        /* Check if program requires an interpreter */
        if (0 > (err = _elf32_find_phinterp(&header, pht, &phinterp))) {
                goto done;
        }

        /* Calculate program bounds for future reference */
        void *proglow;
        void *proghigh;
        _elf32_calc_progbounds(&header, pht, &proglow, &proghigh);

        entry = (uintptr_t) header.e_entry;

        /* if an interpreter was requested load it */
        if (NULL != phinterp) {
                /* read the file name of the interpreter from the binary */
                if (0 > (err = do_lseek(fd, phinterp->p_offset, SEEK_SET))) {
                        goto done;
                } else if (NULL == (interpname = kmalloc(phinterp->p_filesz))) {
                        err = -ENOMEM;
                        goto done;
                } else if (0 > (err = do_read(fd, interpname, phinterp->p_filesz))) {
                        goto done;
                }
                if (err != (int)phinterp->p_filesz) {
                        err = -ENOEXEC;
                        goto done;
                }

                /* open the interpreter */
                dbgq(DBG_ELF, "ELF Interpreter: %*s\n", phinterp->p_filesz, interpname);
                if (0 > (interpfd = do_open(interpname, O_RDONLY))) {
                        err = interpfd;
                        goto done;
                }
                kfree(interpname);
                interpname = NULL;

                interpfile = fget(interpfd);
                KASSERT(NULL != interpfile);

                /* Load and verify the interpreter ELF header */
                if (0 > (err = _elf32_load_ehdr(interpfd, &interpheader, 1))) {
                        goto done;
                }
                size_t interpphtsize = interpheader.e_phentsize * interpheader.e_phnum;
                if (NULL == (interppht = kmalloc(interpphtsize))) {
                        err = -ENOMEM;
                        goto done;
                }
                /* Read in the program header table */
                if (0 > (err = _elf32_load_phtable(interpfd, &interpheader, interppht, interpphtsize))) {
                        goto done;
                }

                /* Interpreter shouldn't itself need an interpreter */
                Elf32_Phdr *interpphinterp;
                if (0 > (err = _elf32_find_phinterp(&interpheader, interppht, &interpphinterp))) {
                        goto done;
                }
                if (NULL != interpphinterp) {
                        err = -EINVAL;
                        goto done;
                }

                /* Calculate the interpreter program size */
                void *interplow;
                void *interphigh;
                _elf32_calc_progbounds(&interpheader, interppht, &interplow, &interphigh);
                uint32_t interpnpages = ADDR_TO_PN(PAGE_ALIGN_UP(interphigh)) - ADDR_TO_PN(interplow);

                /* Find space for the interpreter */
                /* This is the first pn at which the interpreter will be mapped */
                uint32_t interppagebase = (uint32_t) vmmap_find_range(map, interpnpages, VMMAP_DIR_HILO);
                if ((uint32_t) - 1 == interppagebase) {
                        err = -ENOMEM;
                        goto done;
                }

                /* Base address at which the interpreter begins on that page */
                void *interpbase = (void *)((uintptr_t)PN_TO_ADDR(interppagebase) + PAGE_OFFSET(interplow));

                /* Offset from "expected base" in number of pages */
                int32_t interpoff = (int32_t) interppagebase - (int32_t) ADDR_TO_PN(interplow);

                entry = (uintptr_t) interpbase + ((uintptr_t) interpheader.e_entry - (uintptr_t) interplow);

                /* Load the interpreter program header and map in its segments */
                if (0 > (err = _elf32_map_progsegs(interpfile->f_vnode, map, &interpheader, interppht, interpoff))) {
                        goto done;
                }

                /* Build the ELF aux table */
                /* Need to hold AT_PHDR, AT_PHENT, AT_PHNUM, AT_ENTRY, AT_BASE,
                 * AT_PAGESZ, AT_NULL */
                if (NULL == (auxv = (Elf32_auxv_t *) kmalloc(7 * sizeof(Elf32_auxv_t)))) {
                        err = -ENOMEM;
                        goto done;
                }
                Elf32_auxv_t *auxvent = auxv;

                /* Add all the necessary entries */
                auxvent->a_type = AT_PHDR;
                auxvent->a_un.a_ptr = pht;
                auxvent++;

                auxvent->a_type = AT_PHENT;
                auxvent->a_un.a_val = header.e_phentsize;
                auxvent++;

                auxvent->a_type = AT_PHNUM;
                auxvent->a_un.a_val = header.e_phnum;
                auxvent++;

                auxvent->a_type = AT_ENTRY;
                auxvent->a_un.a_ptr = (void *) header.e_entry;
                auxvent++;

                auxvent->a_type = AT_BASE;
                auxvent->a_un.a_ptr = interpbase;
                auxvent++;

                auxvent->a_type = AT_PAGESZ;
                auxvent->a_un.a_val = PAGE_SIZE;
                auxvent++;

                auxvent->a_type = AT_NULL;

        } else {
                /* Just put AT_NULL (we don't really need this at all) */
                if (NULL == (auxv = (Elf32_auxv_t *) kmalloc(sizeof(Elf32_auxv_t)))) {
                        err = -ENOMEM;
                        goto done;
                }
                auxv->a_type = AT_NULL;
        }

        /* Allocate a stack. We put the stack immediately below the program text.
         * (in the Intel x86 ELF supplement pp 59 "example stack", that is where the
         * stack is located). I suppose we can add this "extra page for magic data" too */
        uint32_t stack_lopage = ADDR_TO_PN(proglow) - (DEFAULT_STACK_SIZE / PAGE_SIZE) - 1;
        err = vmmap_map(map, NULL, stack_lopage, (DEFAULT_STACK_SIZE / PAGE_SIZE) + 1,
                        PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, 0, 0, NULL);
        KASSERT(0 == err);
        dbg(DBG_ELF, "Mapped stack at low addr 0x%p, size %#x\n",
            PN_TO_ADDR(stack_lopage), DEFAULT_STACK_SIZE + PAGE_SIZE);


        /* Copy out arguments onto the user stack */
        int argc, envc, auxc;
        size_t argsize = _elf32_calc_argsize(argv, envp, auxv, phtsize, &argc, &envc, &auxc);
        /* Make sure it fits on the stack */
        if (argsize >= DEFAULT_STACK_SIZE) {
                err = -E2BIG;
                goto done;
        }
        /* Copy arguments into kernel buffer */
        if (NULL == (argbuf = (char *) kmalloc(argsize))) {
                err = -ENOMEM;
                goto done;
        }
        /* Calculate where in user space we start putting the args. */
        void *arglow = (void *)((uintptr_t)(((char *) proglow) - argsize) & ~PTR_MASK);
        /* Copy everything into the user address space, modifying addresses in
         * argv, envp, and auxv to be user addresses as we go. */
        _elf32_load_args(map, arglow, argsize, argbuf, argv, envp, auxv, argc, envc, auxc, phtsize);

        dbg(DBG_ELF, "Past the point of no return. Swapping to map at 0x%p, setting brk to 0x%p\n", map, proghigh);
        /* the final threshold / What warm unspoken secrets will we learn? / Beyond
         * the point of no return ... */

        /* Give the process the new mappings. */
        vmmap_t *tempmap = curproc->p_vmmap;
        curproc->p_vmmap = map;
        map = tempmap; /* So the old maps are cleaned up */
        curproc->p_vmmap->vmm_proc = curproc;
        map->vmm_proc = NULL;

        /* Flush the process pagetables and TLB */
        pt_unmap_range(curproc->p_pagedir, USER_MEM_LOW, USER_MEM_HIGH);
        tlb_flush_all();

        /* Set the process break and starting break (immediately after the mapped-in
         * text/data/bss from the executable) */
        curproc->p_brk = proghigh;
        curproc->p_start_brk = proghigh;

        strncpy(curproc->p_comm, filename, PROC_NAME_LEN);

        /* Tell the caller the correct stack pointer and instruction
         * pointer to begin execution in user space */
        *eip = (uint32_t) entry;
        *esp = ((uint32_t) arglow) - 4; /* Space on the user stack for the (garbage) return address */
        /* Note that the return address will be fixed by the userland entry code,
         * whether in static or dynamic */

        /* And we're done */
        err = 0;

done:
        if (NULL != map) {
                vmmap_destroy(map);
        }
        if (NULL != file) {
                fput(file);
        }
        if (NULL != pht) {
                kfree(pht);
        }
        if (NULL != interpname) {
                kfree(interpname);
        }
        if (0 <= interpfd) {
                do_close(interpfd);
        }
        if (NULL != interpfile) {
                fput(interpfile);
        }
        if (NULL != interppht) {
                kfree(interppht);
        }
        if (NULL != auxv) {
                kfree(auxv);
        }
        if (NULL != argbuf) {
                kfree(argbuf);
        }
        return err;
}
Пример #13
0
/*
 * Wait for all forward requests completion.
 *
 * Even if something goes wrong, we have to wait forward requests completion to
 * avoid interleaved requests.
 *
 * Return error code if any one request fails.
 */
static int wait_forward_request(struct write_info *wi, struct request *req)
{
	int nr_sent, err_ret = SD_RES_SUCCESS, ret, pollret, i,
	    repeat = MAX_RETRY_COUNT;
	struct pfd_info pi;
	struct sd_rsp *rsp = &req->rp;
again:
	pfd_info_init(wi, &pi);
	pollret = poll(pi.pfds, pi.nr, 1000 * POLL_TIMEOUT);
	if (pollret < 0) {
		if (errno == EINTR)
			goto again;

		panic("%m");
	} else if (pollret == 0) {
		/*
		 * If IO NIC is down, epoch isn't incremented, so we can't retry
		 * for ever.
		 */
		if (sheep_need_retry(req->rq.epoch) && repeat) {
			repeat--;
			sd_warn("poll timeout %d, disks of some nodes or "
				"network is busy. Going to poll-wait again",
				wi->nr_sent);
			goto again;
		}

		nr_sent = wi->nr_sent;
		/* XXX Blinedly close all the connections */
		for (i = 0; i < nr_sent; i++)
			sockfd_cache_del(wi->ent[i].nid, wi->ent[i].sfd);

		return SD_RES_NETWORK_ERROR;
	}

	nr_sent = wi->nr_sent;
	for (i = 0; i < nr_sent; i++)
		if (pi.pfds[i].revents & POLLIN)
			break;
	if (i < nr_sent) {
		int re = pi.pfds[i].revents;
		sd_debug("%d, revents %x", i, re);
		if (re & (POLLERR | POLLHUP | POLLNVAL)) {
			err_ret = SD_RES_NETWORK_ERROR;
			finish_one_write_err(wi, i);
			goto finish_write;
		}
		if (do_read(pi.pfds[i].fd, rsp, sizeof(*rsp), sheep_need_retry,
			    req->rq.epoch, MAX_RETRY_COUNT)) {
			sd_err("remote node might have gone away");
			err_ret = SD_RES_NETWORK_ERROR;
			finish_one_write_err(wi, i);
			goto finish_write;
		}

		ret = rsp->result;
		if (ret != SD_RES_SUCCESS) {
			sd_err("fail %"PRIx64", %s", req->rq.obj.oid,
			       sd_strerror(ret));
			err_ret = ret;
		}
		finish_one_write(wi, i);
	}
finish_write:
	if (wi->nr_sent > 0)
		goto again;

	return err_ret;
}
Пример #14
0
/**************************************************************
 * void chargen_thread(void *arg)
 *
 * chargen task. This server will wait for connections on well
 * known TCP port number: 19. For every connection, the server will
 * write as much data as possible to the tcp port.
 **************************************************************/
static void chargen_thread(void *arg)
{
    int listenfd;
    struct sockaddr_in chargen_saddr;
    fd_set readset;
    fd_set writeset;
    int i, maxfdp1;
    struct charcb *p_charcb;

    /* First acquire our socket for listening for connections */
    listenfd = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    LWIP_ASSERT("chargen_thread(): Socket create failed.", listenfd >= 0);
    memset(&chargen_saddr, 0, sizeof(chargen_saddr));
    chargen_saddr.sin_family = AF_INET;
    chargen_saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    chargen_saddr.sin_port = htons(19);     // Chargen server port

    if (lwip_bind(listenfd, (struct sockaddr *) &chargen_saddr, sizeof(chargen_saddr)) == -1)
        LWIP_ASSERT("chargen_thread(): Socket bind failed.", 0);

    /* Put socket into listening mode */
    if (lwip_listen(listenfd, MAX_SERV) == -1)
        LWIP_ASSERT("chargen_thread(): Listen failed.", 0);

    /* Wait forever for network input: This could be connections or data */
    for (;;)
    {
        maxfdp1 = listenfd+1;

        /* Determine what sockets need to be in readset */
        FD_ZERO(&readset);
        FD_ZERO(&writeset);
        FD_SET(listenfd, &readset);
        for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next)
        {
            if (maxfdp1 < p_charcb->socket + 1)
                maxfdp1 = p_charcb->socket + 1;
            FD_SET(p_charcb->socket, &readset);
            FD_SET(p_charcb->socket, &writeset);
        }

        /* Wait for data or a new connection */
        i = lwip_select(maxfdp1, &readset, &writeset, 0, 0);

        if (i == 0) continue;

        /* At least one descriptor is ready */
        if (FD_ISSET(listenfd, &readset))
        {
            /* We have a new connection request!!! */
            /* Lets create a new control block */
            p_charcb = (struct charcb *)rt_calloc(1, sizeof(struct charcb));
            if (p_charcb)
            {
                p_charcb->socket = lwip_accept(listenfd,
                                        (struct sockaddr *) &p_charcb->cliaddr,
                                        &p_charcb->clilen);
                if (p_charcb->socket < 0)
                    rt_free(p_charcb);
                else
                {
                    /* Keep this tecb in our list */
                    p_charcb->next = charcb_list;
                    charcb_list = p_charcb;
                    p_charcb->nextchar = 0x21;
                }
            }
			else
			{
                /* No memory to accept connection. Just accept and then close */
                int sock;
                struct sockaddr cliaddr;
                socklen_t clilen;

                sock = lwip_accept(listenfd, &cliaddr, &clilen);
                if (sock >= 0)
                    lwip_close(sock);
            }
        }
        /* Go through list of connected clients and process data */
        for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next)
        {
            if (FD_ISSET(p_charcb->socket, &readset))
            {
                /* This socket is ready for reading. This could be because someone typed
                 * some characters or it could be because the socket is now closed. Try reading
                 * some data to see. */
                if (do_read(p_charcb) < 0)
                    break;
            }
            if (FD_ISSET(p_charcb->socket, &writeset))
            {
                char line[80];
                char setchar = p_charcb->nextchar;

                for( i = 0; i < 59; i++)
                {
                    line[i] = setchar;
                    if (++setchar == 0x7f)
                        setchar = 0x21;
                }
                line[i] = 0;
                strcat(line, "\n\r");
                if (lwip_write(p_charcb->socket, line, strlen(line)) < 0)
                {
                    close_chargen(p_charcb);
                    break;
                }
                if (++p_charcb->nextchar == 0x7f)
                    p_charcb->nextchar = 0x21;
            }
        }
    }
}
Пример #15
0
/* start from bootloader_message.slot_suffix[BOOTCTRL_IDX] */
#define BOOTCTRL_IDX				0
#define BOOTCTRL_OFFSET		\
	(u32)(&(((struct bootloader_message *)0)->slot_suffix[BOOTCTRL_IDX]))
#define CRC_DATA_OFFSET		\
	(uint32_t)(&(((struct boot_ctl *)0)->a_slot_meta[0]))

struct slot_meta {
	u8 bootsuc:1;
	u8 tryremain:3;
	u8 priority:4;
};

struct boot_ctl {
	char magic[4]; /* "\0FSL" */
	u32 crc;
	struct slot_meta a_slot_meta[SLOT_NUM];
	u8 recovery_tryremain;
};

static unsigned int g_mmc_id;
static unsigned int g_slot_selected;
static const char *g_slot_suffix[SLOT_NUM] = {"_a", "_b"};

static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);

static int strcmp_l1(const char *s1, const char *s2)
{
	if (!s1 || !s2)
		return -1;
	return strncmp(s1, s2, strlen(s1));
}

void set_mmc_id(unsigned int id)
{
	g_mmc_id = id;
}

static void dump_slotmeta(struct boot_ctl *ptbootctl)
{
	int i;

	if (ptbootctl == NULL)
		return;

	printf("RecoveryTryRemain %d, crc %u\n",
		   ptbootctl->recovery_tryremain, ptbootctl->crc);

	for (i = 0; i < SLOT_NUM; i++) {
		printf("slot %d: pri %d, try %d, suc %d\n", i,
			   ptbootctl->a_slot_meta[i].priority,
				ptbootctl->a_slot_meta[i].tryremain,
				ptbootctl->a_slot_meta[i].bootsuc);
	}

	return;
}

const char *get_slot_suffix(void)
{
	return g_slot_suffix[g_slot_selected];
}

static unsigned int slot_find(struct boot_ctl *ptbootctl)
{
	unsigned int max_pri = 0;
	unsigned int slot = -1;
	int i;

	for (i	= 0; i < SLOT_NUM; i++) {
		struct slot_meta *pslot_meta = &(ptbootctl->a_slot_meta[i]);
		if ((pslot_meta->priority > max_pri) &&
			((pslot_meta->bootsuc > 0) ||
			(pslot_meta->tryremain > 0))) {
			max_pri = pslot_meta->priority;
			slot = i;
			printf("select_slot slot %d\n", slot);
		}
	}

	return slot;
}

static ulong get_block_size(char *ifname, int dev, int part)
{
	block_dev_desc_t *dev_desc = NULL;
	disk_partition_t part_info;

	dev_desc = get_dev(ifname, dev);
	if (dev_desc == NULL) {
		printf("Block device %s %d not supported\n", ifname, dev);
		return 0;
	}

	if (get_partition_info(dev_desc, part, &part_info)) {
		printf("Cannot find partition %d\n", part);
		return 0;
	}

	return part_info.blksz;
}

#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */
static int rw_block(bool bread, char **ppblock,
					uint *pblksize, char *pblock_write)
{
	int ret;
	char *argv[6];
	char addr_str[20];
	char cnt_str[8];
	char devpart_str[8];
	char block_begin_str[8];
	ulong blk_size = 0;
	uint blk_begin = 0;
	uint blk_end = 0;
	uint block_cnt = 0;
	char *p_block = NULL;

	if (bread && ((ppblock == NULL) || (pblksize == NULL)))
		return -1;

	if (!bread && (pblock_write == NULL))
		return -1;

	blk_size = get_block_size("mmc", g_mmc_id,
			CONFIG_ANDROID_MISC_PARTITION_MMC);
	if (blk_size == 0) {
		printf("rw_block, get_block_size return 0\n");
		return -1;
	}

	blk_begin = BOOTCTRL_OFFSET/blk_size;
	blk_end = (BOOTCTRL_OFFSET + sizeof(struct boot_ctl) - 1)/blk_size;
	block_cnt = 1 + (blk_end - blk_begin);

	sprintf(devpart_str, "0x%x:0x%x", g_mmc_id,
		CONFIG_ANDROID_MISC_PARTITION_MMC);
	sprintf(block_begin_str, "0x%x", blk_begin);
	sprintf(cnt_str, "0x%x", block_cnt);

	argv[0] = "rw"; /* not care */
	argv[1] = "mmc";
	argv[2] = devpart_str;
	argv[3] = addr_str;
	argv[4] = block_begin_str;
	argv[5] = cnt_str;

	if (bread) {
		p_block = (char *)memalign(ALIGN_BYTES, blk_size * block_cnt);
		if (NULL == p_block) {
			printf("rw_block, memalign %d bytes failed\n",
			       (int)(blk_size * block_cnt));
			return -1;
		}
		sprintf(addr_str, "0x%x", (unsigned int)p_block);
		ret = do_read(NULL, 0, 6, argv);
		if (ret) {
			free(p_block);
			printf("do_read failed, ret %d\n", ret);
			return -1;
		}

		*ppblock = p_block;
		*pblksize = (uint)blk_size;
	} else {
		sprintf(addr_str, "0x%x", (unsigned int)pblock_write);
		ret = do_write(NULL, 0, 6, argv);
		if (ret) {
			printf("do_write failed, ret %d\n", ret);
			return -1;
		}
	}

	return 0;
}
Пример #16
0
static int
rsh_loop (int s, int errsock)
{
    fd_set real_readset;
    int count = 1;

#ifdef KRB5
    if(auth_method == AUTH_KRB5 && protocol_version == 2)
	init_ivecs(1, errsock != -1);
#endif

    if (s >= FD_SETSIZE || (errsock != -1 && errsock >= FD_SETSIZE))
	errx (1, "fd too large");

    FD_ZERO(&real_readset);
    FD_SET(s, &real_readset);
    if (errsock != -1) {
	FD_SET(errsock, &real_readset);
	++count;
    }
    if(input)
	FD_SET(STDIN_FILENO, &real_readset);

    for (;;) {
	int ret;
	fd_set readset;
	char buf[RSH_BUFSIZ];

	readset = real_readset;
	ret = select (max(s, errsock) + 1, &readset, NULL, NULL, NULL);
	if (ret < 0) {
	    if (errno == EINTR)
		continue;
	    else
		err (1, "select");
	}
	if (FD_ISSET(s, &readset)) {
	    ret = do_read (s, buf, sizeof(buf), ivec_in[0]);
	    if (ret < 0)
		err (1, "read");
	    else if (ret == 0) {
		close (s);
		FD_CLR(s, &real_readset);
		if (--count == 0)
		    return 0;
	    } else
		net_write (STDOUT_FILENO, buf, ret);
	}
	if (errsock != -1 && FD_ISSET(errsock, &readset)) {
	    ret = do_read (errsock, buf, sizeof(buf), ivec_in[1]);
	    if (ret < 0)
		err (1, "read");
	    else if (ret == 0) {
		close (errsock);
		FD_CLR(errsock, &real_readset);
		if (--count == 0)
		    return 0;
	    } else
		net_write (STDERR_FILENO, buf, ret);
	}
	if (FD_ISSET(STDIN_FILENO, &readset)) {
	    ret = read (STDIN_FILENO, buf, sizeof(buf));
	    if (ret < 0)
		err (1, "read");
	    else if (ret == 0) {
		close (STDIN_FILENO);
		FD_CLR(STDIN_FILENO, &real_readset);
		shutdown (s, SHUT_WR);
	    } else
		do_write (s, buf, ret, ivec_out[0]);
	}
    }
}
Пример #17
0
Файл: pipe10.c Проект: bsbrp/ltp
int main(int ac, char **av)
{
    int lc;

    int fd[2];		/* fds for pipe read/write */
    char wrbuf[BUFSIZ], rebuf[BUFSIZ];
    int red, written;	/* no of chars read and */
    /* written to pipe */
    int length, greater, forkstat;
    int retval = 0, status, e_code;

    tst_parse_opts(ac, av, NULL, NULL);

    setup();

    for (lc = 0; TEST_LOOPING(lc); lc++) {

        /* reset tst_count in case we are looping */
        tst_count = 0;

        TEST(pipe(fd));

        if (TEST_RETURN == -1) {
            retval = 1;
            tst_resm(TFAIL, "pipe creation failed");
            continue;
        }

        strcpy(wrbuf, "abcdefghijklmnopqrstuvwxyz");
        length = strlen(wrbuf) + 1;

        written = write(fd[1], wrbuf, length);

        /* did write write at least some chars */
        if ((written < 0) || (written > length)) {
            tst_brkm(TBROK, cleanup, "write to pipe failed");
        }

        forkstat = FORK_OR_VFORK();

        if (forkstat == -1) {
            tst_brkm(TBROK, cleanup, "fork() failed");
        }

        if (forkstat == 0) {	/* child */
            red = do_read(fd[0], rebuf, written);

            /* did read , get at least some chars */
            if ((red < 0) || (red > written)) {
                tst_brkm(TBROK, cleanup, "read pipe failed");
            }

            greater = strcmp(rebuf, wrbuf);

            /* are the strings written and read equal */
            if (greater == 0) {
                tst_resm(TPASS, "functionality is correct");
            } else {
                retval = 1;
                tst_resm(TFAIL, "read & write strings do "
                         "not match");
            }
            exit(retval);
        } else {	/* parent */
            /* wait for the child to finish */
            wait(&status);
            /* make sure the child returned a good exit status */
            e_code = status >> 8;
            if (e_code != 0) {
                tst_resm(TFAIL, "Failures reported above");
            }
        }
    }
    cleanup();

    tst_exit();
}
Пример #18
0
/********************************************************************
* FUNCTION io_loop
*
* Handle the IO for the program
*
* INPUTS:
*
* RETURNS:
*   status
*********************************************************************/
static status_t
io_loop (void)
{
    status_t  res;
    boolean   done;
    fd_set    fds;
    int       ret;
    ssize_t   retcnt;

    res = NO_ERR;
    done = FALSE;
    FD_ZERO(&fds);

    while (!done) {
        FD_SET(STDIN_FILENO, &fds);
        FD_SET(ncxsock, &fds);

        ret = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
        if (ret < 0) {
            if ( errno != EINTR ) {
                SUBSYS_TRACE1( "ERROR: io_loop(): select() "
                               "failed with error: %s\n", strerror( errno ) );
                res = ERR_NCX_OPERATION_FAILED;
                done = TRUE;
            }
            else
            {
                SUBSYS_TRACE2( "INFO: io_loop(): select() "
                               "failed with error: %s\n", strerror( errno  ) );
            }
            continue;
        } else if (ret == 0) {
            SUBSYS_TRACE1( "ERROR: io_loop(): select() "
                           "returned 0, exiting...\n" );
            res = NO_ERR;
            done = TRUE;
            continue;
        } /* else some IO to process */

        /* check any input from client */
        if (FD_ISSET(STDIN_FILENO, &fds)) {
            /* get buff from openssh */
            retcnt = do_read(STDIN_FILENO,
                             msgbuff,
                             (size_t)BUFFLEN,
                             &res);

            if (res == ERR_NCX_EOF) {
                res = NO_ERR;
                done = TRUE;
                continue;
            } else if (res == ERR_NCX_SKIPPED) {
                res = NO_ERR;
            } else if (res == NO_ERR && retcnt > 0) {
                /* send this buffer to the ncxserver */
                res = send_buff(ncxsock, msgbuff, (size_t)retcnt);
                if (res != NO_ERR) {
                    SUBSYS_TRACE1( "ERROR: io_loop(): send_buff() to ncxserver "
                                   "failed with %s\n", strerror( errno ) );
                    done = TRUE;
                    continue;
                }
            }
        }  /* if STDIN set */

        /* check any input from the ncxserver */
        if (FD_ISSET(ncxsock, &fds)) {
            res = NO_ERR;
            retcnt = do_read(ncxsock,
                             msgbuff,
                             (size_t)BUFFLEN,
                             &res);

            if (res == ERR_NCX_EOF) {
                res = NO_ERR;
                done = TRUE;
                continue;
            } else if (res == ERR_NCX_SKIPPED) {
                res = NO_ERR;
            } else if (res == NO_ERR && retcnt > 0) {
                /* send this buffer to STDOUT */
                res = send_buff(STDOUT_FILENO, msgbuff, (size_t)retcnt);
                if (res != NO_ERR) {
                    SUBSYS_TRACE1( "ERROR: io_loop(): send_buff() to client "
                                   "failed with %s\n", strerror( errno ) );
                    done = TRUE;
                    continue;
                }
            }
        }
    }

    return res;

} /* io_loop */
Пример #19
0
void http_session::start()
{
    boost::system::error_code ec;

#ifdef DEBUG
    boost::asio::socket_base::debug option_debug(true);
    socket_->set_option(option_debug, ec);
    if (ec)
        std::cout << ec.message() << std::endl;
#endif

    /*boost::asio::socket_base::linger option_linger(true);
    socket_->set_option(option_linger, ec);
    if (ec)
        std::cout << ec.message() << std::endl;*/

    http_parser_init(&parser_, HTTP_REQUEST);
    parser_.data = this;

    /*
    
    //on_url
    parser_settings_.on_url = [](http_parser* parser, const char *at, size_t len) {
        auto psession = reinterpret_cast<http_session*>(parser->data);
        psession->request_.url_.from_buf(at, len);
        //std::cout << "on_url: " << std::string(at, len) << std::endl;
        return 0;
    };

    //on_header_field
    parser_settings_.on_header_field = [](http_parser* parser, const char* at, size_t len) {
        auto psession = reinterpret_cast<http_session*>(parser->data);

        if (psession->was_header_value_)
        {
            // new field started
            if (!psession->last_header_field_.empty())
            {
                // add new entry
                psession->request_.headers_[psession->last_header_field_] = psession->last_header_value_;
                psession->last_header_value_.clear();
            }

            psession->last_header_field_ = std::string(at, len);
            psession->was_header_value_ = false;
        }
        else
        {
            // appending
            psession->last_header_field_ += std::string(at, len);
        }

        //std::cout << "on_header_field: " << std::string(at, len) << std::endl;
        return 0;
    };

    //on_header_value
    parser_settings_.on_header_value = [](http_parser* parser, const char* at, size_t len) {
        auto psession = reinterpret_cast<http_session*>(parser->data);

        if (!psession->was_header_value_)
        {
            psession->last_header_value_ = std::string(at, len);
            psession->was_header_value_ = true;
        }
        else
        {
            // appending
            psession->last_header_value_ += std::string(at, len);
        }
        //std::cout << "on_header_value: " << std::string(at, len) << std::endl;
        return 0;
    };

    //on_headers_complete
    parser_settings_.on_headers_complete = [](http_parser* parser) {
        auto psession = reinterpret_cast<http_session*>(parser->data);

        if (!psession->last_header_field_.empty()) {
            // add new entry
            psession->request_.headers_[psession->last_header_field_] = psession->last_header_value_;
        }

        return 0;
    };
    */
    
    //on_body
    parser_settings_.on_body = [](http_parser* parser, const char* at, size_t len) {
        auto psession = reinterpret_cast<http_session*>(parser->data);

        psession->request_.body_ = const_cast<char*>(at);
        psession->request_.len_ = len;
        //std::cout << "on_body: " << std::string(at, len) << std::endl;
        return 0;
    };

    parser_settings_.on_message_complete = [](http_parser* parser) {
        auto psession = reinterpret_cast<http_session*>(parser->data);

        bool bOK = psession->server_.invoke(psession->request_, psession->response_);
        psession->process_ = true;
        psession->do_write(psession->response_.end());
        //std::cout << "on_message_complete: "  << std::endl;
        return 0;
    };

    
    //启动一个业务超时定时器,一个客户端,只允许他连接30秒,超过30秒就断开,无论有没有做完业务,时间可调。
    std::weak_ptr<http_session> wp(shared_Derived_from_this<http_session>());
    timer_.async_wait([wp](const boost::system::error_code& ec){

        if (ec != boost::asio::error::operation_aborted)
        {
            //定时器回调函数返回,但是不是定时器被取消,那么就关闭socket。
            //定期器被取消,是个正常操作
            auto sp(wp.lock());
            if (sp)
            {
                sp->close();
            }
        }
    });
    

    do_read();
}
Пример #20
0
static void
echo_test(void * p)
{
    int s_source, s_sink, e_source, e_sink;
    struct sockaddr_in e_source_addr, e_sink_addr, local;
    int one = 1;
    fd_set in_fds;
    int i, num, len;
    struct test_params params,nparams;
    struct test_status status,nstatus;

    s_source = socket(AF_INET, SOCK_STREAM, 0);
    if (s_source < 0) {
        pexit("stream socket");
    }
    if (setsockopt(s_source, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
        pexit("setsockopt /source/ SO_REUSEADDR");
    }
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
//    local.sin_len = sizeof(local);
    local.sin_port = ntohs(SOURCE_PORT);
    local.sin_addr.s_addr = INADDR_ANY;
    if(bind(s_source, (struct sockaddr *) &local, sizeof(local)) < 0) {
        pexit("bind /source/ error");
    }
    listen(s_source, SOMAXCONN);

    s_sink = socket(AF_INET, SOCK_STREAM, 0);
    if (s_sink < 0) {
        pexit("stream socket");
    }
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
//    local.sin_len = sizeof(local);
    local.sin_port = ntohs(SINK_PORT);
    local.sin_addr.s_addr = INADDR_ANY;
    if(bind(s_sink, (struct sockaddr *) &local, sizeof(local)) < 0) {
        pexit("bind /sink/ error");
    }
    if (setsockopt(s_sink, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
        pexit("setsockopt /sink/ SO_REUSEADDR");
    }
    listen(s_sink, SOMAXCONN);

    e_source = 0;  e_sink = 0;
    while (true) {
        // Wait for a connection on either of the ports
        FD_ZERO(&in_fds);
        FD_SET(s_source, &in_fds);
        FD_SET(s_sink, &in_fds);
        num = select(max(s_sink,s_source)+1, &in_fds, 0, 0, 0);
        if (FD_ISSET(s_source, &in_fds)) {
            len = sizeof(e_source_addr);
            if ((e_source = accept(s_source, (struct sockaddr *)&e_source_addr, &len)) < 0) {
                pexit("accept /source/");
            }
            diag_printf("SOURCE connection from %s:%d\n", 
                        inet_ntoa(e_source_addr.sin_addr), ntohs(e_source_addr.sin_port));
        }
        if (FD_ISSET(s_sink, &in_fds)) {
            len = sizeof(e_sink_addr);
            if ((e_sink = accept(s_sink, (struct sockaddr *)&e_sink_addr, &len)) < 0) {
                pexit("accept /sink/");
            }
            diag_printf("SINK connection from %s:%d\n", 
                        inet_ntoa(e_sink_addr.sin_addr), ntohs(e_sink_addr.sin_port));
        }
        // Continue with test once a connection is established in both directions
        if ((e_source != 0) && (e_sink != 0)) {
            break;
        }
    }

    // Wait for "source" to tell us the testing paramters
    if (do_read(e_source, &nparams, sizeof(nparams)) != sizeof(nparams)) {
        pexit("Can't read initialization parameters");
    }
  
    params.nbufs = ntohl(nparams.nbufs);
    params.bufsize = ntohl(nparams.bufsize);
    params.load = ntohl(nparams.load);
  
    diag_printf("Using %d buffers of %d bytes each, %d%% background load\n", 
                params.nbufs, params.bufsize, params.load);

    // Tell the sink what the parameters are
    if (do_write(e_sink, &nparams, sizeof(nparams)) != sizeof(nparams)) {
        pexit("Can't write initialization parameters");
    }

    status.ok = 1;
    nstatus.ok = htonl(status.ok);
  
    // Tell the "source" to start - we're all connected and ready to go!
    if (do_write(e_source, &nstatus, sizeof(nstatus)) != sizeof(nstatus)) {
        pexit("Can't send ACK to 'source' host");
    }

    TNR_ON();

    // Echo the data from the source to the sink hosts
    for (i = 0;  i < params.nbufs;  i++) {
        if ((len = do_read(e_source, data_buf, params.bufsize)) != params.bufsize) {
            TNR_OFF();
            diag_printf("Can't read buf #%d: ", i+1);
            if (len < 0) {
                perror("I/O error");
            } else {
                diag_printf("short read - only %d bytes\n", len);
            }
            TNR_ON();
        }
        if ((len = do_write(e_sink, data_buf, params.bufsize)) != params.bufsize) {
            TNR_OFF();
            diag_printf("Can't write buf #%d: ", i+1);
            if (len < 0) {
                perror("I/O error");
            } else {
                diag_printf("short write - only %d bytes\n", len);
            }
            TNR_ON();
        }
    }

    TNR_OFF();

    // Wait for the data to drain and the "sink" to tell us all is OK.
    if (do_read(e_sink, &status, sizeof(status)) != sizeof(status)) {
        pexit("Can't receive ACK from 'sink' host");
    }

}
Пример #21
0
void connection::start()
{
  ws_connected = false;
  do_read();
}
Пример #22
0
/* send a message over an already opened TCP connection */
int tcp_send_recv(int sockfd, char* buf, int len, rd_buf_t* rb, 
					unsigned int waited_id)
{
	int n, number_of_tries;
	fd_set active_fd_set, read_fd_set;
	struct timeval tv;
	unsigned long int result_code;
	AAAMessage *msg;
	AAA_AVP	*avp;
	char serviceType;
	unsigned int m_id;

	/* try to write the message to the Diameter client */
	while( (n=write(sockfd, buf, len))==-1 ) 
	{
		if (errno==EINTR)
			continue;
		LM_ERR("write returned error: %s\n", strerror(errno));
		return AAA_ERROR;
	}

	if (n!=len) 
	{
		LM_ERR("write gave no error but wrote less than asked\n");
		return AAA_ERROR;
	}

	/* wait for the answer a limited amount of time */
	tv.tv_sec = MAX_WAIT_SEC;
	tv.tv_usec = MAX_WAIT_USEC;

	/* Initialize the set of active sockets. */
	FD_ZERO (&active_fd_set);
	FD_SET (sockfd, &active_fd_set);
	number_of_tries = 0;

	while(number_of_tries<MAX_TRIES)
	{
		read_fd_set = active_fd_set;
		if (select (sockfd+1, &read_fd_set, NULL, NULL, &tv) < 0)
		{
			LM_ERR("select function failed\n");
			return AAA_ERROR;
		}
/*
		if (!FD_ISSET (sockfd, &read_fd_set))
		{
			LM_ERR("no response message received\n");
//			return AAA_ERROR;
		}
*/
		/* Data arriving on a already-connected socket. */
		reset_read_buffer(rb);
		switch( do_read(sockfd, rb) )
		{
			case CONN_ERROR:
				LM_ERR("error when trying to read from socket\n");
				return AAA_CONN_CLOSED;
			case CONN_CLOSED:
				LM_ERR("connection closed by diameter client!\n");
				return AAA_CONN_CLOSED;
		}
		
		/* obtain the structure corresponding to the message */
		msg = AAATranslateMessage(rb->buf, rb->buf_len, 0);	
		if(!msg)
		{
			LM_ERR("message structure not obtained\n");	
			return AAA_ERROR;
		}
		avp = AAAFindMatchingAVP(msg, NULL, AVP_SIP_MSGID,
								vendorID, AAA_FORWARD_SEARCH);
		if(!avp)
		{
			LM_ERR("AVP_SIP_MSGID not found\n");
			return AAA_ERROR;
		}
		m_id = *((unsigned int*)(avp->data.s));
		LM_DBG("######## m_id=%d\n", m_id);
		if(m_id!=waited_id)
		{
			number_of_tries ++;
			LM_NOTICE("old message received\n");
			continue;
		}
		goto next;
	}

	LM_ERR("too many old messages received\n");
	return AAA_TIMEOUT;
next:
	/* Finally die correct answer */
	avp = AAAFindMatchingAVP(msg, NULL, AVP_Service_Type,
							vendorID, AAA_FORWARD_SEARCH);
	if(!avp)
	{
		LM_ERR("AVP_Service_Type not found\n");
		return AAA_ERROR;
	}
	serviceType = avp->data.s[0];

	result_code = ntohl(*((unsigned long int*)(msg->res_code->data.s)));
	switch(result_code)
	{
		case AAA_SUCCESS:					/* 2001 */
			rb->ret_code = AAA_AUTHORIZED;
			break;
		case AAA_AUTHENTICATION_REJECTED:	/* 4001 */
			if(serviceType!=SIP_AUTH_SERVICE)
			{
				rb->ret_code = AAA_NOT_AUTHORIZED;
				break;
			}
			avp = AAAFindMatchingAVP(msg, NULL, AVP_Challenge,
							vendorID, AAA_FORWARD_SEARCH);
			if(!avp)
			{
				LM_ERR("AVP_Response not found\n");
				rb->ret_code = AAA_SRVERR;
				break;
			}
			rb->chall_len=avp->data.len;
			rb->chall = (unsigned char*)pkg_malloc(avp->data.len*sizeof(char));
			if(rb->chall == NULL)
			{
				LM_ERR("no more pkg memory\n");
				rb->ret_code = AAA_SRVERR;
				break;
			}
			memcpy(rb->chall, avp->data.s, avp->data.len);
			rb->ret_code = AAA_CHALENGE;
			break;
		case AAA_AUTHORIZATION_REJECTED:	/* 5003 */
			rb->ret_code = AAA_NOT_AUTHORIZED;
			break;
		default:							/* error */
			rb->ret_code = AAA_SRVERR;
	}
	
    return rb->ret_code;	
}
Пример #23
0
static int id_read(struct file *file, void *buffer, dword count, dword offset)
{
    return do_read(file, offset, buffer, count);
}
Пример #24
0
void HTTPConnection::start()
{
    do_read();
}
Пример #25
0
int get_sb(char *device, struct gen_sb *sb_out)
{
	int fd;

	fd = open(device, O_RDONLY);
	if (fd < 0)
		die("can't open %s: %s\n", device, strerror(errno));

	if (!strcmp(fsname, "gfs2")) {
		char buf[GFS2_BASIC_BLOCK];
		struct gfs2_sb sb;

		if (lseek(fd, GFS2_SB_ADDR * GFS2_BASIC_BLOCK, SEEK_SET) !=
		    GFS2_SB_ADDR * GFS2_BASIC_BLOCK) {
			fprintf(stderr, "bad seek: %s from %s:%d: "
				"superblock\n",
				strerror(errno), __FUNCTION__, __LINE__);
			exit(-1);
		}
		do_read(fd, buf, GFS2_BASIC_BLOCK);
		gfs2_sb_in(&sb, buf);

		if (sb.sb_header.mh_magic != GFS2_MAGIC ||
	    	    sb.sb_header.mh_type != GFS2_METATYPE_SB) {
			die("there isn't a GFS2 filesystem on %s, "
			    "magic=%x type=%x\n", device,
			    sb.sb_header.mh_magic, sb.sb_header.mh_type);
		}

		if (sb.sb_fs_format != GFS2_FORMAT_FS ||
		    sb.sb_multihost_format != GFS2_FORMAT_MULTI) {
			die("there appears to be a GFS, not GFS2, filesystem "
			    "on %s\n", device);
		}

		strncpy(sb_out->lockproto, sb.sb_lockproto, 256);
		strncpy(sb_out->locktable, sb.sb_locktable, 256);

	} else if (!strcmp(fsname, "gfs")) {
		char buf[GFS_BASIC_BLOCK];
		struct gfs_sb sb;

		if (lseek(fd, GFS_SB_ADDR * GFS_BASIC_BLOCK, SEEK_SET) !=
		    GFS_SB_ADDR * GFS_BASIC_BLOCK) {
			fprintf(stderr, "bad seek: %s from %s:%d: "
				"superblock\n",
				strerror(errno), __FUNCTION__, __LINE__);
			exit(-1);
		}
		do_read(fd, buf, GFS2_BASIC_BLOCK);
		gfs_sb_in(&sb, buf);

		if (sb.sb_header.mh_magic != GFS_MAGIC ||
		    sb.sb_header.mh_type != GFS_METATYPE_SB) {
			die("there isn't a GFS filesystem on %s\n", device);
		}

		if (sb.sb_fs_format != GFS_FORMAT_FS ||
		    sb.sb_multihost_format != GFS_FORMAT_MULTI) {
			die("there appears to be a GFS2, not GFS, filesystem "
			    "on %s\n", device);
		}

		strncpy(sb_out->lockproto, sb.sb_lockproto, 256);
		strncpy(sb_out->locktable, sb.sb_locktable, 256);
	}

	close(fd);
	return 0;
}
Пример #26
0
/* Reads N bytes from EA at byte offset OFFSET into DATA.
   Returns true if successful, false on failure.  */
bool
ext_array_read (const struct ext_array *ea, off_t offset, size_t n, void *data)
{
  return do_seek (ea, offset) && do_read (ea, data, n);
}
Пример #27
0
void process_connection(int ci)
{
	struct boothc_header h;
	char *data = NULL;
	char *site, *ticket;
	int local, rv;
	void (*deadfn) (int ci);

	rv = do_read(client[ci].fd, &h, sizeof(h));

	if (rv < 0) {
		if (errno == ECONNRESET)
			log_debug("client %d connection reset for fd %d", ci, client[ci].fd);
		else 
			log_debug("client %d read failed for fd %d: %s (%d)",
				  ci, client[ci].fd,
				  strerror(errno), errno);

		deadfn = client[ci].deadfn;
		if(deadfn) {
			log_debug("run deadfn");
			deadfn(ci);
		}
		return;
	}
	if (h.magic != BOOTHC_MAGIC) {
		log_error("connection %d magic error %x", ci, h.magic);
		return;
	}
	if (h.version != BOOTHC_VERSION) {
		log_error("connection %d version error %x", ci, h.version);
		return;
	}

	if (h.len) {
		data = malloc(h.len);
		if (!data) {
			log_error("process_connection no mem %u", h.len);
			return;
		}
		memset(data, 0, h.len);

		rv = do_read(client[ci].fd, data, h.len);
		if (rv < 0) {
			log_error("connection %d read data error %d", ci, rv);
			goto out;
		}
	}

	switch (h.cmd) {
	case BOOTHC_CMD_LIST:
		assert(!data);
		h.result = list_ticket(&data, &h.len);
		break;

	case BOOTHC_CMD_GRANT:
		h.len = 0;
		site = data;
		ticket = data + BOOTH_NAME_LEN;
		if (!check_ticket(ticket)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (!check_site(site, &local)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (local)
			h.result = grant_ticket(ticket, h.option);
		else
			h.result = BOOTHC_RLT_REMOTE_OP;
		break;

	case BOOTHC_CMD_REVOKE:
		h.len = 0;
		site = data;
		ticket = data + BOOTH_NAME_LEN;
		if (!check_ticket(ticket)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (!check_site(site, &local)) {
			h.result = BOOTHC_RLT_INVALID_ARG;
			goto reply;
		}
		if (local)
			h.result = revoke_ticket(ticket, h.option);
		else
			h.result = BOOTHC_RLT_REMOTE_OP;
		break;

	case BOOTHC_CMD_CATCHUP:
		h.result = catchup_ticket(&data, h.len);	
		break;

	default:
		log_error("connection %d cmd %x unknown", ci, h.cmd);
		break;
	}

reply:
	rv = do_write(client[ci].fd, &h, sizeof(h));
	if (rv < 0)
		log_error("connection %d write error %d", ci, rv);
	if (h.len) {
		rv = do_write(client[ci].fd, data, h.len);
		if (rv < 0)
			log_error("connection %d write error %d", ci, rv);
	}
out:
	free(data);	
}
Пример #28
0
int do_copy_utf16_to_utf8(const char *src, const char *des)
{
    int buflen;
    char  buffer16[CPBUFFERSIZE];
    char  buffer8[CPBUFFERSIZE];
    int rc = 0;
    int fd1 = -1, fd2 = -1;
    struct stat info;
    int r_count, w_count = 0, i, buf8_count, buf16_count;

    if (src == NULL || des == NULL) return -1;

    if (stat(src, &info) < 0) {
        LOGE("%s: can not open file: %s\n", __FUNCTION__, src);
        return -1;
    }

    if ( ( fd1 = open(src, O_RDONLY) ) < 0 ) {
        return -1;
    }

    if ( ( fd2 = open(des, O_WRONLY | O_CREAT | O_TRUNC, 0660) ) < 0) {
        LOGE("%s: can not open file: %s\n", __FUNCTION__, des);
        close(fd1);
        return -1;
    }

    /* Start copy loop */
    while (1) {
        /* Read data from src */
        r_count = do_read(fd1, buffer16, CPBUFFERSIZE);
        if (r_count < 0) {
            LOGE("%s: read failed, err:%s", __FUNCTION__, strerror(errno));
            rc = -1;
            break;
        }

        if (r_count == 0)
            break;
        /* convert loop, basic strategy => remove odd char */
        for (buf8_count = 0, buf16_count = 0; buf16_count < r_count; buf8_count++, buf16_count += 2) {
            buffer8[buf8_count] = (char) buffer16[buf16_count];
        }

        /* Copy data to des */
        w_count = do_write(fd2, buffer8, buf8_count);
        if (w_count < 0) {
            LOGE("%s: write failed, err:%s", __FUNCTION__, strerror(errno));
            rc = -1;
            break;
        }
        if (buf8_count != w_count) {
            LOGE("%s: write failed, r_count:%d w_count:%d",
                 __FUNCTION__, r_count, w_count);
            rc = -1;
            break;
        }
    }

    /* Error occurred while copying data */
    if ((rc == -1) && (w_count == -ENOSPC)) {
        /* CRASHLOG_ERROR_FULL shall only be raised if des indicates LOGS_DIR */
        if (check_partlogfull(des))
            raise_infoerror(ERROREVENT, CRASHLOG_ERROR_FULL);
    }

    if (fd1 >= 0)
        close(fd1);
    if (fd2 >= 0)
        close(fd2);

    do_chown(des, PERM_USER, PERM_GROUP);
    return rc;
}
/* Must be run in process context as the kernel function si_meminfo() can sleep */
static void wq_sched_handler(struct work_struct *wsptr)
{
	do_read();
}
Пример #30
0
int main(int argc, char **argv) {
	struct epoll_event events[1024];
	int pending;
	int i, n, r;

	(void) argc;

	if (argv[1] == NULL || (n_conns = atoi(argv[1])) == 0)
		n_conns = 100;

	/* x2 for both ends of streams, +2 for server and timerfd conn_rec */
	E(conns = calloc(n_conns * 2 + 2, sizeof(*conns)));
	E(client_conns = calloc(n_conns, sizeof(**client_conns)));
	E(server_conns = calloc(n_conns, sizeof(**server_conns)));

	E(epfd = epoll_create1(0));
	E(svfd = socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0));
	{
		int yes = 1;
		E(setsockopt(svfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes));
	}
	{
		struct sockaddr_in s;
		s.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		s.sin_family = AF_INET;
		s.sin_port = htons(PORT);
		E(bind(svfd, (struct sockaddr *) &s, sizeof s));
	}
	E(listen(svfd, 1024));
	fd_add(svfd, EPOLLIN);

	for (pending = i = 0; i < n_conns; i++) {
		struct sockaddr_in s;
		conn_rec *c;
		int fd;

		E(fd = socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0));
		s.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		s.sin_family = AF_INET;
		s.sin_port = htons(PORT);

		if (connect(fd, (struct sockaddr *) &s, sizeof s) == 0)
			c = fd_add(fd, EPOLLIN);
		else if (errno != EINPROGRESS)
			report_error("connect", errno);
		else {
			c = fd_add(fd, EPOLLOUT);
			pending++;
		}

		client_conns[n_client_conns++] = c;
	}

	while (pending) {
		E(n = epoll_wait(epfd, events, ARRAY_SIZE(events), -1));

		for (i = 0; i < n; i++) {
			conn_rec *c = events[i].data.ptr;

			if (c->fd == svfd) {
				struct sockaddr_in s;
				socklen_t len;
				int fd;

				len = sizeof s;
				E(fd = accept4(svfd, (struct sockaddr *) &s, &len, SOCK_NONBLOCK));
				server_conns[n_server_conns++] = fd_add(fd, EPOLLIN);
			}
			else {
				socklen_t len;
				int status;

				len = sizeof status;
				E(getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &status, &len));

				if (status)
					report_error("getsockopt(SO_ERROR)", EINVAL);

				fd_mod(c, EPOLLIN);
				pending--;
			}
		}
	}

	//assert(n_client_conns == n_server_conns);

	for (i = 0; i < n_client_conns; i++) {
		conn_rec *c = client_conns[i];
		r = write(c->fd, "PING", 4);
		//assert(r == 4);
		fd_mod(c, EPOLLIN|EPOLLOUT);
		c->events = EPOLLIN;
	}

	for (i = 0; i < n_server_conns; i++) {
		conn_rec *c = server_conns[i];
		do_write(c->fd, "PONG", 4);
		fd_mod(c, EPOLLIN|EPOLLOUT);
		c->events = EPOLLIN;
	}

	fd_add(make_timer_fd(2000), EPOLLIN);

	while (1) {
		E(n = epoll_wait(epfd, events, ARRAY_SIZE(events), -1));

		for (i = 0; i < n; i++) {
			conn_rec *c = events[i].data.ptr;

			if (c->fd == tmfd) {
				do_read(c->fd);
        do_report();
				continue;
			}

			if ((events[i].events & EPOLLIN) & (c->events & EPOLLIN)) {
				do_read(c->fd);
        c->events = EPOLLOUT;
        continue;
			}

			if ((events[i].events & EPOLLOUT) & (c->events & EPOLLOUT)) {
				do_write(c->fd, "PING", 4);
        c->events = EPOLLIN;
        continue;
			}
		}
	}

	return 0;
}