コード例 #1
0
ファイル: tcp.hpp プロジェクト: david-k/protoperf
	virtual void listen()
	{
		if(::bind(m_socket, m_addr.native_address(), m_addr.native_size()) == -1)
			throw std::runtime_error{"bind(): " + errno_string(errno)};

		if(::listen(m_socket, 10) == -1)
			throw std::runtime_error{"listen(): " + errno_string(errno)};
	}
コード例 #2
0
ファイル: tcp.hpp プロジェクト: david-k/protoperf
	virtual size_t write(char const *src, size_t size)
	{
		// Retry on EINTR.
		while(true)
		{
			// MSG_NOSIGNAL: Return EPIPE instead of sending a SIGPIPE signal if the connection has
			// been closed.
			auto send_res = ::send(m_socket, src, size, MSG_NOSIGNAL);
			if(send_res == -1)
			{
				if(errno == EPIPE || errno == ECONNRESET)
				{
					// Connection has been closed
					return 0;
				}
				else if(errno != EINTR)
					throw std::runtime_error{"send(): " + errno_string(errno)};
			}
			else
			{
				socket_logger().add_bytes_written(send_res);
				return send_res;
			}
		}
	}
コード例 #3
0
ファイル: tcp.hpp プロジェクト: david-k/protoperf
	explicit TCPSocket(Address const &addr) :
		m_addr{addr},
		m_socket{::socket(m_addr.family(), m_addr.type(), 0)}
	{
		if(m_socket == -1)
			throw std::runtime_error{"socket(): " + errno_string(errno)};
	}
コード例 #4
0
ファイル: tcp.hpp プロジェクト: david-k/protoperf
T setsockopt(int sock, int level, int opt_name, T val)
{
	socklen_t len = sizeof(T);
	if(setsockopt(sock, level, opt_name, (void*)&val, len) == -1)
		throw std::runtime_error{"setsockopt(): " + errno_string(errno)};

	return val;
}
コード例 #5
0
ファイル: tcp.hpp プロジェクト: david-k/protoperf
	virtual void print_statistics()
	{
		tcp_info info;
		socklen_t info_size = sizeof(info);
		if(getsockopt(m_socket, SOL_TCP, TCP_INFO, (void*)&info, &info_size) != 0)
			throw std::runtime_error{"getsockopt(): " + errno_string(errno)};

		std::cout << "RTT: " << info.tcpi_rtt / 1000.0 << " ms\n"
		          << "Lost packets: " << info.tcpi_lost << '\n'
		          << "Retrans: " << info.tcpi_retrans << '\n'
		          << "Total retransmits: " << info.tcpi_total_retrans << std::endl;
	}
コード例 #6
0
ファイル: tcp.hpp プロジェクト: david-k/protoperf
	virtual void connect()
	{
		// Retry on EINTR.
		// It seems this only works on Linux, see http://www.madore.org/~david/computers/connect-intr.html
		// for more information.
		while(true)
		{
			if(::connect(m_socket, m_addr.native_address(), m_addr.native_size()) == -1)
			{
				if(errno != EINTR)
					throw std::runtime_error{"connect(): " + errno_string(errno)};
			}
			else
				break;
		}
	}
コード例 #7
0
ファイル: tcp.hpp プロジェクト: david-k/protoperf
	virtual std::ostream& stats_csv(std::ostream &os)
	{
		tcp_info info;
		socklen_t info_size = sizeof(info);
		if(getsockopt(m_socket, SOL_TCP, TCP_INFO, (void*)&info, &info_size) != 0)
			throw std::runtime_error{"getsockopt(): " + errno_string(errno)};

		os << Milliseconds{info.tcpi_rtt / 1000.0}.count()
		   << ',' << info.tcpi_snd_cwnd
		   << ',' << info.tcpi_snd_mss
		   << ',' << info.tcpi_rcv_mss
		   << ',' << info.tcpi_reordering
		   << ',' << info.tcpi_snd_ssthresh
		   << ',' << info.tcpi_rcv_ssthresh
		;

		return os;
	}
コード例 #8
0
ファイル: md_env.cpp プロジェクト: zalemwoo/mordor-v8
v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate,
                            int errorno,
                            const char *syscall,
                            const char *msg,
                            const char *path) {
  Environment* env = Environment::GetCurrent(isolate);

  v8::Local<v8::Value> e;
  v8::Local<v8::String> estring = OneByteString(env->isolate(), errno_string(errorno));
  if (msg == NULL || msg[0] == '\0') {
    msg = strerror(errorno);
  }
  v8::Local<v8::String> message = OneByteString(env->isolate(), msg);

  v8::Local<v8::String> cons1 =
          v8::String::Concat(estring, FIXED_UTF8_STRING(env->isolate(), ", "));
  v8::Local<v8::String> cons2 = v8::String::Concat(cons1, message);

  if (path) {
    v8::Local<v8::String> cons3 =
            v8::String::Concat(cons2, FIXED_UTF8_STRING(env->isolate(), " '"));
    v8::Local<v8::String> cons4 =
            v8::String::Concat(cons3, v8::String::NewFromUtf8(env->isolate(), path));
    v8::Local<v8::String> cons5 =
            v8::String::Concat(cons4, FIXED_UTF8_STRING(env->isolate(), "'"));
    e = v8::Exception::Error(cons5);
  } else {
    e = v8::Exception::Error(cons2);
  }

  v8::Local<v8::Object> obj = e->ToObject();
  obj->Set(env->errno_string(), v8::Integer::New(env->isolate(), errorno));
  obj->Set(env->code_string(), estring);

  if (path != NULL) {
    obj->Set(env->path_string(), v8::String::NewFromUtf8(env->isolate(), path));
  }

  if (syscall != NULL) {
    obj->Set(env->syscall_string(), OneByteString(env->isolate(), syscall));
  }

  return e;
}
コード例 #9
0
ファイル: tcp.hpp プロジェクト: david-k/protoperf
	virtual size_t read(char *dest, size_t size)
	{
		// Retry on EINTR.
		while(true)
		{
			auto recv_res = ::recv(m_socket, dest, size, 0);
			if(recv_res == -1)
			{
				if(errno != EINTR)
					throw std::runtime_error{"recv(): " + errno_string(errno)};
			}
			else
			{
				socket_logger().add_bytes_read(recv_res);

				// If recv_res == 0 the connection has been closed.
				return recv_res;
			}
		}
	}
コード例 #10
0
ファイル: tcp.hpp プロジェクト: david-k/protoperf
	virtual std::unique_ptr<Socket> accept()
	{
		// Retry on EINTR and ECONNABORTED.
		while(true)
		{
			::sockaddr_storage client_addr;
			socklen_t addr_size = sizeof(client_addr);
			int client_sock = ::accept(m_socket, (::sockaddr*)&client_addr, &addr_size);

			if(client_sock == -1)
			{
				if(errno != EINTR && errno != ECONNABORTED)
					throw std::runtime_error{"accept(): " + errno_string(errno)};
			}
			else
			{
				Address addr{m_addr.type(), "", (::sockaddr*)&client_addr, addr_size};
				return std::unique_ptr<TCPSocket>{new TCPSocket{addr, client_sock}};
			}
		}
	}
コード例 #11
0
ファイル: directory_lock.hpp プロジェクト: B-sound/rethinkdb
 directory_open_failed_exc_t(int err, const base_path_t &path) {
     info = strprintf("Could not open directory '%s': %s",
                      path.path().c_str(), errno_string(err).c_str());
 }
コード例 #12
0
ファイル: request.c プロジェクト: andreiw/polaris
SNMP_pdu *request_send_to_port_time_out_blocking(IPAddress *ip_address, int port,struct timeval *timeout,SNMP_pdu *request, char *error_label)
{
	int sd;
	Address address;
	SNMP_pdu *response;
	Address me;
	int numfds;
	fd_set fdset;
	int count;


	error_label[0] = '\0';

	if(request == NULL)
	{
		sprintf(error_label, "BUG: request_send_blocking(): request is NULL");
		return NULL;
	}

	switch(request->type)
	{
		case GET_REQ_MSG:
		case GETNEXT_REQ_MSG:
		case SET_REQ_MSG:
			break;

		default:
			sprintf(error_label, "BUG: request_send_blocking(): bad type (0x%x)",
				request->type);
			return NULL;
	}

	/* sd */
	sd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sd < 0)
	{
		sprintf(error_label, ERR_MSG_SOCKET,
			errno_string());
		return (NULL);
	}

	memset(&me, 0, sizeof (Address));
	me.sin_family = AF_INET;
	if ((request->type) == SET_REQ_MSG)
		me.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	else
		me.sin_addr.s_addr = htonl(INADDR_ANY);
	me.sin_port = htons(0);
	if(bind(sd, (struct sockaddr *)&me, sizeof(me)) != 0)
	{
		sprintf(error_label, ERR_MSG_BIND,
			errno_string());
		(void)close(sd);
		return NULL;
	}

	/* address */
	memset(&address, 0, sizeof(Address));
	address.sin_family = AF_INET;
	/* LINTED */
	address.sin_port = (short)port;
	address.sin_addr.s_addr = ip_address->s_addr;

	if(snmp_pdu_send(sd, &address, request, error_label))
	{
		(void)close(sd);
		return NULL;
	}


	for (;;)
	{
		numfds = 0;
		FD_ZERO(&fdset);

		numfds = sd + 1;
		FD_SET(sd, &fdset);

		count = select(numfds, &fdset, 0, 0, timeout);
		if(count > 0)
		{
			if(FD_ISSET(sd, &fdset))
			{
				response = snmp_pdu_receive(sd, &address, error_label);
				if(response == NULL)
				{
					(void)close(sd);
					return NULL;
				}
				(void)close(sd);

				return response;
			}
		}
		else
		{
			switch(count)
			{
				case 0:
					sprintf(error_label, ERR_MSG_TIMEOUT);
					(void)close(sd);
					return NULL;

				case -1:
					if(errno == EINTR)
					{
						continue;
					}
					else
					{
						sprintf(error_label, ERR_MSG_SELECT,
							errno_string());
						(void)close(sd);
						return NULL;
					}
			}
		}
	}
	/* NOTREACHED */
}
コード例 #13
0
ファイル: UErrNoBMS.c プロジェクト: idunham/cdesktop
/*
 * This function calls the CDE message logging service.
 */
static void 
log_message(
        char *progName,
        char *help,
        char *message,
        DtSeverity severity,
        int errnoset )
{
   char			* errmsg = NULL;
   char			* errname = NULL;
   char			format[25];
   DtMsgLogType 	msg_type;
   char                 buff[40];
   
   (void) strcpy (format, "%s");

   if (help)
      (void) strcat (format, "\n  %s");

   if (errnoset) {
      unsigned int	errn;

      if (errnoset == TRUE)		/* Use "errno" from <errno.h> ? */
	 errn = errno;			/* --- yep.			*/
      else
	 errn = errnoset;		/* No, not the magic value, use parm */

      errname = errno_string(errn, buff);

      if (!(errmsg = strerror(errn)))
 	 errmsg = "unknown";
   } 

   /*
    * Must map the old message types to the new
    */
   switch (severity) {
      case DtError:
	   DtFatalError:
	   DtInternalError: 
		msg_type = DtMsgLogError; break;
      case DtIgnore:
	   DtInformation:
		msg_type = DtMsgLogInformation; break;
      case DtWarning:
		msg_type = DtMsgLogWarning; break;
      default: 
		msg_type = DtMsgLogError;
   }

   if (errmsg)
      (void) strcat (format, "\n  [%s] %s");

   if (help) {
      if (errmsg)
	 DtMsgLogMessage (progName, msg_type, format, message, help, 
			  errname, errmsg);
      else
	 DtMsgLogMessage (progName, msg_type, format, message, help);
   } else {
      if (errmsg)
	 DtMsgLogMessage (progName, msg_type, format, message, errname, errmsg);
      else
         DtMsgLogMessage (progName, msg_type, format, message);
   }
}
コード例 #14
0
ファイル: dispatcher.c プロジェクト: CoryXie/opensolaris
int
main(int argc, char *argv[])
{
	int arg;
	int Fails ; 
	char *str;
	int level;
	char *error_file = NULL;

 	extern char *optarg;
	extern int optind;
	int opt;

	error_init(argv[0], application_end);

	optind = 1;


	{
        char domain_path[MAXPATHLEN];

        setlocale(LC_ALL, "");

        sprintf(domain_path, SEA_LOCALE_PATH);

        bindtextdomain(DOMAIN_MGET, domain_path);
        bindtextdomain(DOMAIN_SGET,   domain_path);
        bindtextdomain(DOMAIN_LIBGET,   domain_path);
        bindtextdomain(DOMAIN_LGET, domain_path);
        bindtextdomain(DOMAIN_FGET,  domain_path);  /* formatting string */
	}


	/* parse arguments */
	while((opt = getopt(argc,argv,"c:i:hr:m:o:p:a:d:yf:n:?"))!=EOF){
		switch(opt){
				case 'h':
				case '?':
					print_usage();
					break;
				case 'f':
					Fails = strtol (optarg, &str, 10) ; 
					if (optarg == str) { 
						fprintf (stderr, "Invalid number following the -t option: %s\n", optarg ) ; 
						print_usage () ; 
					} else {
						SetFailThreshold (Fails) ; 
					}
					break ; 	
					

				case 'y':
					recovery_on=TRUE;
					break;

				case 'p':
					port = strtol(optarg, &str, 10);
					if(optarg == str)
					{
						fprintf(stderr, "Not a valid integer following the -p option: %s\n", optarg);
						print_usage();
					}

					break;

				case 'n':
					relay_agent_name = strdup(optarg);
					if(relay_agent_name == NULL)
					{
						fprintf(stderr, "%s\n", ERR_MSG_ALLOC);
						exit(1);
					}

					break;

				case 'o':
					if(optind > argc)
					{
						fprintf(stderr, "must have the enterprise name-oid file\n");
						print_usage();
					}

					name_oid_file= strdup(optarg);
					if(name_oid_file == NULL)
					{
						fprintf(stderr, "%s\n", ERR_MSG_ALLOC);
						exit(1);
					}

					break;

				case 'c':
					if(optind > argc)
					{
						fprintf(stderr, "Must have a configuration directory name following the -c option\n");
						print_usage();
					}

					config_dir = strdup(optarg);
					if(config_dir == NULL)
					{
						fprintf(stderr, "%s\n", ERR_MSG_ALLOC);
						exit(1);
					}

					break;

                                case 'a':
                                        if(optind > argc)
                                        {
                                                fprintf(stderr, "Must have a access control filename following the -a option\n");
                                                print_usage();
                                        }

                                        sec_config_file = strdup(optarg);
                                        if(sec_config_file == NULL)
                                        {
                                                fprintf(stderr, "%s\n", ERR_MSG_ALLOC);
                                                exit(1);
                                        }

                                        break;

				case 'r':
					if(optind > argc)
					{
						fprintf(stderr, "Must have a resource file name following the -r option\n");
						print_usage();
					}

					resource_file = strdup(optarg);
					if(resource_file == NULL)
					{
						fprintf(stderr, "%s\n", ERR_MSG_ALLOC);
						exit(1);
					}

					break;

				case 'i':
					if(optind > argc)
					{
						fprintf(stderr, "Must have a pid file name following the -i option\n");
						print_usage();
					}

					pid_file = strdup(optarg);
					if(pid_file == NULL)
					{
						fprintf(stderr, "%s\n", ERR_MSG_ALLOC);
						exit(1);
					}

					break;


				case 'd':
					if(optind> argc)
					{
						fprintf(stderr, "Must have a trace-level following the -d option\n");
						print_usage();
					}

					level = strtol(optarg, &str, 10);
					if(optarg == str)
					{
						fprintf(stderr, "Not a valid integer following the -d option: %s\n", optarg);
						print_usage();
					}

					if(trace_set(level, error_label))
					{
						print_usage();
					}

					break;

				case 'm':
					if(optind > argc)
					{
						fprintf(stderr, "Must have GROUP or SPLIT following the -m option\n");
						print_usage();
					}

					if(strcmp(optarg, "GROUP") == 0)
					{
						mode = MODE_GROUP;
					}
					else
					if(strcmp(optarg, "SPLIT") == 0)
					{
						mode = MODE_SPLIT;
					}
					else
					{
						fprintf(stderr, "Invalid mode: %s\n", optarg);
						print_usage();
					}

					break;

				default:
					fprintf(stderr, "Invalid Option: -%c\n", optarg);
					print_usage();
					break;
			}
		}


/*
	if(error_file == NULL)
	{
		error_file = default_error_file;
	}
	error_open(error_file);
*/

	if(trace_level == 0)
	{
		/* run the daemon in backgound */

		int pid;

		pid = fork();
		switch(pid)
		{
			case -1:
				error_exit(ERR_MSG_FORK, errno_string());
				break;

			case 0: /* child process */
				break;

			default: /* parent process */
				exit(0);
				break;
		}
	}

	if(fclose(stdin) == EOF)
	{
		error(ERR_MSG_FCLOSE, "stdin", errno_string());
	}

	dispatcher_init();

	if(signals_init(signals_sighup, signals_exit, error_label))
	{
		error_exit("signals_init() failed: %s", error_label);
	}
	
	if(trace_level == 0)
	{
		if(fclose(stdout) == EOF)
		{
			error(ERR_MSG_FCLOSE, "stdout", errno_string());
		}
	}

	if(trace_level == 0)
	{
		/* background */

		if(chdir("/") == -1)
		{
			error(ERR_MSG_CHDIR, "/", errno_string());
		}

		/* set process group ID */
		setpgrp();

		error_close_stderr();
	}

	dispatcher_loop();

	return (0);
}
コード例 #15
0
ファイル: dispatcher.c プロジェクト: CoryXie/opensolaris
static void dispatcher_loop()
{
	int numfds;
	fd_set fdset;
	int count;
	struct timeval timeout;


	timeout.tv_usec = 0;

	while(1)
	{
		if(sighup)
		{
			resource_update(config_dir);
			sighup = False;
		}

		if(trace_level > 1)
		{
			trace_sessions();
		}

		numfds = 0;
		FD_ZERO(&fdset);

		numfds = MAX(clients_sd, agents_sd);
		numfds = MAX(numfds,trap_sd);
		numfds++;
		FD_SET(clients_sd, &fdset);
		FD_SET(agents_sd, &fdset);
		FD_SET(trap_sd, &fdset);

		timeout.tv_sec = relay_agent_poll_interval;

		/* we compute the timeout according to the	*/
		/* timeout of the pending requests		*/
		session_select_info(&timeout);

		count = select(numfds, &fdset, 0, 0, &timeout);
		if(count > 0)
		{
			if(FD_ISSET(agents_sd, &fdset))
			{
				/* we read the responses of the agents */
				session_read();
				continue;
				
			}

			if(FD_ISSET(trap_sd, &fdset))
			{
				/* working on the trap */
				trap_processing();
				continue;
				
			}

			if(FD_ISSET(clients_sd, &fdset))
			{
				/* we dispatch the requests of the application */
				session_dispatch();

			        session_timeout();
				continue;
			}

		}
		else
		{
			switch(count)
			{
				case 0:
					/* we check if some requests have timeout */
					session_timeout();
					  watch_dog_in_action();
					break;

				case -1:
					if(errno == EINTR)
					{
						break;
					}
					else
					{
						error_exit(ERR_MSG_SELECT, errno_string());
					}
			}
		}
	}
}
コード例 #16
0
ファイル: dispatcher.c プロジェクト: CoryXie/opensolaris
static void
dispatcher_init()
{
	struct sockaddr_in me;
	socklen_t len;

	/* init my_ip_address (we need it before parsing the config file) */

	if(get_my_ip_address(&my_ip_address, error_label))
		error_exit(ERR_MSG_MY_IP_ADDRESS,
			error_label);

	if(trace_level > 0)
		trace("Local IP Addresss : %s\n\n",
			inet_ntoa(my_ip_address));


	/* init the config_dir pointer and then parse the configuration files */

	if(config_dir == NULL)
		config_dir = default_config_dir;

	config_init(config_dir);

	/* read enterprise name-oid file */
	if(name_oid_file == NULL)
		name_oid_file = default_name_oid_file;

	load_enterprise_oid(name_oid_file);

	/* set up the relay agent name */
	if(sec_config_file == NULL)
		sec_config_file = default_sec_config_file;

	sec_config_init(sec_config_file);
	if(relay_agent_name == NULL)
		relay_agent_name = default_relay_agent_name;

	init_relay_agent();

	/* read the resource file */
	if(resource_file == NULL)
		resource_file = default_resource_file;
	if(pid_file == NULL)
		pid_file = default_pid_file;
	write_pid_file1(pid_file);
	res_config_init(config_dir);

	/* init clients_sd and agents_sd */

	clients_sd = socket(AF_INET, SOCK_DGRAM, 0);
	if(clients_sd < 0)
		error_exit(ERR_MSG_SOCKET, errno_string());

	memset(&me, 0, sizeof(me));
	me.sin_family = AF_INET;
	me.sin_addr.s_addr = htonl(INADDR_ANY);
	me.sin_port = htons(port);

	if(trace_level > 0)
		trace("Waiting for incoming SNMP requests on UDP port %d\n\n", port);

	if (bind(clients_sd, (struct sockaddr *)&me, sizeof(me)) != 0)
		error_exit(ERR_MSG_BIND, port, errno_string());

	agents_sd = socket(AF_INET, SOCK_DGRAM, 0);
	if (agents_sd < 0)
		error_exit(ERR_MSG_SOCKET, errno_string());

	me.sin_family = AF_INET;
	me.sin_addr.s_addr = htonl(INADDR_ANY);
	me.sin_port = htons(0);

	if (bind(agents_sd, (struct sockaddr *)&me, sizeof(me)) != 0)
		error_exit(ERR_MSG_BIND, 0, errno_string());

	trap_sd = socket(AF_INET, SOCK_DGRAM, 0);
	if (trap_sd < 0)
		error_exit(ERR_MSG_SOCKET, errno_string());

	me.sin_family = AF_INET;
	me.sin_addr.s_addr = htonl(INADDR_ANY);
	me.sin_port = htons(0);

	if(bind(trap_sd, (struct sockaddr *)&me, sizeof(me)) != 0)
		error_exit(ERR_MSG_BIND, 0, errno_string());


	len = (socklen_t)sizeof(me);
	if (getsockname(trap_sd, (struct sockaddr *)&me, &len) == -1)
		error_exit(ERR_MSG_BIND, 0, errno_string());

	relay_agent_trap_port = ntohs(me.sin_port);
	write_pid_file(pid_file);
}
コード例 #17
0
std::pair<int,int> persistent_tests()
{
  int num_tests_run = 0;
  int num_tests_failed = 0;
    
  // does it appear that this test code has run in the past?
  struct stat st;
  if (stat("/persistent/file_system_example/root", &st) == 0) {
    if (S_ISDIR(st.st_mode)) {
      fs_postHeading("Persistent File Tests: Data previously stored, running validate and delete tests");
                
      // is the access mode set to 0777?
      ++num_tests_run;
      if ((st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != (S_IRWXU | S_IRWXG | S_IRWXO)) {
        ++num_tests_failed;
        fs_postError("stat(\"/persistent/file_system_example/root\", &st) incorrectly reported access as " << to_octal_string(st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) << " instead of 0777");
      } else
        fs_postLine("stat(\"/persistent/file_system_example/root\", &st) correctly reported access as 0777");
                
      // there should be exactly 4 files in persistent/file_system_example/root,
      // one named empty_file, one named small_file, one named write_only_file, and one named big_file (plus '.' and '..')
      ++num_tests_run;
      DIR* dir = opendir("/persistent/file_system_example/root");
      if (dir == 0) {
        ++num_tests_failed;
        fs_postError("opendir(\"/persistent/file_system_example/root\") failed with errno: " << errno_string());
      } else {
        fs_postLine("opendir(\"/persistent/file_system_example/root\")");
        struct dirent *ent;
        while ((ent = readdir(dir)) != 0) {
          ++num_tests_run;
          fs_postLine("readdir returned \"" << ent->d_name << "\"");
          if (strcmp(ent->d_name,".") && strcmp(ent->d_name,"..")) {
          
            if (strcmp(ent->d_name,"small_file") == 0) {
              ++num_tests_run;
              struct stat st;
              if (stat("/persistent/file_system_example/root/small_file",&st) != 0) {
                ++num_tests_failed;
                fs_postError("stat(\"/persistent/file_system_example/root/small_file\",&st) failed with errno: " << errno_string());
              } else {
                fs_postLine("stat(\"/persistent/file_system_example/root/small_file\",&st)");
                ++num_tests_run;
                if (S_ISREG(st.st_mode)) {
                  fs_postLine("S_ISREG reported \"/persistent/file_system_example/root/small_file\" as a file (not directory)");
                  ++num_tests_run;
                  if (st.st_size == 20) {
                    fs_postLine("stat correctly reported the file size for \"/persistent/file_system_example/root/small_file\" as 20 bytes");
        
                    ++num_tests_run;
                    char rd_buf[32];
                    char b[32];
                    memcpy(&b[0], "hello world  goodbye", 20);
                    b[11] = b[12] = 0;
                    auto fd = open("/persistent/file_system_example/root/small_file", O_RDONLY);
                    read(fd, &rd_buf, sizeof(rd_buf));
                    if (memcmp(&b[0], &rd_buf[0], 20) != 0) {
                      ++num_tests_failed;
                      rd_buf[20] = 0;
                      for (int i = 0; i < 20; i++)
                        if (rd_buf[i] == 0)
                          rd_buf[i] = 'Z';
                      fs_postError("file should have contained \"hello worldZZgoodbye\", but it did not.  It contained: \"" << &rd_buf[0] << "\"");
                    } else
                      fs_postLine("file correctly contained \"hello worldZZgoodbye\" (with the Z's as NULL bytes)");
                  } else {
                    ++num_tests_failed;
                    fs_postError("stat incorrectly reported the file size for \"/persistent/file_system_example/root/small_file\" as " << st.st_size << " bytes instead of 20");
                  }
                } else {
                  ++num_tests_failed;
                  fs_postError("S_ISREG incorrectly reported \"/persistent/file_system_example/root/small_file\" as something other than a file");
                }
              }
            }
            
            else if (strcmp(ent->d_name,"write_only_file") == 0) {
              ++num_tests_run;
              struct stat st;
              if (stat("/persistent/file_system_example/root/write_only_file",&st) != 0) {
                ++num_tests_failed;
                fs_postError("stat(\"/persistent/file_system_example/root/write_only_file\",&st) failed with errno: " << errno_string());
              } else {
                fs_postLine("stat(\"/persistent/file_system_example/root/write_only_file\",&st)");
                ++num_tests_run;
                if ((st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) != (S_IWUSR | S_IWGRP | S_IWOTH)) {
                  ++num_tests_failed;
                  fs_postError("stat(\"/persistent/file_system_example/root/write_only_file\",&st) incorrectly reported access as " << to_octal_string(st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) << " instead of " << to_octal_string(S_IWUSR | S_IWGRP | S_IWOTH));
                } else
                  fs_postLine("stat(\"/persistent/file_system_example/root/write_only_file\",&st) correctly reported access as " << to_octal_string(S_IWUSR | S_IWGRP | S_IWOTH));
                                    
                ++num_tests_run;
                if (st.st_mtime != 17) {
                  ++num_tests_failed;
                  fs_postError("write_only_file mod time incorrectly reported as " << st.st_mtime << ", instead of 17");
                } else fs_postLine("write_only_file mod time correctly reported as 17");
              }
            }
            
            else if (strcmp(ent->d_name,"big_file") == 0) {
              ++num_tests_run;
              struct stat st;
              if (stat("/persistent/file_system_example/root/big_file",&st) != 0) {
                ++num_tests_failed;
                fs_postError("stat(\"/persistent/file_system_example/root/big_file\",&st) failed with errno: " << errno_string());
              } else {
                fs_postLine("stat(\"/persistent/file_system_example/root/big_file\",&st)");
                ++num_tests_run;
                if (S_ISREG(st.st_mode)) {
                  fs_postLine("S_ISREG reported \"/persistent/file_system_example/root/big_file\" as a file (not directory)");
                  ++num_tests_run;
                  if (st.st_size == kReallyBigFileSize*strlen(kReallyBigFileString))
                    fs_postLine("stat correctly reported the file size of \"/persistent/file_system_example/root/big_file\" as " << kReallyBigFileSize*strlen(kReallyBigFileString) << " bytes");
                  else {
                    ++num_tests_failed;
                    fs_postError("stat incorrectly reported the file size of \"/persistent/file_system_example/root/big_file\" as " << st.st_size << " bytes");
                  }
                } else {
                  ++num_tests_failed;
                  fs_postError("S_ISREG incorrectly reported \"/persistent/file_system_example/root/big_file\" as something other than a file");
                }
              }
            }
            
          }
        }
        closedir(dir);
      }
                
      ++num_tests_run;
      if (truncate("/persistent/file_system_example/root/big_file",10) != 0) {
        ++num_tests_failed;
        fs_postError("truncate(\"/persistent/file_system_example/root/big_file\",10) failed with errno: " << errno_string());
      } else {
        fs_postLine("truncate(\"/persistent/file_system_example/root/big_file\",10)");
                    
        ++num_tests_run;
        struct stat st;
        if (stat("/persistent/file_system_example/root/big_file",&st) != 0) {
          ++num_tests_failed;
          fs_postError("stat(\"/persistent/file_system_example/root/big_file\",&st) failed with errno: " << errno_string());
        } else {
          fs_postLine("stat(\"/persistent/file_system_example/root/big_file\",&st)");
                    
          ++num_tests_run;
          if (st.st_size == 10)
            fs_postLine("stat correctly reported the new, truncated file size of \"/persistent/file_system_example/root/big_file\" as 10 bytes");
          else {
            ++num_tests_failed;
            fs_postError("stat incorrectly reported the file new, truncated size of \"/persistent/file_system_example/root/big_file\" as " << st.st_size << " bytes");
          }
        }
      }
                
      ++num_tests_run;
      struct stat st;
      if (stat("persistent/file_system_example/root/empty_file", &st) != 0) {
        ++num_tests_failed;
        fs_postError("stat(\"persistent/file_system_example/root/empty_file\", &st) failed with errno: " << errno_string());
      } else {
        fs_postLine("stat(\"persistent/file_system_example/root/empty_file\", &st)");
                    
        ++num_tests_run;
        if (st.st_size == 0)
          fs_postLine("stat correctly reported the size of \"/persistent/file_system_example/root/empty_file\" as 0 bytes");
        else {
          ++num_tests_failed;
          fs_postError("stat incorrectly reported the size of \"/persistent/file_system_example/root/empty_file\" as " << st.st_size << " bytes");
        }
      }
                
      clear_all("/persistent/file_system_example/root");
    } else {
      fs_postError("/persistent/file_system_example/root exists but does not appear to be a directory, attempting to delete");
      unlink("/persistent/file_system_example/root");
    }
  }
  
  else {
    fs_postHeading("Persistent File Tests: No data previously stored, running create and store tests");
            
    // can we make our root directory?
    // we handle failure a little differently on this one.  If this fails we don't
    // attempt to run further tests
    ++num_tests_run;
    if (mkdir("/persistent/file_system_example/root",0777) != 0) {
      ++num_tests_failed;
      fs_postError("mkdir(\"/persistent/file_system_example/root\",0777) failed with errno: " << errno_string());
      return std::make_pair(num_tests_run, num_tests_failed);
    }
    fs_postLine("mkdir(\"/persistent/file_system_example/root\",0777)");
            
            
    // does a file which does not exist fail to open as expected?
    ++num_tests_run;
    auto fd = open("/persistent/file_system_example/root/does_not_exist", O_RDONLY);
    if (fd != -1 || errno != ENOENT) {
      ++num_tests_failed;
      fs_postError("open(\"/persistent/file_system_example/root/does_not_exist\",O_RDONLY) should have failed with errno = ENOENT, but did not.  It returned " << fd << ", and errno: " << errno_string());
    } else
      fs_postLine("open(\"/persistent/file_system_example/root/does_not_exist\", O_RDONLY) correctly failed with errno = ENOENT");


    // can we make an empty file and will it persist?
    ++num_tests_run;
    fd = open("/persistent/file_system_example/root/empty_file",O_RDWR | O_CREAT, 0666);
    if (fd == -1) {
      ++num_tests_failed;
      fs_postError("open(\"/persistent/file_system_example/root/empty_file\",O_RDWR | O_CREAT, 0666) should have succeeded, but did not.  It returned -1, and errno: " << errno_string());
    } else {
      close(fd);
      fs_postLine("open(\"/persistent/file_system_example/root/empty_file\", O_RDWR | O_CREAT, 0666)");
    }

            
    // can we create a new read-only file?
    ++num_tests_run;
    fd = open("/persistent/file_system_example/root/small_file",O_RDONLY | O_CREAT, 0666);
    if (fd == -1) {
      ++num_tests_failed;
      fs_postError("open(\"/persistent/file_system_example/root/small_file\",O_RDONLY | O_CREAT, 0666) should have succeeded, but did not.  It returned -1, and errno: " << errno_string());
    } else {
      close(fd);
      fs_postLine("open(\"/persistent/file_system_example/root/small_file\", O_RDONLY | O_CREAT, 0666)");
    }


    // can we create a file with write-only access, and does this access persist?
    ++num_tests_run;
    fd = open("/persistent/file_system_example/root/write_only_file",O_WRONLY | O_CREAT, S_IWUSR | S_IWGRP | S_IWOTH);
    if (fd == -1) {
      ++num_tests_failed;
      fs_postError("open(\"/persistent/file_system_example/root/write_only_file\",O_WRONLY | O_CREAT, S_IWUSR | S_IWGRP | S_IWOTH) should have succeeded, but did not.  It returned -1, and errno: " << errno_string());
    } else {
      close(fd);
      fs_postLine("open(\"/persistent/file_system_example/root/write_only_file\", O_WRONLY | O_CREAT, S_IWUSR | S_IWGRP | S_IWOTH)");
                
      // imediately after creation is the access mode S_IWUSR | S_IWGRP | S_IWOTH?
      ++num_tests_run;
      struct stat st;
      stat("/persistent/file_system_example/root/write_only_file",&st);
      int mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
      if (mode != (S_IWUSR | S_IWGRP | S_IWOTH)) {
        ++num_tests_failed;
        fs_postError("stat(\"/persistent/file_system_example/root/write_only_file\",&st) incorrectly reported access as " << to_octal_string(mode) << " instead of " << to_octal_string(S_IWUSR | S_IWGRP | S_IWOTH));
      } else
        fs_postLine("stat(\"/persistent/file_system_example/root/write_only_file\",&st) correctly reported access as " << to_octal_string(S_IWUSR | S_IWGRP | S_IWOTH));
                
      ++num_tests_run;
      #if !defined(__native_client__) || PPAPI_RELEASE >= 39
        // can we set the access time of this file and does that persist?
        struct timeval tv[2] = {{0, 0}, {17, 0}};
        if (utimes("/persistent/file_system_example/root/write_only_file", tv) != 0) {
          ++num_tests_failed;
          fs_postError("utimes(\"/persistent/file_system_example/root/write_only_file\", tv) failed with errno: " << errno_string());
        } else {
          fs_postLine("utimes(\"/persistent/file_system_example/root/write_only_file\", tv)");
                    
          // can we read them back right now?
          ++num_tests_run;
          struct stat st;
          stat("/persistent/file_system_example/root/write_only_file", &st);
                    
          // although the code above does set the atime field, following the
          // "Criticism of atime" issues, we don't verify that it was set, or
          // care whether it was set.
          if (st.st_mtime != 17) {
            ++num_tests_failed;
            fs_postError("immediately after setting with utime, file mod time should have been 17.  Instead is " << st.st_mtime);
          } else
            fs_postLine("immediately after setting with utime, file mod time was read as 17");
        }
      #elif defined(__native_client__)
        ++num_tests_failed;
        fs_postError("Pepper_" << PPAPI_RELEASE << " is too old to run file modification time tests - it doesn't implement utime, please consider updating to at least Pepper_39");
      #endif
    }


    // can we open, read-only, an existing file (the one we just created above)
    ++num_tests_run;
    fd = open("/persistent/file_system_example/root/small_file",O_RDONLY);
    if (fd == 1) {
      ++num_tests_failed;
      fs_postError("open(\"/persistent/file_system_example/root/small_file\",O_RDONLY) should have succeeded, but did not.  It returned -1, and errno: " << errno_string());
    } else {
      fs_postLine("open(\"/persistent/file_system_example/root/small_file\", O_RDONLY)");
                
      // are we correctly blocked from writing to this file - we opened it O_RDONLY
      ++num_tests_run;
      const char* buf = "hello";
      auto written = write(fd, buf, strlen(buf));
      if (written != -1 || errno != EBADF) {
        ++num_tests_failed;
        fs_postError("write(read-only-fd, \"hello\", 5) should have failed with EBADF, but did not.  It returned " << written << ", and errno: " << errno_string());
      } else
        fs_postLine("write(read-only-fd, \"hello\", 5) correctly failed with errno = EBADF");
      close(fd);
    }
            
    const char* hello = "hello";
    const char* hello_world = "hello world";
    
    
    // can we open, write-only, an existing file
    ++num_tests_run;
    fd = open("/persistent/file_system_example/root/small_file",O_WRONLY);
    if (fd == -1) {
      ++num_tests_failed;
      fs_postError("open(\"/persistent/file_system_example/root/small_file\",O_WRONLY) should have succeeded, but did not.  It returned -1, and errno: " << errno_string());
    } else {
      fs_postLine("open(\"/persistent/file_system_example/root/small_file\", O_WRONLY)");
                
      // are we correctly blocked from reading from this file?
      ++num_tests_run;
      char b;
      auto bytes_read = read(fd, &b, 1);
      if (bytes_read != -1 || errno != EBADF) {
        ++num_tests_failed;
        fs_postError("read(write-only-fd, &b, 1) should have failed with errno EBADF, but did not.  It returned " << bytes_read << ", and errno: " << errno_string());
      } else
        fs_postLine("read(write-only-fd, &b, 1) correctly failed with errno = EBADF");
                
      // can we write to this file?
      ++num_tests_run;
      auto written = write(fd, hello, strlen(hello));
      if (written != strlen(hello)) {
        ++num_tests_failed;
        fs_postError("write(write-only-fd, \"hello\", 5) should have succeeded, but did not.  It returned " << written << ", and errno: " << errno_string());
      } else
        fs_postLine("write(write-only-fd, \"hello\", 5)");
      close(fd);
    }


    // can we open, read-write, an existing file?
    ++num_tests_run;
    fd = open("/persistent/file_system_example/root/small_file",O_RDWR);
    if (fd == -1) {
      ++num_tests_failed;
      fs_postError("open(\"/persistent/file_system_example/root/small_file\",O_RDWR) should have succeeded, but did not.  It returned -1, and errno: " << errno_string());
    } else {
      fs_postLine("open(\"/persistent/file_system_example/root/small_file\", O_RDWR)");
                
      // can we read from this file, and does it contain "hello"?
      ++num_tests_run;
      char rd_buf[32] = {0};
      auto bytes_read = read(fd, &rd_buf[0], sizeof(rd_buf));
      if (bytes_read != strlen(hello)) {
        ++num_tests_failed;
        fs_postError("read(read-write-fd, &rd_buf, " << sizeof(rd_buf) << ") should have returned 5, but did not.  It returned " << bytes_read << (bytes_read == -1 ? (std::string(", and errno: ") + errno_string()) : std::string("")));
      } else if (memcmp(rd_buf, hello, strlen(hello)) != 0) {
        ++num_tests_failed;
        fs_postError("read(read-write-fd, &rd_buf, " << sizeof(rd_buf) << ") should have read \"hello\", but did not.  It read: \"" << &rd_buf[0] << "\"");
      } else
        fs_postLine("read(read-write-fd, &rd_buf, " << sizeof(rd_buf) << ")");

      // can we also write (append) to this file?
      ++num_tests_run;
      const char* buf = " world";
      auto written = write(fd, buf, strlen(buf));
      if (written != strlen(buf)) {
        ++num_tests_failed;
        fs_postError("write(read-write-fd, \" world\", 6) should have succeeded, but did not.  It returned " << written << ", and errno: " << errno_string());
      } else
        fs_postLine("write(read-write-fd, \" world\", 6)");
                
      // can we lseek to the middle and read the right stuff?
      ++num_tests_run;
      auto reslt = lseek(fd, 3, SEEK_SET);
      if (reslt != 3) {
        ++num_tests_failed;
        fs_postError("lseek(fd, 3, SEEK_SET) should have returned 3, but did not.  It returned: " << reslt);
      } else {
        fs_postLine("lseek(fd, 3, SEEK_SET)");

        ++num_tests_run;
        bytes_read = read(fd, &rd_buf[0], 3);
        if ((bytes_read != 3) || (memcmp(&rd_buf[0], "lo ", 3) != 0)) {
          ++num_tests_failed;
          rd_buf[3] = 0;
          fs_postError("read(fd, &rd_buf[0], 3) should have read \"lo \", but did not.  It returned: " << bytes_read << " and read: \"" << &rd_buf[0] << "\"");
        } else
          fs_postLine("read(fd, &rd_buf[0], 3) correctly read \"lo \"");
      }
                
      // can we seek past the end of the file and write some new data and does that cause
      // the gap between the old and new data to be zero?
      ++num_tests_run;
      reslt = lseek(fd, 2, SEEK_END);
      if (reslt != 13) {
        ++num_tests_failed;
        fs_postError("lseek(fd, 2, SEEK_END) should have returned 13, but did not.  It returned: " << reslt);
      } else {
        fs_postLine("lseek(fd, 2, SEEK_END)");
                    
        ++num_tests_run;
        reslt = write(fd, "goodbye", 7);
        if (reslt != 7) {
          ++num_tests_failed;
          fs_postError("write(fd, \"goodbye\", 7), should have returned 7 but did not.  It returned: " << reslt);
        } else {
          fs_postLine("write(fd, \"goodbye\", 7)");
                        
          ++num_tests_run;
          lseek(fd, 0, SEEK_SET);
          read(fd, &rd_buf[0], sizeof(rd_buf));
          char b[32];
          memcpy(b, "hello world  goodbye", 20);
          b[11] = b[12] = 0;
          if (memcmp(&rd_buf[0], &b[0], 20) != 0) {
            ++num_tests_failed;
            rd_buf[20] = 0;
            fs_postError("file should have contained \"hello worldZZgoodbye\" (with the Z's being NULL bytes), but did not, it contained: \"" << &rd_buf[0] << "\"");
          } else
            fs_postLine("file correctly contained \"hello worldZZgoodbye\" (with the Z's being NULL bytes)");
        }
                    
      }
                
                
      close(fd);
    }


    // can we create and write to a really big file?
    ++num_tests_run;
    fd = open("/persistent/file_system_example/root/big_file",O_RDWR | O_CREAT, 0666);
    if (fd == -1) {
      ++num_tests_failed;
      fs_postError("open(\"/persistent/file_system_example/root/big_file\",O_RDWR | O_CREAT, 0666) should have succeeded, but did not.  It returned -1, and errno: " << errno_string());
    } else {
      auto len = strlen(kReallyBigFileString);
      for (int i = 0; i < kReallyBigFileSize; i++) {
        auto bytes_written = write(fd, kReallyBigFileString, len);
        if (bytes_written != len) {
          ++num_tests_failed;
          fs_postError("write to really big file failed after writing " << i*len << " bytes");
          break;
        }
      }
      fs_postLine("wrote " << kReallyBigFileSize*len << " bytes to \"/persistent/file_system_example/root/big_file\"");
      close(fd);
    }
            
  }
    
  return std::make_pair(num_tests_run, num_tests_failed);
}