int stream_open(stream *stream, const char *url) { fprintf(stderr, "stream_open: %s\n", url); stream->url = sdsnew(url); response *response = resolve_stream(url); if (response == NULL) { return -1; } if (stream->fd > 3 && fd_is_valid(stream->fd)) { close(stream->fd); mpg123_close(stream->mpg123); } stream->fd = response->fd; free_response(response); if (mpg123_open_fd(stream->mpg123, stream->fd) != MPG123_OK) { return -1; } return 0; }
void ClientSocketMultiplexer::updateSockets() { map<int, AbstractMultiplexedClientSocket *>::iterator mi; set<AbstractMultiplexedClientSocket *>::iterator i; AbstractMultiplexedClientSocket *s; int fd; mutex->lock(); // remove bad fd's and closed sockets for (mi=sockets.begin();mi!=sockets.end();++mi) { fd = (*mi).first; s = (*mi).second; if (!fd_is_valid(fd) || s->getSocketStatus() != SOCKET_OPENED) removedSockets.insert(s); } // removed sockets for (i=removedSockets.begin();i!=removedSockets.end();++i) { fd = (*i)->getSocketFd(); if (sockets.find(fd)!=sockets.end()) { sockets.erase(fd); delete (*i); } } removedSockets.clear(); // inserted sockets for (i=insertedSockets.begin();i!=insertedSockets.end();++i) { fd = (*i)->getSocketFd(); if (fd_is_valid(fd) && (*i)->getSocketStatus() == SOCKET_OPENED) { sockets[fd]=(*i); (*i)->setNonBlocking(true); (*i)->setMultiplexer(this); } } insertedSockets.clear(); mutex->unlock(); }
static int msghdr_add_fd(struct cmsghdr *cmsg, int fd) { PJDLOG_ASSERT(fd >= 0); if (!fd_is_valid(fd)) { errno = EBADF; return (-1); } cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); bcopy(&fd, CMSG_DATA(cmsg), sizeof(fd)); return (0); }
int main() { printf("midipix-start started\n"); fprintf(stderr, "midipix-start stderr works\n"); { printf(" pid: %d\n", getpid()); } { char cwd[512]; char * result = getcwd(cwd, sizeof(cwd)); if (result == NULL) { perror("getcwd"); } else { printf(" getcwd: %s\n", cwd); } } for (int fd = 0; fd < 10; fd++) { if (fd_is_valid(fd)) { printf(" isatty(%d) = %d\n", fd, isatty(fd)); } } { int result = chroot("//c/midipix"); if (result != 0) { perror("chroot"); } } execl("bash", "bash", "--login", "-i", NULL); perror("execl"); return 1; }
int main(int argc, char **argv) { int i; int config_loaded = 0; int dont_fork = 0; size_t default_stacksize; // set the name for logging program_name = "netdata"; // parse depercated options // TODO: Remove this block with the next major release. { i = 1; while(i < argc) { if(strcmp(argv[i], "-pidfile") == 0 && (i+1) < argc) { strncpyz(pidfile, argv[i+1], FILENAME_MAX); fprintf(stderr, "%s: deprecated option -- %s -- please use -P instead.\n", argv[0], argv[i]); remove_option(i, &argc, argv); } else if(strcmp(argv[i], "-nodaemon") == 0 || strcmp(argv[i], "-nd") == 0) { dont_fork = 1; fprintf(stderr, "%s: deprecated option -- %s -- please use -D instead.\n ", argv[0], argv[i]); remove_option(i, &argc, argv); } else if(strcmp(argv[i], "-ch") == 0 && (i+1) < argc) { config_set(CONFIG_SECTION_GLOBAL, "host access prefix", argv[i+1]); fprintf(stderr, "%s: deprecated option -- %s -- please use -s instead.\n", argv[0], argv[i]); remove_option(i, &argc, argv); } else if(strcmp(argv[i], "-l") == 0 && (i+1) < argc) { config_set(CONFIG_SECTION_GLOBAL, "history", argv[i+1]); fprintf(stderr, "%s: deprecated option -- %s -- This option will be removed with V2.*.\n", argv[0], argv[i]); remove_option(i, &argc, argv); } else i++; } } // parse options { int num_opts = sizeof(option_definitions) / sizeof(struct option_def); char optstring[(num_opts * 2) + 1]; int string_i = 0; for( i = 0; i < num_opts; i++ ) { optstring[string_i] = option_definitions[i].val; string_i++; if(option_definitions[i].arg_name) { optstring[string_i] = ':'; string_i++; } } // terminate optstring optstring[string_i] ='\0'; optstring[(num_opts *2)] ='\0'; int opt; while( (opt = getopt(argc, argv, optstring)) != -1 ) { switch(opt) { case 'c': if(config_load(optarg, 1) != 1) { error("Cannot load configuration file %s.", optarg); return 1; } else { debug(D_OPTIONS, "Configuration loaded from %s.", optarg); config_loaded = 1; } break; case 'D': dont_fork = 1; break; case 'h': return help(0); case 'i': config_set(CONFIG_SECTION_WEB, "bind to", optarg); break; case 'P': strncpy(pidfile, optarg, FILENAME_MAX); pidfile[FILENAME_MAX] = '\0'; break; case 'p': config_set(CONFIG_SECTION_GLOBAL, "default port", optarg); break; case 's': config_set(CONFIG_SECTION_GLOBAL, "host access prefix", optarg); break; case 't': config_set(CONFIG_SECTION_GLOBAL, "update every", optarg); break; case 'u': config_set(CONFIG_SECTION_GLOBAL, "run as user", optarg); break; case 'v': case 'V': printf("%s %s\n", program_name, program_version); return 0; case 'W': { char* stacksize_string = "stacksize="; char* debug_flags_string = "debug_flags="; if(strcmp(optarg, "unittest") == 0) { if(unit_test_buffer()) return 1; if(unit_test_str2ld()) return 1; //default_rrd_update_every = 1; //default_rrd_memory_mode = RRD_MEMORY_MODE_RAM; //if(!config_loaded) config_load(NULL, 0); get_netdata_configured_variables(); default_rrd_update_every = 1; default_rrd_memory_mode = RRD_MEMORY_MODE_RAM; default_health_enabled = 0; rrd_init("unittest"); default_rrdpush_enabled = 0; if(run_all_mockup_tests()) return 1; if(unit_test_storage()) return 1; fprintf(stderr, "\n\nALL TESTS PASSED\n\n"); return 0; } else if(strcmp(optarg, "simple-pattern") == 0) { if(optind + 2 > argc) { fprintf(stderr, "%s", "\nUSAGE: -W simple-pattern 'pattern' 'string'\n\n" " Checks if 'pattern' matches the given 'string'.\n" " - 'pattern' can be one or more space separated words.\n" " - each 'word' can contain one or more asterisks.\n" " - words starting with '!' give negative matches.\n" " - words are processed left to right\n" "\n" "Examples:\n" "\n" " > match all veth interfaces, except veth0:\n" "\n" " -W simple-pattern '!veth0 veth*' 'veth12'\n" "\n" "\n" " > match all *.ext files directly in /path/:\n" " (this will not match *.ext files in a subdir of /path/)\n" "\n" " -W simple-pattern '!/path/*/*.ext /path/*.ext' '/path/test.ext'\n" "\n" ); return 1; } const char *heystack = argv[optind]; const char *needle = argv[optind + 1]; size_t len = strlen(needle) + 1; char wildcarded[len]; SIMPLE_PATTERN *p = simple_pattern_create(heystack, NULL, SIMPLE_PATTERN_EXACT); int ret = simple_pattern_matches_extract(p, needle, wildcarded, len); simple_pattern_free(p); if(ret) { fprintf(stdout, "RESULT: MATCHED - pattern '%s' matches '%s', wildcarded '%s'\n", heystack, needle, wildcarded); return 0; } else { fprintf(stdout, "RESULT: NOT MATCHED - pattern '%s' does not match '%s', wildcarded '%s'\n", heystack, needle, wildcarded); return 1; } } else if(strncmp(optarg, stacksize_string, strlen(stacksize_string)) == 0) { optarg += strlen(stacksize_string); config_set(CONFIG_SECTION_GLOBAL, "pthread stack size", optarg); } else if(strncmp(optarg, debug_flags_string, strlen(debug_flags_string)) == 0) { optarg += strlen(debug_flags_string); config_set(CONFIG_SECTION_GLOBAL, "debug flags", optarg); debug_flags = strtoull(optarg, NULL, 0); } else if(strcmp(optarg, "set") == 0) { if(optind + 3 > argc) { fprintf(stderr, "%s", "\nUSAGE: -W set 'section' 'key' 'value'\n\n" " Overwrites settings of netdata.conf.\n" "\n" " These options interact with: -c netdata.conf\n" " If -c netdata.conf is given on the command line,\n" " before -W set... the user may overwrite command\n" " line parameters at netdata.conf\n" " If -c netdata.conf is given after (or missing)\n" " -W set... the user cannot overwrite the command line\n" " parameters." "\n" ); return 1; } const char *section = argv[optind]; const char *key = argv[optind + 1]; const char *value = argv[optind + 2]; optind += 3; // set this one as the default // only if it is not already set in the config file // so the caller can use -c netdata.conf before or // after this parameter to prevent or allow overwriting // variables at netdata.conf config_set_default(section, key, value); // fprintf(stderr, "SET section '%s', key '%s', value '%s'\n", section, key, value); } else if(strcmp(optarg, "get") == 0) { if(optind + 3 > argc) { fprintf(stderr, "%s", "\nUSAGE: -W get 'section' 'key' 'value'\n\n" " Prints settings of netdata.conf.\n" "\n" " These options interact with: -c netdata.conf\n" " -c netdata.conf has to be given before -W get.\n" "\n" ); return 1; } if(!config_loaded) { fprintf(stderr, "warning: no configuration file has been loaded. Use -c CONFIG_FILE, before -W get. Using default config.\n"); config_load(NULL, 0); } backwards_compatible_config(); get_netdata_configured_variables(); const char *section = argv[optind]; const char *key = argv[optind + 1]; const char *def = argv[optind + 2]; const char *value = config_get(section, key, def); printf("%s\n", value); return 0; } else { fprintf(stderr, "Unknown -W parameter '%s'\n", optarg); return help(1); } } break; default: /* ? */ fprintf(stderr, "Unknown parameter '%c'\n", opt); return help(1); } } } #ifdef _SC_OPEN_MAX // close all open file descriptors, except the standard ones // the caller may have left open files (lxc-attach has this issue) { int fd; for(fd = (int) (sysconf(_SC_OPEN_MAX) - 1); fd > 2; fd--) if(fd_is_valid(fd)) close(fd); } #endif if(!config_loaded) config_load(NULL, 0); // ------------------------------------------------------------------------ // initialize netdata { char *pmax = config_get(CONFIG_SECTION_GLOBAL, "glibc malloc arena max for plugins", "1"); if(pmax && *pmax) setenv("MALLOC_ARENA_MAX", pmax, 1); #if defined(HAVE_C_MALLOPT) i = (int)config_get_number(CONFIG_SECTION_GLOBAL, "glibc malloc arena max for netdata", 1); if(i > 0) mallopt(M_ARENA_MAX, 1); #endif // prepare configuration environment variables for the plugins get_netdata_configured_variables(); set_global_environment(); // work while we are cd into config_dir // to allow the plugins refer to their config // files using relative filenames if(chdir(netdata_configured_config_dir) == -1) fatal("Cannot cd to '%s'", netdata_configured_config_dir); } char *user = NULL; { // -------------------------------------------------------------------- // get the debugging flags from the configuration file char *flags = config_get(CONFIG_SECTION_GLOBAL, "debug flags", "0x0000000000000000"); setenv("NETDATA_DEBUG_FLAGS", flags, 1); debug_flags = strtoull(flags, NULL, 0); debug(D_OPTIONS, "Debug flags set to '0x%" PRIX64 "'.", debug_flags); if(debug_flags != 0) { struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; if(setrlimit(RLIMIT_CORE, &rl) != 0) error("Cannot request unlimited core dumps for debugging... Proceeding anyway..."); #ifdef HAVE_SYS_PRCTL_H prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); #endif } // -------------------------------------------------------------------- // get log filenames and settings log_init(); error_log_limit_unlimited(); // -------------------------------------------------------------------- // load stream.conf { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s/stream.conf", netdata_configured_config_dir); appconfig_load(&stream_config, filename, 0); } // -------------------------------------------------------------------- // setup process signals // block signals while initializing threads. // this causes the threads to block signals. signals_block(); // setup the signals we want to use signals_init(); // setup threads configs default_stacksize = netdata_threads_init(); // -------------------------------------------------------------------- // check which threads are enabled and initialize them for (i = 0; static_threads[i].name != NULL ; i++) { struct netdata_static_thread *st = &static_threads[i]; if(st->config_name) st->enabled = config_get_boolean(st->config_section, st->config_name, st->enabled); if(st->enabled && st->init_routine) st->init_routine(); } // -------------------------------------------------------------------- // get the user we should run // IMPORTANT: this is required before web_files_uid() if(getuid() == 0) { user = config_get(CONFIG_SECTION_GLOBAL, "run as user", NETDATA_USER); } else { struct passwd *passwd = getpwuid(getuid()); user = config_get(CONFIG_SECTION_GLOBAL, "run as user", (passwd && passwd->pw_name)?passwd->pw_name:""); } // -------------------------------------------------------------------- // create the listening sockets web_client_api_v1_init(); web_server_threading_selection(); if(web_server_mode != WEB_SERVER_MODE_NONE) api_listen_sockets_setup(); } // initialize the log files open_all_log_files(); #ifdef NETDATA_INTERNAL_CHECKS if(debug_flags != 0) { struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY }; if(setrlimit(RLIMIT_CORE, &rl) != 0) error("Cannot request unlimited core dumps for debugging... Proceeding anyway..."); #ifdef HAVE_SYS_PRCTL_H prctl(PR_SET_DUMPABLE, 1, 0, 0, 0); #endif } #endif /* NETDATA_INTERNAL_CHECKS */ // get the max file limit if(getrlimit(RLIMIT_NOFILE, &rlimit_nofile) != 0) error("getrlimit(RLIMIT_NOFILE) failed"); else info("resources control: allowed file descriptors: soft = %zu, max = %zu", rlimit_nofile.rlim_cur, rlimit_nofile.rlim_max); // fork, switch user, create pid file, set process priority if(become_daemon(dont_fork, user) == -1) fatal("Cannot daemonize myself."); info("netdata started on pid %d.", getpid()); // IMPORTANT: these have to run once, while single threaded // but after we have switched user web_files_uid(); web_files_gid(); netdata_threads_init_after_fork((size_t)config_get_number(CONFIG_SECTION_GLOBAL, "pthread stack size", (long)default_stacksize)); // ------------------------------------------------------------------------ // initialize rrd, registry, health, rrdpush, etc. rrd_init(netdata_configured_hostname); // ------------------------------------------------------------------------ // enable log flood protection error_log_limit_reset(); // ------------------------------------------------------------------------ // spawn the threads web_server_config_options(); for (i = 0; static_threads[i].name != NULL ; i++) { struct netdata_static_thread *st = &static_threads[i]; if(st->enabled) { st->thread = mallocz(sizeof(netdata_thread_t)); debug(D_SYSTEM, "Starting thread %s.", st->name); netdata_thread_create(st->thread, st->name, NETDATA_THREAD_OPTION_DEFAULT, st->start_routine, st); } else debug(D_SYSTEM, "Not starting thread %s.", st->name); } info("netdata initialization completed. Enjoy real-time performance monitoring!"); // ------------------------------------------------------------------------ // unblock signals signals_unblock(); // ------------------------------------------------------------------------ // Handle signals signals_handle(); // should never reach this point // but we need it for rpmlint #2752 return 1; }
void disconnectPlayer(Player *player) { if (fd_is_valid(player->descriptor)) if(TEMP_FAILURE_RETRY(close(player->descriptor))<0)ERR("close"); }
int become_daemon(int dont_fork, int close_all_files, const char *user, const char *input, const char *output, const char *error, const char *access, int *access_fd, FILE **access_fp) { fflush(NULL); // open the files before forking int input_fd = -1, output_fd = -1, error_fd = -1, dev_null; if(input && *input) { if((input_fd = open(input, O_RDONLY, 0666)) == -1) { error("Cannot open input file '%s'.", input); return -1; } } if(output && *output) { if((output_fd = open(output, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) { error("Cannot open output log file '%s'", output); if(input_fd != -1) close(input_fd); return -1; } } if(error && *error) { if((error_fd = open(error, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) { error("Cannot open error log file '%s'.", error); if(input_fd != -1) close(input_fd); if(output_fd != -1) close(output_fd); return -1; } } if(access && *access && access_fd) { if((*access_fd = open(access, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) { error("Cannot open access log file '%s'", access); if(input_fd != -1) close(input_fd); if(output_fd != -1) close(output_fd); if(error_fd != -1) close(error_fd); return -1; } if(access_fp) { *access_fp = fdopen(*access_fd, "w"); if(!*access_fp) { error("Cannot migrate file's '%s' fd %d.", access, *access_fd); if(input_fd != -1) close(input_fd); if(output_fd != -1) close(output_fd); if(error_fd != -1) close(error_fd); close(*access_fd); *access_fd = -1; return -1; } } } if((dev_null = open("/dev/null", O_RDWR, 0666)) == -1) { perror("Cannot open /dev/null"); if(input_fd != -1) close(input_fd); if(output_fd != -1) close(output_fd); if(error_fd != -1) close(error_fd); if(access && access_fd && *access_fd != -1) { close(*access_fd); *access_fd = -1; if(access_fp) { fclose(*access_fp); *access_fp = NULL; } } return -1; } // all files opened // lets do it if(!dont_fork) { int i = fork(); if(i == -1) { perror("cannot fork"); exit(1); } if(i != 0) { exit(0); // the parent } // become session leader if (setsid() < 0) { perror("Cannot become session leader."); exit(2); } } // fork() again if(!dont_fork) { int i = fork(); if(i == -1) { perror("cannot fork"); exit(1); } if(i != 0) { exit(0); // the parent } } // Set new file permissions umask(0); // close all files if(close_all_files) { int i; for(i = (int) (sysconf(_SC_OPEN_MAX) - 1); i > 0; i--) if( ((access_fd && i != *access_fd) || !access_fd) && i != dev_null && i != input_fd && i != output_fd && i != error_fd && fd_is_valid(i) ) close(i); } else { close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } // put the opened files // to our standard file descriptors if(input_fd != -1) { if(input_fd != STDIN_FILENO) { dup2(input_fd, STDIN_FILENO); close(input_fd); } input_fd = -1; } else dup2(dev_null, STDIN_FILENO); if(output_fd != -1) { if(output_fd != STDOUT_FILENO) { dup2(output_fd, STDOUT_FILENO); close(output_fd); } output_fd = -1; } else dup2(dev_null, STDOUT_FILENO); if(error_fd != -1) { if(error_fd != STDERR_FILENO) { dup2(error_fd, STDERR_FILENO); close(error_fd); } error_fd = -1; } else dup2(dev_null, STDERR_FILENO); // close /dev/null if(dev_null != STDIN_FILENO && dev_null != STDOUT_FILENO && dev_null != STDERR_FILENO) close(dev_null); // generate our pid file if(pidfile[0]) { pidfd = open(pidfile, O_RDWR | O_CREAT, 0644); if(pidfd >= 0) { if(ftruncate(pidfd, 0) != 0) error("Cannot truncate pidfile '%s'.", pidfile); char b[100]; sprintf(b, "%d\n", getpid()); ssize_t i = write(pidfd, b, strlen(b)); if(i <= 0) error("Cannot write pidfile '%s'.", pidfile); // don't close it, we might need it at exit // close(pidfd); } else error("Failed to open pidfile '%s'.", pidfile); } if(user && *user) { if(become_user(user) != 0) { error("Cannot become user '%s'. Continuing as we are.", user); } else info("Successfully became user '%s'.", user); } else if(pidfd != -1) close(pidfd); return(0); }
static void parent(int sock) { nvlist_t *nvl; const nvlist_t *cnvl; const char *name, *cname; void *cookie, *ccookie; int type, ctype; size_t size; nvl = nvlist_recv(sock); CHECK(nvlist_error(nvl) == 0); if (nvlist_error(nvl) != 0) err(1, "nvlist_recv() failed"); cookie = NULL; name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_BOOL); CHECK(strcmp(name, "nvlist/bool/true") == 0); CHECK(nvlist_get_bool(nvl, name) == true); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_BOOL); CHECK(strcmp(name, "nvlist/bool/false") == 0); CHECK(nvlist_get_bool(nvl, name) == false); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_NUMBER); CHECK(strcmp(name, "nvlist/number/0") == 0); CHECK(nvlist_get_number(nvl, name) == 0); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_NUMBER); CHECK(strcmp(name, "nvlist/number/1") == 0); CHECK(nvlist_get_number(nvl, name) == 1); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_NUMBER); CHECK(strcmp(name, "nvlist/number/-1") == 0); CHECK((int)nvlist_get_number(nvl, name) == -1); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_NUMBER); CHECK(strcmp(name, "nvlist/number/UINT64_MAX") == 0); CHECK(nvlist_get_number(nvl, name) == UINT64_MAX); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_NUMBER); CHECK(strcmp(name, "nvlist/number/INT64_MIN") == 0); CHECK((int64_t)nvlist_get_number(nvl, name) == INT64_MIN); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_NUMBER); CHECK(strcmp(name, "nvlist/number/INT64_MAX") == 0); CHECK((int64_t)nvlist_get_number(nvl, name) == INT64_MAX); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_STRING); CHECK(strcmp(name, "nvlist/string/") == 0); CHECK(strcmp(nvlist_get_string(nvl, name), "") == 0); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_STRING); CHECK(strcmp(name, "nvlist/string/x") == 0); CHECK(strcmp(nvlist_get_string(nvl, name), "x") == 0); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_STRING); CHECK(strcmp(name, "nvlist/string/abcdefghijklmnopqrstuvwxyz") == 0); CHECK(strcmp(nvlist_get_string(nvl, name), "abcdefghijklmnopqrstuvwxyz") == 0); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_DESCRIPTOR); CHECK(strcmp(name, "nvlist/descriptor/STDERR_FILENO") == 0); CHECK(fd_is_valid(nvlist_get_descriptor(nvl, name))); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_BINARY); CHECK(strcmp(name, "nvlist/binary/x") == 0); CHECK(memcmp(nvlist_get_binary(nvl, name, NULL), "x", 1) == 0); CHECK(memcmp(nvlist_get_binary(nvl, name, &size), "x", 1) == 0); CHECK(size == 1); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_BINARY); CHECK(strcmp(name, "nvlist/binary/abcdefghijklmnopqrstuvwxyz") == 0); CHECK(memcmp(nvlist_get_binary(nvl, name, NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(memcmp(nvlist_get_binary(nvl, name, &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz")); name = nvlist_next(nvl, &type, &cookie); CHECK(name != NULL); CHECK(type == NV_TYPE_NVLIST); CHECK(strcmp(name, "nvlist/nvlist") == 0); cnvl = nvlist_get_nvlist(nvl, name); ccookie = NULL; cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_BOOL); CHECK(strcmp(cname, "nvlist/bool/true") == 0); CHECK(nvlist_get_bool(cnvl, cname) == true); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_BOOL); CHECK(strcmp(cname, "nvlist/bool/false") == 0); CHECK(nvlist_get_bool(cnvl, cname) == false); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_NUMBER); CHECK(strcmp(cname, "nvlist/number/0") == 0); CHECK(nvlist_get_number(cnvl, cname) == 0); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_NUMBER); CHECK(strcmp(cname, "nvlist/number/1") == 0); CHECK(nvlist_get_number(cnvl, cname) == 1); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_NUMBER); CHECK(strcmp(cname, "nvlist/number/-1") == 0); CHECK((int)nvlist_get_number(cnvl, cname) == -1); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_NUMBER); CHECK(strcmp(cname, "nvlist/number/UINT64_MAX") == 0); CHECK(nvlist_get_number(cnvl, cname) == UINT64_MAX); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_NUMBER); CHECK(strcmp(cname, "nvlist/number/INT64_MIN") == 0); CHECK((int64_t)nvlist_get_number(cnvl, cname) == INT64_MIN); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_NUMBER); CHECK(strcmp(cname, "nvlist/number/INT64_MAX") == 0); CHECK((int64_t)nvlist_get_number(cnvl, cname) == INT64_MAX); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_STRING); CHECK(strcmp(cname, "nvlist/string/") == 0); CHECK(strcmp(nvlist_get_string(cnvl, cname), "") == 0); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_STRING); CHECK(strcmp(cname, "nvlist/string/x") == 0); CHECK(strcmp(nvlist_get_string(cnvl, cname), "x") == 0); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_STRING); CHECK(strcmp(cname, "nvlist/string/abcdefghijklmnopqrstuvwxyz") == 0); CHECK(strcmp(nvlist_get_string(cnvl, cname), "abcdefghijklmnopqrstuvwxyz") == 0); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_DESCRIPTOR); CHECK(strcmp(cname, "nvlist/descriptor/STDERR_FILENO") == 0); CHECK(fd_is_valid(nvlist_get_descriptor(cnvl, cname))); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_BINARY); CHECK(strcmp(cname, "nvlist/binary/x") == 0); CHECK(memcmp(nvlist_get_binary(cnvl, cname, NULL), "x", 1) == 0); CHECK(memcmp(nvlist_get_binary(cnvl, cname, &size), "x", 1) == 0); CHECK(size == 1); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname != NULL); CHECK(ctype == NV_TYPE_BINARY); CHECK(strcmp(cname, "nvlist/binary/abcdefghijklmnopqrstuvwxyz") == 0); CHECK(memcmp(nvlist_get_binary(cnvl, cname, NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(memcmp(nvlist_get_binary(cnvl, cname, &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz")); cname = nvlist_next(cnvl, &ctype, &ccookie); CHECK(cname == NULL); name = nvlist_next(nvl, &type, &cookie); CHECK(name == NULL); }
int main(void) { const nvlist_t *cnvl; nvlist_t *nvl; size_t size; printf("1..83\n"); nvl = nvlist_create(0); CHECK(!nvlist_exists_bool(nvl, "nvlist/bool/true")); nvlist_add_bool(nvl, "nvlist/bool/true", true); CHECK(nvlist_error(nvl) == 0); CHECK(nvlist_get_bool(nvl, "nvlist/bool/true") == true); CHECK(!nvlist_exists_bool(nvl, "nvlist/bool/false")); nvlist_add_bool(nvl, "nvlist/bool/false", false); CHECK(nvlist_error(nvl) == 0); CHECK(nvlist_get_bool(nvl, "nvlist/bool/false") == false); CHECK(!nvlist_exists_number(nvl, "nvlist/number/0")); nvlist_add_number(nvl, "nvlist/number/0", 0); CHECK(nvlist_error(nvl) == 0); CHECK(nvlist_get_number(nvl, "nvlist/number/0") == 0); CHECK(!nvlist_exists_number(nvl, "nvlist/number/1")); nvlist_add_number(nvl, "nvlist/number/1", 1); CHECK(nvlist_error(nvl) == 0); CHECK(nvlist_get_number(nvl, "nvlist/number/1") == 1); CHECK(!nvlist_exists_number(nvl, "nvlist/number/-1")); nvlist_add_number(nvl, "nvlist/number/-1", -1); CHECK(nvlist_error(nvl) == 0); CHECK((int)nvlist_get_number(nvl, "nvlist/number/-1") == -1); CHECK(!nvlist_exists_number(nvl, "nvlist/number/UINT64_MAX")); nvlist_add_number(nvl, "nvlist/number/UINT64_MAX", UINT64_MAX); CHECK(nvlist_error(nvl) == 0); CHECK(nvlist_get_number(nvl, "nvlist/number/UINT64_MAX") == UINT64_MAX); CHECK(!nvlist_exists_number(nvl, "nvlist/number/INT64_MIN")); nvlist_add_number(nvl, "nvlist/number/INT64_MIN", INT64_MIN); CHECK(nvlist_error(nvl) == 0); CHECK((int64_t)nvlist_get_number(nvl, "nvlist/number/INT64_MIN") == INT64_MIN); CHECK(!nvlist_exists_number(nvl, "nvlist/number/INT64_MAX")); nvlist_add_number(nvl, "nvlist/number/INT64_MAX", INT64_MAX); CHECK(nvlist_error(nvl) == 0); CHECK((int64_t)nvlist_get_number(nvl, "nvlist/number/INT64_MAX") == INT64_MAX); CHECK(!nvlist_exists_string(nvl, "nvlist/string/")); nvlist_add_string(nvl, "nvlist/string/", ""); CHECK(nvlist_error(nvl) == 0); CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/"), "") == 0); CHECK(!nvlist_exists_string(nvl, "nvlist/string/x")); nvlist_add_string(nvl, "nvlist/string/x", "x"); CHECK(nvlist_error(nvl) == 0); CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/x"), "x") == 0); CHECK(!nvlist_exists_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz")); nvlist_add_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"); CHECK(nvlist_error(nvl) == 0); CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"), "abcdefghijklmnopqrstuvwxyz") == 0); CHECK(!nvlist_exists_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO")); nvlist_add_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO", STDERR_FILENO); CHECK(nvlist_error(nvl) == 0); CHECK(fd_is_valid(nvlist_get_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO"))); CHECK(!nvlist_exists_binary(nvl, "nvlist/binary/x")); nvlist_add_binary(nvl, "nvlist/binary/x", "x", 1); CHECK(nvlist_error(nvl) == 0); CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/x", NULL), "x", 1) == 0); CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/x", &size), "x", 1) == 0); CHECK(size == 1); CHECK(!nvlist_exists_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz")); nvlist_add_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")); CHECK(nvlist_error(nvl) == 0); CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz")); CHECK(!nvlist_exists_nvlist(nvl, "nvlist/nvlist")); nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl); CHECK(nvlist_error(nvl) == 0); cnvl = nvlist_get_nvlist(nvl, "nvlist/nvlist"); CHECK(nvlist_get_bool(cnvl, "nvlist/bool/true") == true); CHECK(nvlist_get_bool(cnvl, "nvlist/bool/false") == false); CHECK(nvlist_get_number(cnvl, "nvlist/number/0") == 0); CHECK(nvlist_get_number(cnvl, "nvlist/number/1") == 1); CHECK((int)nvlist_get_number(cnvl, "nvlist/number/-1") == -1); CHECK(nvlist_get_number(cnvl, "nvlist/number/UINT64_MAX") == UINT64_MAX); CHECK((int64_t)nvlist_get_number(cnvl, "nvlist/number/INT64_MIN") == INT64_MIN); CHECK((int64_t)nvlist_get_number(cnvl, "nvlist/number/INT64_MAX") == INT64_MAX); CHECK(strcmp(nvlist_get_string(cnvl, "nvlist/string/"), "") == 0); CHECK(strcmp(nvlist_get_string(cnvl, "nvlist/string/x"), "x") == 0); CHECK(strcmp(nvlist_get_string(cnvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"), "abcdefghijklmnopqrstuvwxyz") == 0); /* TODO */ CHECK(memcmp(nvlist_get_binary(cnvl, "nvlist/binary/x", NULL), "x", 1) == 0); CHECK(memcmp(nvlist_get_binary(cnvl, "nvlist/binary/x", &size), "x", 1) == 0); CHECK(size == 1); CHECK(memcmp(nvlist_get_binary(cnvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(memcmp(nvlist_get_binary(cnvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz")); CHECK(nvlist_get_bool(nvl, "nvlist/bool/true") == true); CHECK(nvlist_get_bool(nvl, "nvlist/bool/false") == false); CHECK(nvlist_get_number(nvl, "nvlist/number/0") == 0); CHECK(nvlist_get_number(nvl, "nvlist/number/1") == 1); CHECK((int)nvlist_get_number(nvl, "nvlist/number/-1") == -1); CHECK(nvlist_get_number(nvl, "nvlist/number/UINT64_MAX") == UINT64_MAX); CHECK((int64_t)nvlist_get_number(nvl, "nvlist/number/INT64_MIN") == INT64_MIN); CHECK((int64_t)nvlist_get_number(nvl, "nvlist/number/INT64_MAX") == INT64_MAX); CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/"), "") == 0); CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/x"), "x") == 0); CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"), "abcdefghijklmnopqrstuvwxyz") == 0); CHECK(fd_is_valid(nvlist_get_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO"))); CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/x", NULL), "x", 1) == 0); CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/x", &size), "x", 1) == 0); CHECK(size == 1); CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0); CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz")); nvlist_destroy(nvl); return (0); }