HASH_WALK_FILTER(src_hash, next, src, sp) { if (src->uc == 0) { HASH_DO_REMOVE(src_hash, RSH, sp); rte_src_free_id(src->global_id); sl_free(rte_src_slab, src); } }
void endusershell(void) { if (sl) { sl_free(sl, 1); sl = NULL; } curshell = NULL; }
static void pl_each_test(void) { printsln((Any)__func__); List ac, ex; ac = sl_of_string("a, b, c, d"); pl_each(ac, pl_upper_case_free, NULL); ex = sl_of_string("A, B, C, D"); sl_check_expect(ac, ex); sl_free(ac); sl_free(ex); ac = sl_of_string(""); pl_each(ac, pl_upper_case_free, NULL); ex = sl_of_string(""); sl_check_expect(ac, ex); sl_free(ac); sl_free(ex); }
void scene_free(scene *s) { rgb_free(s->bg); sl_free(s->spheres); light_free(s->light); rgb_free(s->amb); free(s); return; }
void conf_rtables_rtable(FILE *output, int rtableid) { int i; StringList *rtable_name, *rtable_daemons; rtable_name = sl_init(); if (db_select_name_rtable(rtable_name, rtableid) < 0) { printf("%% database failure select rtables name\n"); sl_free(rtable_name, 1); return; } else { fprintf(output, "rtable %d %s\n", rtableid, rtable_name->sl_str[0]); } sl_free(rtable_name, 1); /* * Routes must be printed before we attempt to start daemons, * else rtables will not be created in the kernel (Unless an * rdomain is created by specifing one on an interface prior * to this point. An rdomain creates a new corresponding rtable) */ conf_arp(output, " arp "); conf_routes(output, " route ", AF_INET, RTF_STATIC, rtableid); conf_routes(output, " route ", AF_INET6, RTF_STATIC, rtableid); rtable_daemons = sl_init(); if (db_select_flag_x_ctl_rtable(rtable_daemons, "ctl", rtableid) < 0) { printf("%% database failure select ctl rtable\n"); sl_free(rtable_daemons, 1); return; } else { for (i = 0; i < rtable_daemons->sl_cur; i++) conf_ctl(output, " ", rtable_daemons->sl_str[i], rtableid); } sl_free(rtable_daemons, 1); fprintf(output, "!\n"); }
void unload_elf(dso *so) { /* Are we allowed to unload? */ if (so->flags_1 & DF_1_NODELETE) { sl_printf("Error unload_elf: NODELETE flag set on %s.\n", so->name); sl_exit(1); } #ifdef D_RLOAD sl_printf("Unloading %s (%p-%p)\n", so->path, so->text_addr, so->end_addr); #endif #ifdef SL_STATISTIC curr_loaded_dsos--; #endif /* Call fini functions */ so_fini(so); /* Remove it from chain and global scope */ chain_delete(so); gscope_remove(so); #if defined(VERIFY_CFTX) /* Remove it from libdetox dso_chain */ remove_dso(so); #endif /* Free name and path */ sl_free((void *)so->name, MAX_LIB_NAME); sl_free((void *)so->path, MAX_PATH_LEN); /* Free dep. and lsope lists */ if (so->deps) sl_free(so->deps, so->deps_count * sizeof(dso *)); if (so->lscope) sl_free(so->lscope, so->lscope_num * sizeof(dso *)); /* Unmap text and data segments */ unmap_segments(so); /* Free struct */ sl_free(so, sizeof(dso)); }
int main(int argc, char **argv) { int ch, i; int ret = 0; int flags = 0; includes = sl_init(); if (includes == NULL) err(EXIT_FAILURE, "sl_init()"); while ((ch = getopt(argc, argv, "CrtvI:")) != -1) { switch (ch) { case 'C': flags |= C_OPTION; break; case 'r': case 'v': case 't': /* stub compatibility with groff's soelim */ break; case 'I': sl_add(includes, optarg); break; default: sl_free(includes, 0); usage(); } } argc -= optind; argv += optind; if (argc == 0) ret = soelim_file(stdin, flags); for (i = 0; i < argc; i++) ret = soelim_file(soelim_fopen(argv[i]), flags); sl_free(includes, 0); return (ret); }
DLL_VARIABLE void sbuffer_release(sbuffer_t* lhs, sstring_t* rhs) { if(0 != rhs->str) sl_free(rhs->str); rhs->str = lhs->str; rhs->len = lhs->len; lhs->str = 0; lhs->len = 0; lhs->capacity = 0; }
/* * Help/usage command. * Call each command handler with argc == 0 and argv[0] == name. */ void help(int argc, char *argv[]) { struct cmd *c; char *nargv[1], *cmd; const char *p; int isusage; cmd = argv[0]; isusage = (strcmp(cmd, "usage") == 0); if (argc == 0 || (isusage && argc == 1)) { UPRINTF("usage: %s [command [...]]\n", cmd); return; } if (argc == 1) { StringList *buf; buf = ftp_sl_init(); fprintf(ttyout, "%sommands may be abbreviated. Commands are:\n\n", proxy ? "Proxy c" : "C"); for (c = cmdtab; (p = c->c_name) != NULL; c++) if (!proxy || c->c_proxy) ftp_sl_add(buf, ftp_strdup(p)); list_vertical(buf); sl_free(buf, 1); return; } #define HELPINDENT ((int) sizeof("disconnect")) while (--argc > 0) { char *arg; char cmdbuf[MAX_C_NAME]; arg = *++argv; c = getcmd(arg); if (c == (struct cmd *)-1) fprintf(ttyout, "?Ambiguous %s command `%s'\n", cmd, arg); else if (c == NULL) fprintf(ttyout, "?Invalid %s command `%s'\n", cmd, arg); else { if (isusage) { (void)strlcpy(cmdbuf, c->c_name, sizeof(cmdbuf)); nargv[0] = cmdbuf; (*c->c_handler)(0, nargv); } else fprintf(ttyout, "%-*s\t%s\n", HELPINDENT, c->c_name, c->c_help); } } }
/*ARGSUSED*/ static int _nis_initshells(void *rv, void *cb_data, va_list ap) { static char *ypdomain; char *key, *data; char *lastkey; int keylen, datalen; int r; if (sl) sl_free(sl, 1); sl = sl_init(); if (ypdomain == NULL) { switch (yp_get_default_domain(&ypdomain)) { case 0: break; case YPERR_RESRC: return NS_TRYAGAIN; default: return NS_UNAVAIL; } } /* * `key' and `data' point to strings dynamically allocated by * the yp_... functions. * `data' is directly put into the stringlist of shells. */ key = data = NULL; if (yp_first(ypdomain, "shells", &key, &keylen, &data, &datalen)) return NS_UNAVAIL; do { data[datalen] = '\0'; /* clear trailing \n */ sl_add(sl, data); lastkey = key; r = yp_next(ypdomain, "shells", lastkey, keylen, &key, &keylen, &data, &datalen); free(lastkey); } while (r == 0); if (r == YPERR_NOMORE) { /* * `data' and `key' ought to be NULL - do not try to free them. */ return NS_SUCCESS; } return NS_UNAVAIL; }
/* * Complete a local executable */ static unsigned char complete_executable(EditLine *el, char *word, int dolist) { StringList *words; char dir[ MAXPATHLEN ]; char *fname; unsigned char rv; size_t len; int error; if ((fname = strrchr(word, '/')) == NULL) { dir[0] = '\0'; /* walk the path */ fname = word; } else { if (fname == word) { dir[0] = '/'; dir[1] = '\0'; } else { len = fname - word; (void)strncpy(dir, word, len); dir[fname - word] = '\0'; } fname++; } words = sl_init(); if (*dir == '\0') { /* walk path */ char *env; char *path; env = getenv("PATH"); len = strlen(env); path = salloc(len + 1); (void)strcpy(path, env); error = find_execs(word, path, words); } else { /* check specified dir only */ error = find_execs(word, dir, words); } if (error != 0) return CC_ERROR; rv = complete_ambiguous(el, fname, dolist, words); if (rv == CC_REFRESH) { if (el_insertstr(el, " ") == -1) rv = CC_ERROR; } sl_free(words, 1); return rv; }
/* * Complete a local file */ static unsigned char complete_local(char *word, int list) { StringList *words; char dir[MAXPATHLEN]; char *file; DIR *dd; struct dirent *dp; unsigned char rv; if ((file = strrchr(word, '/')) == NULL) { dir[0] = '.'; dir[1] = '\0'; file = word; } else { if (file == word) { dir[0] = '/'; dir[1] = '\0'; } else { (void)strlcpy(dir, word, (size_t)(file - word) + 1); } file++; } if ((dd = opendir(dir)) == NULL) return (CC_ERROR); words = sl_init(); for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; if (strlen(file) > dp->d_namlen) continue; if (strncmp(file, dp->d_name, strlen(file)) == 0) { char *tcp; tcp = strdup(dp->d_name); if (tcp == NULL) errx(1, "Can't allocate memory for local dir"); sl_add(words, tcp); } } closedir(dd); rv = complete_ambiguous(file, list, words); sl_free(words, 1); return (rv); }
/* * Complete mime_transfer_encoding type. */ static unsigned char mime_enc_complete(EditLine *el, int ch) { static char word[LINESIZE]; StringList *words; unsigned char rv; const LineInfo *lf; size_t word_len; int dolist; lf = el_line(el); #ifdef EMACS_CTRL_D_BINDING_HACK { int cc_ret; if ((cc_ret = emacs_ctrl_d(el, lf, ch)) != -1) return cc_ret; } #endif /* EMACS_CTRL_D_BINDING_HACK */ word_len = lf->cursor - lf->buffer; if (word_len >= sizeof(word) - 1) return CC_ERROR; words = mail_sl_init(); { const char *ename; const void *cookie; cookie = NULL; for (ename = mime_next_encoding_name(&cookie); ename; ename = mime_next_encoding_name(&cookie)) if (word_len == 0 || strncmp(lf->buffer, ename, word_len) == 0) { char *cp; cp = estrdup(ename); mail_sl_add(words, cp); } } (void)strlcpy(word, lf->buffer, word_len + 1); if ((dolist = get_dolist(lf)) == -1) return CC_ERROR; rv = complete_ambiguous(el, word, dolist, words); sl_free(words, 1); return rv; }
static void f_scandir_work(uv_work_t* req) { char* path = req->data; f_scandir_response_t response = malloc(sizeof(struct f_scandir_response_s)); check_oom(response); response->dents = sl_alloc_f(1); check_oom(response->dents); response->path = path; if (!f_scandir_impl(path, response)) { if (response->dents != NULL) { sl_free(response->dents); } response->dents = NULL; } req->data = response; }
int conf_dhcrelay(char *ifname, char *server, int serverlen) { StringList *data; int alen; data = sl_init(); if ((alen = db_select_flag_x_data_ctl_rtable(data, "dhcrelay", ifname, 0)) > 0) { strlcpy(server, data->sl_str[0], serverlen); alen = strlen(data->sl_str[0]); } sl_free(data, 1); return(alen); }
void conf_db_single(FILE *output, char *dbname, char *lookup, char *ifname) { StringList *dbreturn; dbreturn = sl_init(); if (db_select_flag_x_ctl(dbreturn, dbname, ifname) < 0) { printf("%% conf_db_single %s database select failed\n", dbname); } if (dbreturn->sl_cur > 0) { if (lookup == NULL) fprintf(output, " %s\n", dbname); else if (strcmp(dbreturn->sl_str[0], lookup) != 0) fprintf(output, " %s %s\n", dbname, dbreturn->sl_str[0]); } sl_free(dbreturn, 1); }
static void add(DB *db, StringList *sl, size_t port, const char *proto, size_t *cnt, int warndup) { size_t i; char keyb[BUFSIZ], datab[BUFSIZ], abuf[BUFSIZ]; DBT data, key; key.data = keyb; data.data = datab; #ifdef DEBUG (void)printf("add %s %zu %s [ ", sl->sl_str[0], port, proto); for (i = 1; i < sl->sl_cur; i++) (void)printf("%s ", sl->sl_str[i]); (void)printf("]\n"); #endif /* key `indirect key', data `full line' */ data.size = snprintf(datab, sizeof(datab), "%zu", (*cnt)++) + 1; key.size = snprintf(keyb, sizeof(keyb), "%s %zu/%s %s", sl->sl_str[0], port, proto, mkaliases(sl, abuf, sizeof(abuf))) + 1; store(db, &data, &key, warndup); /* key `\377port/proto', data = `indirect key' */ key.size = snprintf(keyb, sizeof(keyb), "\377%zu/%s", port, proto) + 1; store(db, &key, &data, warndup); /* key `\377port', data = `indirect key' */ killproto(&key); store(db, &key, &data, warndup); /* add references for service and all aliases */ for (i = 0; i < sl->sl_cur; i++) { /* key `\376service/proto', data = `indirect key' */ key.size = snprintf(keyb, sizeof(keyb), "\376%s/%s", sl->sl_str[i], proto) + 1; store(db, &key, &data, warndup); /* key `\376service', data = `indirect key' */ killproto(&key); store(db, &key, &data, warndup); } sl_free(sl, 1); }
int main(void) { StringList *sl; char teststr[] = "test"; if ((sl = sl_init()) == NULL) return 1; if (sl_add(sl, teststr)) return 2; if (sl->sl_cur != 1) return 3; if (sl->sl_str[0] != teststr) return 4; sl_free(sl, 0); return 0; }
static unsigned char complete_alias(EditLine *el, char *word, int dolist) { struct grouphead *gh; const char **ap; const char **p; int h; int s; size_t len = strlen(word); StringList *words; unsigned char rv; words = sl_init(); /* allocate space for alias table */ s = 1; for (h = 0; h < HSHSIZE; h++) for (gh = groups[h]; gh != NULL; gh = gh->g_link) s++; ap = salloc(s * sizeof(*ap)); /* save pointers */ p = ap; for (h = 0; h < HSHSIZE; h++) for (gh = groups[h]; gh != NULL; gh = gh->g_link) *p++ = gh->g_name; *p = NULL; sort(ap); for (p = ap; *p != NULL; p++) if (len == 0 || strncmp(*p, word, len) == 0) mail_sl_add(words, estrdup(*p)); rv = complete_ambiguous(el, word, dolist, words); if (rv == CC_REFRESH) { if (el_insertstr(el, " ") == -1) rv = CC_ERROR; } sl_free(words, 1); return rv; }
static unsigned char complete_thread_key(EditLine *el, char *word, int dolist) { const char **ap; const char **p; const char *name; size_t len; StringList *words; unsigned char rv; int cnt; const void *cookie; len = strlen(word); words = sl_init(); /* count the entries in the table */ /* XXX - have a function return this rather than counting? */ cnt = 1; /* count the NULL terminator */ cookie = NULL; while (thread_next_key_name(&cookie) != NULL) cnt++; /* allocate sufficient space for the pointers */ ap = salloc(cnt * sizeof(*ap)); /* load the array */ p = ap; cookie = NULL; while ((name = thread_next_key_name(&cookie)) != NULL) *p++ = name; *p = NULL; sort(ap); for (p = ap; *p != NULL; p++) if (len == 0 || strncmp(*p, word, len) == 0) mail_sl_add(words, estrdup(*p)); rv = complete_ambiguous(el, word, dolist, words); sl_free(words, 1); return rv; }
/* * Complete a command */ static unsigned char complete_command(char *word, int list) { const struct cmd *c; StringList *words; size_t wordlen; unsigned char rv; words = sl_init(); wordlen = strlen(word); for (c = cmdtab; c->c_name != NULL; c++) { if (wordlen > strlen(c->c_name)) continue; if (strncmp(word, c->c_name, wordlen) == 0) sl_add(words, c->c_name); } rv = complete_ambiguous(word, list, words); sl_free(words, 0); return (rv); }
static unsigned char complete_set(EditLine *el, char *word, int dolist) { struct var *vp; const char **ap; const char **p; int h; int s; size_t len = strlen(word); StringList *words; unsigned char rv; words = sl_init(); /* allocate space for variables table */ s = 1; for (h = 0; h < HSHSIZE; h++) for (vp = variables[h]; vp != NULL; vp = vp->v_link) s++; ap = salloc(s * sizeof(*ap)); /* save the pointers */ for (h = 0, p = ap; h < HSHSIZE; h++) for (vp = variables[h]; vp != NULL; vp = vp->v_link) *p++ = vp->v_name; *p = NULL; sort(ap); for (p = ap; *p != NULL; p++) if (len == 0 || strncmp(*p, word, len) == 0) mail_sl_add(words, estrdup(*p)); rv = complete_ambiguous(el, word, dolist, words); sl_free(words, 1); return rv; }
int ipv6ll_db_compare(struct sockaddr_in6 *sin6, struct sockaddr_in6 *sin6mask, char *ifname) { int count, scope; StringList *data; struct in6_addr store; if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_MC_INTFACELOCAL(&sin6->sin6_addr)) { /* * Save any scope or embedded scope. * The kernel does not set sin6_scope_id. * But if it ever does, we're already prepared. */ store.s6_addr[0] = sin6->sin6_addr.s6_addr[2]; store.s6_addr[1] = sin6->sin6_addr.s6_addr[3]; sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0; scope = sin6->sin6_scope_id; sin6->sin6_scope_id = 0; data = sl_init(); db_select_flag_x_ctl_data(data, "ipv6linklocal", ifname, netname6(sin6, sin6mask)); count = data->sl_cur; sl_free(data, 1); /* restore any scope or embedded scope */ sin6->sin6_addr.s6_addr[2] = store.s6_addr[0]; sin6->sin6_addr.s6_addr[3] = store.s6_addr[1]; sin6->sin6_scope_id = scope; return(count); } return 1; }
/* * Complete a remote file */ static unsigned char complete_remote(char *word, int list) { static StringList *dirlist; static char lastdir[MAXPATHLEN]; StringList *words; char dir[MAXPATHLEN]; char *file, *cp; size_t i; unsigned char rv; char cmdbuf[MAX_C_NAME]; char *dummyargv[3] = { NULL, NULL, NULL }; (void)strlcpy(cmdbuf, "complete", sizeof(cmdbuf)); dummyargv[0] = cmdbuf; dummyargv[1] = dir; if ((file = strrchr(word, '/')) == NULL) { dir[0] = '\0'; file = word; } else { cp = file; while (*cp == '/' && cp > word) cp--; (void)strlcpy(dir, word, cp - word + 2); file++; } if (dirchange || dirlist == NULL || strcmp(dir, lastdir) != 0) { /* dir not cached */ const char *emesg; if (dirlist != NULL) sl_free(dirlist, 1); dirlist = ftp_sl_init(); mflag = 1; emesg = NULL; while ((cp = remglob(dummyargv, 0, &emesg)) != NULL) { char *tcp; if (!mflag) continue; if (*cp == '\0') { mflag = 0; continue; } tcp = strrchr(cp, '/'); if (tcp) tcp++; else tcp = cp; tcp = ftp_strdup(tcp); ftp_sl_add(dirlist, tcp); } if (emesg != NULL) { fprintf(ttyout, "\n%s\n", emesg); return (CC_REDISPLAY); } (void)strlcpy(lastdir, dir, sizeof(lastdir)); dirchange = 0; } words = ftp_sl_init(); for (i = 0; i < dirlist->sl_cur; i++) { cp = dirlist->sl_str[i]; if (strlen(file) > strlen(cp)) continue; if (strncmp(file, cp, strlen(file)) == 0) ftp_sl_add(words, cp); } rv = complete_ambiguous(file, list, words); sl_free(words, 0); return (rv); }
void dc_free(void * ptr){ /* if ptr is NULL,no operation is performed. */ if(!ptr) return; void * word_before_ptr = (uint64 *)ptr - 1; uint64 cap = *(uint64 *)word_before_ptr; int pos = cap - SMALL; struct sl_node * sn_ptr; struct slist * sl_ptr; /* if chunks wasn't pre-allocated */ if(cap < SMALL || cap > BIG){ sl_ptr = elm_table[cap]->chunks_list; pthread_mutex_lock(extra_mutex[cap]); mv2head(word_before_ptr,sl_ptr); printf("dc_mm : %s%8ld%s\n","free a extra chunk with specific capacity ", POW2(cap), " Bytes."); if(++(elm_table[cap]->idle_num) == elm_table[cap]->total_num ){ traverse(free_extra_data,elm_table[cap]->chunks_list); sl_free(free,elm_table[cap]->chunks_list); free(elm_table[cap]); elm_table[cap] = NULL; printf("dc_mm : %s%8ld%s\n","free a extra chunks list with specific capacity ", POW2(cap), " Bytes."); } extra_free[cap]++; pthread_mutex_unlock(extra_mutex[cap]); return; } /* if chunks was pre-allocated */ /* if chunk to be freed in the pre-alloc-list */ sl_ptr = chunks_manager_table[pos]->alloced_chunks; int found = find(word_before_ptr,sl_ptr); if(found){ pthread_mutex_lock(pre_alloc_mutex[pos]); mv2head(word_before_ptr,sl_ptr); push(pop(sl_ptr),chunks_manager_table[pos]->idle_chunks); ++(chunks_manager_table[pos]->idle_num); pre_alloc_free[pos]++; pthread_mutex_unlock(pre_alloc_mutex[pos]); printf("dc_mm : %s%8ld%s\n","free a chunk with specific capacity ", POW2(cap), " Bytes."); return; /* added by wakemecn at Jun 30th, 2011 */ } /* if chunk to be freed in the extra-list */ sl_ptr = elm_table[cap]->chunks_list; pthread_mutex_lock(extra_mutex[cap]); mv2head(word_before_ptr,sl_ptr); printf("dc_mm : %s%8ld%s\n","free a extra chunk with specific capacity ", POW2(cap), " Bytes."); (elm_table[cap]->idle_num)++; if(elm_table[cap]->idle_num == elm_table[cap]->total_num ){ traverse(free_extra_data,elm_table[cap]->chunks_list); sl_free(free,elm_table[cap]->chunks_list); free(elm_table[cap]); elm_table[cap] = NULL; printf("dc_mm : %s%8ld%s\n","free a extra chunks list with specific capacity ", POW2(cap), " Bytes."); } extra_free[cap]++; pthread_mutex_unlock(extra_mutex[cap]); }
static void *sl_init(const char *device, unsigned rate, unsigned latency) { unsigned i; SLInterfaceID id; SLboolean req; SLresult res; sl_t *sl; SLDataFormat_PCM fmt_pcm = {0}; SLDataSource audio_src = {0}; SLDataSink audio_sink = {0}; SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {0}; SLDataLocator_OutputMix loc_outmix = {0}; settings_t *settings = config_get_ptr(); (void)device; id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE; req = SL_BOOLEAN_TRUE; res = 0; sl = (sl_t*)calloc(1, sizeof(sl_t)); if (!sl) goto error; RARCH_LOG("[SLES]: Requested audio latency: %u ms.", latency); GOTO_IF_FAIL(slCreateEngine(&sl->engine_object, 0, NULL, 0, NULL, NULL)); GOTO_IF_FAIL(SLObjectItf_Realize(sl->engine_object, SL_BOOLEAN_FALSE)); GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->engine_object, SL_IID_ENGINE, &sl->engine)); GOTO_IF_FAIL(SLEngineItf_CreateOutputMix(sl->engine, &sl->output_mix, 0, NULL, NULL)); GOTO_IF_FAIL(SLObjectItf_Realize(sl->output_mix, SL_BOOLEAN_FALSE)); if (settings->audio.block_frames) sl->buf_size = settings->audio.block_frames * 4; else sl->buf_size = next_pow2(32 * latency); sl->buf_count = (latency * 4 * rate + 500) / 1000; sl->buf_count = (sl->buf_count + sl->buf_size / 2) / sl->buf_size; sl->buffer = (uint8_t**)calloc(sizeof(uint8_t*), sl->buf_count); if (!sl->buffer) goto error; sl->buffer_chunk = (uint8_t*)calloc(sl->buf_count, sl->buf_size); if (!sl->buffer_chunk) goto error; for (i = 0; i < sl->buf_count; i++) sl->buffer[i] = sl->buffer_chunk + i * sl->buf_size; RARCH_LOG("[SLES]: Setting audio latency: Block size = %u, Blocks = %u, Total = %u ...\n", sl->buf_size, sl->buf_count, sl->buf_size * sl->buf_count); fmt_pcm.formatType = SL_DATAFORMAT_PCM; fmt_pcm.numChannels = 2; fmt_pcm.samplesPerSec = rate * 1000; // Samplerate is in milli-Hz. fmt_pcm.bitsPerSample = 16; fmt_pcm.containerSize = 16; fmt_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; fmt_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; /* Android only. */ audio_src.pLocator = &loc_bufq; audio_src.pFormat = &fmt_pcm; loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; loc_bufq.numBuffers = sl->buf_count; loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; loc_outmix.outputMix = sl->output_mix; audio_sink.pLocator = &loc_outmix; GOTO_IF_FAIL(SLEngineItf_CreateAudioPlayer(sl->engine, &sl->buffer_queue_object, &audio_src, &audio_sink, 1, &id, &req)); GOTO_IF_FAIL(SLObjectItf_Realize(sl->buffer_queue_object, SL_BOOLEAN_FALSE)); GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &sl->buffer_queue)); sl->cond = scond_new(); sl->lock = slock_new(); (*sl->buffer_queue)->RegisterCallback(sl->buffer_queue, opensl_callback, sl); /* Enqueue a bit to get stuff rolling. */ sl->buffered_blocks = sl->buf_count; sl->buffer_index = 0; for (i = 0; i < sl->buf_count; i++) (*sl->buffer_queue)->Enqueue(sl->buffer_queue, sl->buffer[i], sl->buf_size); GOTO_IF_FAIL(SLObjectItf_GetInterface(sl->buffer_queue_object, SL_IID_PLAY, &sl->player)); GOTO_IF_FAIL(SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_PLAYING)); return sl; error: RARCH_ERR("Couldn't initialize OpenSL ES driver, error code: [%d].\n", (int)res); sl_free(sl); return NULL; }
slint_t mpi_partition_radix2(elements_t *s, partcond2_t *pc, slint_t rhigh, slint_t rlow, slint_t rwidth, int *scounts, int *sdispls, int size, int rank, MPI_Comm comm) /* sl_proto, sl_func mpi_partition_radix2 */ { slkey_pure_t max_nclasses; slkey_pure_t nclasses, bit_mask; slkey_pure_t k; const slint_t max_nareas = size - 1; slint_t nareas, nareas_new; elements_t areas0[max_nareas], areas1[max_nareas], *areas, *areas_new; double *locals, *globals; double *local_counts, *local_weights, *global_counts, *global_weights; const slint_t max_nparts = size - 1; slint_t parts_low, parts_high, nparts_removed; slint_t parts[max_nparts], part_areas[max_nparts]; double parts_range_[2 * 2 * (1 + max_nparts + 1)]; double *parts_range = parts_range_ + (2 * 2); double parts_minmax_[2 * 4 * (1 + max_nparts + 1)]; double *parts_minmax = parts_minmax_ + (2 * 4); slint_t parts_update_[1 + max_nparts + 1]; slint_t *parts_update = parts_update_ + 1; double parts_minmax_new[2 * 4]; double current_minmax[2 * 2]; double final_locals[2 * max_nparts]; slint_t i, j, jp1, jm1, l, lp1, lm1; slint_t current_width; double minmax[2 * 4 * size]; slint_t last_new_area, last_new_class; #ifdef HAVENT_MPI_IN_PLACE double local_minmax[2 * 4]; #endif slint_t lc, lcs, gc, gcs; double lw, gw, lws, gws; double d, m; elements_t xi, end; slint_t round = 0; slint_t direction = 1; slint_t refine, finalize; #ifdef RCOUNTS_RDISPLS int *rcounts, *rdispls; #endif #ifdef WEIGHT_STATS slint_t total_count = 0, partial_counts[size + 1]; double total_weight = 0.0, partial_weights[size + 1]; double vmin, vmax; # ifdef HAVENT_MPI_IN_PLACE slint_t partial_counts2[size + 1]; double partial_weights2[size + 1]; # endif #endif rti_treset(rti_tid_mpi_partition_radix2_while); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_count); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_allreduce); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_round1); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_round1_allgather); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_exscan); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_check); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_check_pre); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_check_classes); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_check_final); /* sl_tid */ rti_treset(rti_tid_mpi_partition_radix2_while_check_post); /* sl_tid */ rti_tstart(rti_tid_mpi_partition_radix2_sync); #ifdef SYNC_ON_INIT MPI_Barrier(comm); #endif rti_tstop(rti_tid_mpi_partition_radix2_sync); rti_tstart(rti_tid_mpi_partition_radix2); if (rhigh < 0) rhigh = radix_high; if (rlow < 0) rlow = radix_low; if (rwidth < 0) rwidth = sort_radix_width_default; max_nclasses = powof2_typed(rwidth, slkey_pure_t); locals = sl_alloc(2 * (max_nareas * max_nclasses + max_nareas), sizeof(double)); globals = sl_alloc(2 * (max_nareas * max_nclasses + max_nareas), sizeof(double)); areas = areas0; areas_new = areas1; /* init the first area (all elements) */ nareas = 1; elem_assign(s, &areas[0]); /* init all parts */ parts_low = 0; parts_high = max_nparts - 1; for (i = parts_low; i <= parts_high; ++i) { parts[i] = i; part_areas[i] = 0; } /* init sdispls */ for (i = 0; i < size; ++i) sdispls[i] = 0; rti_tstart(rti_tid_mpi_partition_radix2_while); while (parts_low <= parts_high) { ++round; /* setup bitmask */ current_width = xmin(rwidth, rhigh - rlow + 1); rhigh -= (current_width > 0)?current_width - 1:rhigh; nclasses = (current_width > 0)?powof2_typed(current_width, slkey_pure_t):1; bit_mask = nclasses - 1; SL_TRACE_IF(DEBUG_OR_NOT, "ROUND: %" sl_int_type_fmt ", rhigh: %" sl_int_type_fmt ", current_width: %" sl_int_type_fmt ", nclasses: %" sl_key_pure_type_fmt, round, rhigh, current_width, nclasses); finalize = (current_width <= 0); if (!finalize || round == 1) { /* init counters */ local_counts = locals; global_counts = globals; local_weights = locals + (nareas * nclasses) + nareas; global_weights = globals + (nareas * nclasses) + nareas; /* zero all counter */ for (i = 0; i < nareas; ++i) for (k = 0; k < nclasses; ++k) local_counts[i * nclasses + k] = local_weights[i * nclasses + k] = 0.0; rti_tstart(rti_tid_mpi_partition_radix2_while_count); /* for every area */ for (i = 0; i < nareas; ++i) { elem_assign_at(&areas[i], areas[i].size, &end); if (nclasses > 1) { /* counts and weights in every class */ for (elem_assign(&areas[i], &xi); xi.keys < end.keys; elem_inc(&xi)) { k = radix_key2class(key_purify(*xi.keys), rhigh, bit_mask); local_counts[i * nclasses + k] += 1; local_weights[i * nclasses + k] += elem_weight_one(&xi, 0); } } else { /* total counts and weights */ local_counts[i * nclasses + 0] = areas[i].size; for (elem_assign(&areas[i], &xi); xi.keys < end.keys; elem_inc(&xi)) local_weights[i * nclasses + 0] += elem_weight_one(&xi, 0); } /* total counts and weights in this area */ local_counts[nareas * nclasses + i] = areas[i].size; local_weights[nareas * nclasses + i] = 0.0; for (k = 0; k < nclasses; ++k) local_weights[nareas * nclasses + i] += local_weights[i * nclasses + k]; } rti_tstop(rti_tid_mpi_partition_radix2_while_count); --rhigh; rti_tstart(rti_tid_mpi_partition_radix2_while_allreduce); /* create global counts and weights */ #ifdef MPI_PARTITION_RADIX_REDUCEBCAST_THRESHOLD if (size >= MPI_PARTITION_RADIX_REDUCEBCAST_THRESHOLD) { MPI_Reduce(locals, globals, (1 + 1) * (nareas * nclasses + nareas), MPI_DOUBLE, MPI_SUM, REDUCEBCAST_ROOT, comm); MPI_Bcast(globals, (1 + 1) * (nareas * nclasses + nareas), MPI_DOUBLE, REDUCEBCAST_ROOT, comm); } else #endif MPI_Allreduce(locals, globals, (1 + 1) * (nareas * nclasses + nareas), MPI_DOUBLE, MPI_SUM, comm); rti_tstop(rti_tid_mpi_partition_radix2_while_allreduce); } #ifdef TIMING SL_TRACE_IF(DEBUG_OR_NOT, "allreduce: %f, nareas: %" sl_int_type_fmt ", nclasses: %" sl_key_type_fmt ", doubles: %" sl_int_type_fmt, rti_tlast(rti_tid_mpi_partition_radix2_while_allreduce), nareas, nclasses, (1 + 1) * (nareas * nclasses + nareas)); #endif /* if (DEBUG_OR_NOT) { printf("%d: locals\n", rank); for (i = 0; i < nareas; ++i) { printf("%d: %" sl_int_type_fmt ":", rank, i); for (k = 0; k < nclasses; ++k) printf(" %f", local_counts[i * nclasses + k]); printf(" = %f\n", local_counts[nareas * nclasses + i]); printf("%d: %" sl_int_type_fmt ":", rank, i); for (k = 0; k < nclasses; ++k) printf(" %f", local_weights[i * nclasses + k]); printf(" = %f\n", local_weights[nareas * nclasses + i]); } printf("%d: globals\n", rank); for (i = 0; i < nareas; ++i) { printf("%d: %" sl_int_type_fmt ":", rank, i); for (k = 0; k < nclasses; ++k) printf(" %f", global_counts[i * nclasses + k]); printf(" = %f\n", global_counts[nareas * nclasses + i]); printf("%d: %" sl_int_type_fmt ":", rank, i); for (k = 0; k < nclasses; ++k) printf(" %f", global_weights[i * nclasses + k]); printf(" = %f\n", global_weights[nareas * nclasses + i]); } }*/ /* do some initializations */ if (round == 1) { rti_tstart(rti_tid_mpi_partition_radix2_while_round1); /* distribute min/max counts and weights */ minmax[rank * 2 * 4 + 0 + 0] = (pc->min_count >= 0)?pc->min_count:(-pc->min_count * global_counts[nareas * nclasses + 0] / size); minmax[rank * 2 * 4 + 0 + 1] = (pc->max_count >= 0)?pc->max_count:(-pc->max_count * global_counts[nareas * nclasses + 0] / size); minmax[rank * 2 * 4 + 0 + 2] = (pc->min_cpart >= 0)?pc->min_cpart:(-pc->min_cpart * global_counts[nareas * nclasses + 0]); minmax[rank * 2 * 4 + 0 + 3] = (pc->max_cpart >= 0)?pc->max_cpart:(-pc->max_cpart * global_counts[nareas * nclasses + 0]); minmax[rank * 2 * 4 + 4 + 0] = (pc->min_weight >= 0)?pc->min_weight:(-pc->min_weight * global_weights[nareas * nclasses + 0] / size); minmax[rank * 2 * 4 + 4 + 1] = (pc->max_weight >= 0)?pc->max_weight:(-pc->max_weight * global_weights[nareas * nclasses + 0] / size); minmax[rank * 2 * 4 + 4 + 2] = (pc->min_wpart >= 0)?pc->min_wpart:(-pc->min_wpart * global_weights[nareas * nclasses + 0]); minmax[rank * 2 * 4 + 4 + 3] = (pc->max_wpart >= 0)?pc->max_wpart:(-pc->max_wpart * global_weights[nareas * nclasses + 0]); rti_tstart(rti_tid_mpi_partition_radix2_while_round1_allgather); #ifdef HAVENT_MPI_IN_PLACE local_minmax[0 + 0] = minmax[rank * 2 * 4 + 0 + 0]; local_minmax[0 + 1] = minmax[rank * 2 * 4 + 0 + 1]; local_minmax[0 + 2] = minmax[rank * 2 * 4 + 0 + 2]; local_minmax[0 + 3] = minmax[rank * 2 * 4 + 0 + 3]; local_minmax[4 + 0] = minmax[rank * 2 * 4 + 4 + 0]; local_minmax[4 + 1] = minmax[rank * 2 * 4 + 4 + 1]; local_minmax[4 + 2] = minmax[rank * 2 * 4 + 4 + 2]; local_minmax[4 + 3] = minmax[rank * 2 * 4 + 4 + 3]; MPI_Allgather(local_minmax, 2 * 4, MPI_DOUBLE, minmax, 2 * 4, MPI_DOUBLE, comm); /* MPI_Gather(local_minmax_weights, 2 * 4, MPI_DOUBLE, minmax_weights, 2 * 4, MPI_DOUBLE, 0, comm); MPI_Bcast(minmax_weights, 2 * 4 * size, MPI_DOUBLE, 0, comm);*/ #else MPI_Allgather(MPI_IN_PLACE, 2 * 4, MPI_DOUBLE, minmax_weights, 2 * 4, MPI_DOUBLE, comm); #endif rti_tstop(rti_tid_mpi_partition_radix2_while_round1_allgather); #ifdef WEIGHT_STATS total_count = global_counts[nareas * nclasses + 0]; total_weight = global_weights[nareas * nclasses + 0]; #endif parts_minmax[2 * 4 * (parts_low - 1) + 0 + 0] = parts_minmax[2 * 4 * (parts_low - 1) + 0 + 2] = 0; parts_minmax[2 * 4 * (parts_low - 1) + 0 + 1] = parts_minmax[2 * 4 * (parts_low - 1) + 0 + 3] = 0; parts_minmax[2 * 4 * (parts_low - 1) + 4 + 0] = parts_minmax[2 * 4 * (parts_low - 1) + 4 + 2] = 0; parts_minmax[2 * 4 * (parts_low - 1) + 4 + 1] = parts_minmax[2 * 4 * (parts_low - 1) + 4 + 3] = 0; parts_minmax[2 * 4 * (parts_high + 1) + 0 + 0] = parts_minmax[2 * 4 * (parts_high + 1) + 0 + 2] = 0; parts_minmax[2 * 4 * (parts_high + 1) + 0 + 1] = parts_minmax[2 * 4 * (parts_high + 1) + 0 + 3] = global_counts[nareas * nclasses + 0]; parts_minmax[2 * 4 * (parts_high + 1) + 4 + 0] = parts_minmax[2 * 4 * (parts_high + 1) + 4 + 2] = 0; parts_minmax[2 * 4 * (parts_high + 1) + 4 + 1] = parts_minmax[2 * 4 * (parts_high + 1) + 4 + 3] = global_weights[nareas * nclasses + 0]; parts_range[2 * 2 * (parts_low - 1) + 0 + 0] = parts_range[2 * 2 * (parts_high + 1) + 0 + 0] = 0.0; parts_range[2 * 2 * (parts_low - 1) + 0 + 1] = parts_range[2 * 2 * (parts_high + 1) + 0 + 1] = global_counts[nareas * nclasses + 0]; parts_range[2 * 2 * (parts_low - 1) + 2 + 0] = parts_range[2 * 2 * (parts_high + 1) + 2 + 0] = 0.0; parts_range[2 * 2 * (parts_low - 1) + 2 + 1] = parts_range[2 * 2 * (parts_high + 1) + 2 + 1] = global_weights[nareas * nclasses + 0]; for (i = parts_high; i >= parts_low; --i) { parts_minmax[2 * 4 * parts[i] + 0 + 1] = parts_minmax[2 * 4 * (parts[i] + 1) + 0 + 1] - minmax[2 * 4 * (parts[i] + 1) + 0 + 0]; parts_minmax[2 * 4 * parts[i] + 0 + 3] = parts_minmax[2 * 4 * (parts[i] + 1) + 0 + 3] - minmax[2 * 4 * (parts[i] + 1) + 0 + 1]; parts_minmax[2 * 4 * parts[i] + 4 + 1] = parts_minmax[2 * 4 * (parts[i] + 1) + 4 + 1] - minmax[2 * 4 * (parts[i] + 1) + 4 + 0]; parts_minmax[2 * 4 * parts[i] + 4 + 3] = parts_minmax[2 * 4 * (parts[i] + 1) + 4 + 3] - minmax[2 * 4 * (parts[i] + 1) + 4 + 1]; parts_minmax[2 * 4 * parts[i] + 0 + 0] = parts_minmax[2 * 4 * parts[i] + 0 + 2] = parts_minmax[2 * 4 * parts[i] + 4 + 0] = parts_minmax[2 * 4 * parts[i] + 4 + 2] = -1; parts_range[2 * 2 * parts[i] + 0 + 0] = 0.0; parts_range[2 * 2 * parts[i] + 0 + 1] = global_counts[nareas * nclasses + 0]; parts_range[2 * 2 * parts[i] + 2 + 0] = 0.0; parts_range[2 * 2 * parts[i] + 2 + 1] = global_weights[nareas * nclasses + 0]; /* SL_ASSERT(minmax[2 * 4 * (parts[i] + 1) + 0 + 2] <= minmax[2 * 4 * (parts[i] + 0) + 0 + 3]);*/ /* SL_ASSERT(minmax[2 * 4 * (parts[i] + 1) + 4 + 2] <= minmax[2 * 4 * (parts[i] + 0) + 4 + 3]);*/ parts_update[parts[i]] = 1; if (finalize) { final_locals[2 * i + 0] = local_counts[nareas * nclasses + 0]; final_locals[2 * i + 1] = local_weights[nareas * nclasses + 0]; } } rti_tstop(rti_tid_mpi_partition_radix2_while_round1); } if (finalize) { j = parts_high - parts_low + 1; SL_TRACE_IF(DEBUG_OR_NOT, "Exscan: finalizing %" sl_int_type_fmt " parts", j); rti_tstart(rti_tid_mpi_partition_radix2_while_exscan); MPI_Exscan(&final_locals[2 * parts_low], &locals[2 * parts_low], 2 * j, MPI_DOUBLE, MPI_SUM, comm); if (rank == 0) for (i = parts_low; i <= parts_high; ++i) locals[2 * i + 0] = locals[2 * i + 1] = 0; rti_tstop(rti_tid_mpi_partition_radix2_while_exscan); } nareas_new = 0; last_new_area = last_new_class = -1; /* check all remaining parts */ SL_TRACE_IF(DEBUG_OR_NOT, "ROUND: %" sl_int_type_fmt ", %s", round, (direction > 0)?"forward":"backward"); nparts_removed = 0; rti_tstart(rti_tid_mpi_partition_radix2_while_check); i = (direction > 0)?parts_low:parts_high; while ((direction > 0)?(i <= parts_high):(i >= parts_low)) { rti_tstart(rti_tid_mpi_partition_radix2_while_check_pre); SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": PART: %" sl_int_type_fmt ",%" sl_int_type_fmt, round, i, parts[i]); j = 2 * 4 * parts[i]; jp1 = 2 * 4 * (parts[i] + 1); jm1 = 2 * 4 * (parts[i] - 1); l = 2 * 2 * parts[i]; lp1 = 2 * 2 * (parts[i] + 1); lm1 = 2 * 2 * (parts[i] - 1); if (parts_update[parts[i]]) { if (direction > 0) { parts_minmax_new[0 + 0] = parts_minmax[jm1 + 0 + 0] + minmax[j + 0 + 0]; parts_minmax_new[0 + 2] = parts_minmax[jm1 + 0 + 2] + minmax[j + 0 + 1]; parts_minmax_new[4 + 0] = parts_minmax[jm1 + 4 + 0] + minmax[j + 4 + 0]; parts_minmax_new[4 + 2] = parts_minmax[jm1 + 4 + 2] + minmax[j + 4 + 1]; SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": %f + %f, %f + %f / %f + %f, %f + %f", i, parts[i], parts_minmax[jm1 + 0 + 0], minmax[j + 0 + 0], parts_minmax[jm1 + 0 + 2], minmax[j + 0 + 1], parts_minmax[jm1 + 4 + 0], minmax[j + 4 + 0], parts_minmax[jm1 + 4 + 2], minmax[j + 4 + 1]); SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": 0. parts_minmax_new: %f %f %f %f / %f %f %f %f", parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]); if (parts_minmax_new[0 + 0] < minmax[jp1 + 0 + 2]) parts_minmax_new[0 + 0] = minmax[jp1 + 0 + 2]; if (parts_minmax_new[0 + 2] > minmax[j + 0 + 3]) parts_minmax_new[0 + 2] = minmax[j + 0 + 3]; if (parts_minmax_new[4 + 0] < minmax[jp1 + 4 + 2]) parts_minmax_new[4 + 0] = minmax[jp1 + 4 + 2]; if (parts_minmax_new[4 + 2] > minmax[j + 4 + 3]) parts_minmax_new[4 + 2] = minmax[j + 4 + 3]; parts_minmax_new[0 + 1] = parts_minmax[j + 0 + 1]; parts_minmax_new[0 + 3] = parts_minmax[j + 0 + 3]; parts_minmax_new[4 + 1] = parts_minmax[j + 4 + 1]; parts_minmax_new[4 + 3] = parts_minmax[j + 4 + 3]; } else { parts_minmax_new[0 + 1] = parts_minmax[jp1 + 0 + 1] - minmax[jp1 + 0 + 0]; parts_minmax_new[0 + 3] = parts_minmax[jp1 + 0 + 3] - minmax[jp1 + 0 + 1]; parts_minmax_new[4 + 1] = parts_minmax[jp1 + 4 + 1] - minmax[jp1 + 4 + 0]; parts_minmax_new[4 + 3] = parts_minmax[jp1 + 4 + 3] - minmax[jp1 + 4 + 1]; SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": %f - %f, %f - %f / %f - %f, %f - %f", i, parts[i], parts_minmax[jp1 + 0 + 1], minmax[jp1 + 0 + 0], parts_minmax[jp1 + 0 + 3], minmax[jp1 + 0 + 1], parts_minmax[jp1 + 4 + 1], minmax[jp1 + 4 + 0], parts_minmax[jp1 + 4 + 3], minmax[jp1 + 4 + 1]); SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": 0. parts_minmax_new: %f %f %f %f / %f %f %f %f", parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]); if (parts_minmax_new[0 + 3] < minmax[jp1 + 0 + 2]) parts_minmax_new[0 + 3] = minmax[jp1 + 0 + 2]; if (parts_minmax_new[0 + 1] > minmax[j + 0 + 3]) parts_minmax_new[0 + 1] = minmax[j + 0 + 3]; if (parts_minmax_new[4 + 3] < minmax[jp1 + 4 + 2]) parts_minmax_new[4 + 3] = minmax[jp1 + 4 + 2]; if (parts_minmax_new[4 + 1] > minmax[j + 4 + 3]) parts_minmax_new[4 + 1] = minmax[j + 4 + 3]; parts_minmax_new[0 + 0] = parts_minmax[j + 0 + 0]; parts_minmax_new[0 + 2] = parts_minmax[j + 0 + 2]; parts_minmax_new[4 + 0] = parts_minmax[j + 4 + 0]; parts_minmax_new[4 + 2] = parts_minmax[j + 4 + 2]; } SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": 1. parts_minmax_new: %f %f %f %f / %f %f %f %f", parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]); SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": minmax: %f %f / %f %f", parts[i], minmax[2 * 4 * (parts[i] + 1) + 0 + 2], minmax[2 * 4 * (parts[i] + 0) + 0 + 3], minmax[2 * 4 * (parts[i] + 1) + 4 + 2], minmax[2 * 4 * (parts[i] + 0) + 4 + 3]); if (parts_minmax_new[0 + 0] > parts_minmax_new[0 + 1]) parts_minmax_new[0 + 0] = parts_minmax_new[0 + 1] = (parts_minmax_new[0 + 0] + parts_minmax_new[0 + 1]) / 2; if (parts_minmax_new[0 + 2] < parts_minmax_new[0 + 3]) parts_minmax_new[0 + 2] = parts_minmax_new[0 + 3] = (parts_minmax_new[0 + 2] + parts_minmax_new[0 + 3]) / 2; if (parts_minmax_new[4 + 0] > parts_minmax_new[4 + 1]) parts_minmax_new[4 + 0] = parts_minmax_new[4 + 1] = (parts_minmax_new[4 + 0] + parts_minmax_new[4 + 1]) / 2; if (parts_minmax_new[4 + 2] < parts_minmax_new[4 + 3]) parts_minmax_new[4 + 2] = parts_minmax_new[4 + 3] = (parts_minmax_new[4 + 2] + parts_minmax_new[4 + 3]) / 2; } else { parts_minmax_new[0 + 0] = parts_minmax[j + 0 + 0]; parts_minmax_new[0 + 1] = parts_minmax[j + 0 + 1]; parts_minmax_new[0 + 2] = parts_minmax[j + 0 + 2]; parts_minmax_new[0 + 3] = parts_minmax[j + 0 + 3]; parts_minmax_new[4 + 0] = parts_minmax[j + 4 + 0]; parts_minmax_new[4 + 1] = parts_minmax[j + 4 + 1]; parts_minmax_new[4 + 2] = parts_minmax[j + 4 + 2]; parts_minmax_new[4 + 3] = parts_minmax[j + 4 + 3]; } SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": 2. parts_minmax_new: %f %f %f %f / %f %f %f %f", i, parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]); current_minmax[0 + 0] = xmax(parts_minmax_new[0 + 0], parts_minmax_new[0 + 3]) - parts_range[l + 0 + 0]; current_minmax[0 + 1] = xmin(parts_minmax_new[0 + 2], parts_minmax_new[0 + 1]) - parts_range[l + 0 + 0]; current_minmax[2 + 0] = xmax(parts_minmax_new[4 + 0], parts_minmax_new[4 + 3]) - parts_range[l + 2 + 0]; current_minmax[2 + 1] = xmin(parts_minmax_new[4 + 2], parts_minmax_new[4 + 1]) - parts_range[l + 2 + 0]; SL_ASSERT(current_minmax[0 + 0] <= current_minmax[0 + 1]); SL_ASSERT(current_minmax[2 + 0] <= current_minmax[2 + 1]); rti_tstop(rti_tid_mpi_partition_radix2_while_check_pre); SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ": current_minmax: %f %f / %f %f", parts[i], current_minmax[0 + 0], current_minmax[0 + 1], current_minmax[2 + 0], current_minmax[2 + 1]); lcs = gcs = 0; lws = gws = 0; /* HIT is the default */ refine = 0; if (!finalize) { rti_tstart(rti_tid_mpi_partition_radix2_while_check_classes); for (k = 0; k < nclasses; ++k) { lc = local_counts[part_areas[i] * nclasses + k]; gc = global_counts[part_areas[i] * nclasses + k]; lw = local_weights[part_areas[i] * nclasses + k]; gw = global_weights[part_areas[i] * nclasses + k]; current_minmax[0 + 0] -= gc; current_minmax[0 + 1] -= gc; current_minmax[2 + 0] -= gw; current_minmax[2 + 1] -= gw; SL_TRACE_IF(DEBUG_OR_NOT, "k = %" sl_key_pure_type_fmt ", current_minmax: %f %f / %f %f", k, current_minmax[0], current_minmax[1], current_minmax[2], current_minmax[3]); /* stop and refine if max count is skipped OR min count AND max weight is skipped */ if ((current_minmax[0 + 1] < 0) || (current_minmax[0 + 0] < 0 && current_minmax[2 + 1] < 0)) { refine = 1; break; } lcs += lc; gcs += gc; lws += lw; gws += gw; gc = gw = 0.0; /* if between min/max counts */ if (current_minmax[0 + 0] <= 0 && current_minmax[0 + 1] >= 0) { /* go to next if max count not reached AND min weight not reached */ if (current_minmax[0 + 1] > 0 && current_minmax[2 + 0] > 0) continue; /* look ahead for a better stop */ if (k + 1 < nclasses && current_minmax[0 + 1] - global_counts[part_areas[i] * nclasses + k + 1] >= 0) { /* continue if weights will improve */ if (myabs(current_minmax[2 + 0] + current_minmax[2 + 1]) > myabs(current_minmax[2 + 0] + current_minmax[2 + 1] - 2 * global_weights[part_areas[i] * nclasses + k + 1])) continue; } /* stop */ break; } } SL_ASSERT(k < nclasses); SL_TRACE_IF(DEBUG_OR_NOT, "%s k = %" sl_key_pure_type_fmt, (refine)?"REFINE":"HIT", k); rti_tstop(rti_tid_mpi_partition_radix2_while_check_classes); } else { rti_tstart(rti_tid_mpi_partition_radix2_while_check_final); /* middle of min/max weight */ m = (current_minmax[2 + 0] + current_minmax[2 + 1]) / 2; /* min. part of weight to contribute */ d = xmax(0, m - locals[i * 2 + 1]); /* contribute all? */ if (d >= final_locals[i * 2 + 1]) { lc = final_locals[i * 2 + 0]; lw = final_locals[i * 2 + 1]; } else { /* contribute only a part */ lc = 0; lw = 0; /* not required */ do { d -= elem_weight_one(s, sdispls[1 + parts[i]] + lc); ++lc; } while (d >= 0 && lc < final_locals[i * 2 + 0]); --lc; /* if unweighted, then m = middle of min/max count, d = ..., lc = d */ } /* check mc against min/max count borders */ lc = xminmax(current_minmax[0 + 0] - locals[i * 2 + 0], lc, current_minmax[0 + 1] - locals[i * 2 + 0]); /* check agains 0 (don't step back!) and the local contribution */ lc = xminmax(0, lc, final_locals[i * 2 + 0]); /* the exact global counts/weights are unknown (set gc/gw so that parts_range is not changed) */ gc = 0; gw = 0; lcs += lc; gcs += gc; lws += lw; gws += gw; gc = (parts_range[2 * 2 * parts[i] + 0 + 1] - parts_range[2 * 2 * parts[i] + 0 + 0]); gw = (parts_range[2 * 2 * parts[i] + 2 + 1] - parts_range[2 * 2 * parts[i] + 2 + 0]); rti_tstop(rti_tid_mpi_partition_radix2_while_check_final); } rti_tstart(rti_tid_mpi_partition_radix2_while_check_post); SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": sdispls[%" sl_int_type_fmt " + 1] = %d, lcs = %" sl_int_type_fmt, i, parts[i], parts[i], sdispls[parts[i] + 1], lcs); sdispls[parts[i] + 1] += lcs; if (gcs > 0 || gws > 0) { parts_range[l + 0 + 0] += gcs; parts_range[l + 0 + 1] = parts_range[l + 0 + 0] + gc; parts_range[l + 2 + 0] += gws; parts_range[l + 2 + 1] = parts_range[l + 2 + 0] + gw; SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": 3. part_minmax_new: %f %f %f %f / %f %f %f %f", i, parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]); SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": parts_range: %f %f / %f %f", i, parts[i], parts_range[2 * 2 * parts[i] + 0 + 0], parts_range[2 * 2 * parts[i] + 0 + 1], parts_range[2 * 2 * parts[i] + 2 + 0], parts_range[2 * 2 * parts[i] + 2 + 1]); parts_minmax_new[0 + 0] = xminmax(parts_range[l + 0 + 0], parts_minmax_new[0 + 0], parts_range[l + 0 + 1]); parts_minmax_new[0 + 2] = xminmax(parts_range[l + 0 + 0], parts_minmax_new[0 + 2], parts_range[l + 0 + 1]); parts_minmax_new[0 + 1] = xminmax(parts_range[l + 0 + 0], parts_minmax_new[0 + 1], parts_range[l + 0 + 1]); parts_minmax_new[0 + 3] = xminmax(parts_range[l + 0 + 0], parts_minmax_new[0 + 3], parts_range[l + 0 + 1]); parts_minmax_new[4 + 0] = xminmax(parts_range[l + 2 + 0], parts_minmax_new[4 + 0], parts_range[l + 2 + 1]); parts_minmax_new[4 + 2] = xminmax(parts_range[l + 2 + 0], parts_minmax_new[4 + 2], parts_range[l + 2 + 1]); parts_minmax_new[4 + 1] = xminmax(parts_range[l + 2 + 0], parts_minmax_new[4 + 1], parts_range[l + 2 + 1]); parts_minmax_new[4 + 3] = xminmax(parts_range[l + 2 + 0], parts_minmax_new[4 + 3], parts_range[l + 2 + 1]); } SL_TRACE_IF(DEBUG_OR_NOT, "%" sl_int_type_fmt ",%" sl_int_type_fmt ": 4. part_minmax_new: %f %f %f %f / %f %f %f %f", i, parts[i], parts_minmax_new[0 + 0], parts_minmax_new[0 + 1], parts_minmax_new[0 + 2], parts_minmax_new[0 + 3], parts_minmax_new[4 + 0], parts_minmax_new[4 + 1], parts_minmax_new[4 + 2], parts_minmax_new[4 + 3]); if (parts_minmax_new[0 + 0] != parts_minmax[j + 0 + 0] || parts_minmax_new[0 + 2] != parts_minmax[j + 0 + 2] || parts_minmax_new[4 + 0] != parts_minmax[j + 4 + 0] || parts_minmax_new[4 + 2] != parts_minmax[j + 4 + 2]) { parts_minmax[j + 0 + 0] = parts_minmax_new[0 + 0]; parts_minmax[j + 0 + 2] = parts_minmax_new[0 + 2]; parts_minmax[j + 4 + 0] = parts_minmax_new[4 + 0]; parts_minmax[j + 4 + 2] = parts_minmax_new[4 + 2]; parts_update[parts[i] + 1] = 1; } if (parts_minmax_new[0 + 1] != parts_minmax[j + 0 + 1] || parts_minmax_new[0 + 3] != parts_minmax[j + 0 + 3] || parts_minmax_new[4 + 1] != parts_minmax[j + 4 + 1] || parts_minmax_new[4 + 3] != parts_minmax[j + 4 + 3]) { parts_minmax[j + 0 + 1] = parts_minmax_new[0 + 1]; parts_minmax[j + 0 + 3] = parts_minmax_new[0 + 3]; parts_minmax[j + 4 + 1] = parts_minmax_new[4 + 1]; parts_minmax[j + 4 + 3] = parts_minmax_new[4 + 3]; parts_update[parts[i] - 1] = 1; } parts_update[parts[i]] = 0; /* refine or remove */ if (refine) { /* bits left for partitioning? */ if (rhigh >= rlow) { if (last_new_area == part_areas[i] && last_new_class == k) part_areas[i] = nareas_new - 1; else { /* update last_new_... */ last_new_area = part_areas[i]; last_new_class = k; /* create new area */ elem_assign_at(&areas[part_areas[i]], lcs, &areas_new[nareas_new]); areas_new[nareas_new].size = local_counts[part_areas[i] * nclasses + k]; part_areas[i] = nareas_new; ++nareas_new; } } else { /* save local count/weight for the later prefix calculations */ final_locals[2 * (i - nparts_removed * direction) + 0] = lc; final_locals[2 * (i - nparts_removed * direction) + 1] = lw; } parts[i - nparts_removed * direction] = parts[i]; part_areas[i - nparts_removed * direction] = part_areas[i]; } else ++nparts_removed; rti_tstop(rti_tid_mpi_partition_radix2_while_check_post); i += direction; } if (direction > 0) parts_high -= nparts_removed; else parts_low += nparts_removed; direction *= -1; /* SL_NOTICE_IF(DEBUG_OR_NOT, "nparts = %" sl_int_type_fmt " vs. nareas_new = %" sl_int_type_fmt, nparts, nareas_new);*/ rti_tstop(rti_tid_mpi_partition_radix2_while_check); /* switch areas */ nareas = nareas_new; if (areas == areas0) { areas = areas1; areas_new = areas0; } else { areas = areas0; areas_new = areas1; } } rti_tstop(rti_tid_mpi_partition_radix2_while); /* create scounts */ for (i = 0; i < size - 1; ++i) scounts[i] = sdispls[i + 1] - sdispls[i]; scounts[size - 1] = s->size - sdispls[size - 1]; #ifdef SCOUNTS_SDISPLS printf("%d: scounts", rank); for (i = 0, j = 0; i < size; ++i) { printf(" %d", scounts[i]); j += scounts[i]; } printf(" = %" sl_int_type_fmt "\n", j); printf("%d: sdispls", rank); for (i = 0; i < size; ++i) printf(" %d", sdispls[i]); printf("\n"); #endif #ifdef RCOUNTS_RDISPLS rcounts = sl_alloc(size, sizeof(int)); rdispls = sl_alloc(size, sizeof(int)); MPI_Alltoall(scounts, 1, MPI_INT, rcounts, 1, MPI_INT, comm); rdispls[0] = 0; for (i = 1; i < size; ++i) rdispls[i] = rdispls[i - 1] + rcounts[i - 1]; printf("%d: rcounts", rank); for (i = 0; i < size; ++i) printf(" %d", rcounts[i]); printf("\n"); printf("%d: rdispls", rank); for (i = 0; i < size; ++i) printf(" %d", rdispls[i]); printf("\n"); sl_free(rcounts); sl_free(rdispls); #endif sl_free(locals); sl_free(globals); #ifdef WEIGHT_STATS partial_counts[size] = 0; partial_weights[size] = 0.0; for (i = 0; i < size; ++i) { partial_counts[i] = scounts[i]; partial_weights[i] = 0.0; for (j = sdispls[i]; j < sdispls[i] + scounts[i]; ++j) partial_weights[i] += elem_weight_one(s, j); partial_counts[size] += partial_counts[i]; partial_weights[size] += partial_weights[i]; } #ifdef HAVENT_MPI_IN_PLACE MPI_Reduce(partial_counts, partial_counts2, size + 1, int_mpi_datatype, MPI_SUM, 0, comm); MPI_Reduce(partial_weights, partial_weights2, size + 1, MPI_DOUBLE, MPI_SUM, 0, comm); # define partial_counts partial_counts2 # define partial_weights partial_weights2 #else /* recvbuf requires workaround for an in-place/aliased-buffer-check-bug in mpich2 (fixed with rev 5518) */ MPI_Reduce((rank == 0)?MPI_IN_PLACE:partial_counts, (rank == 0)?partial_counts:NULL, size + 1, int_mpi_datatype, MPI_SUM, 0, comm); MPI_Reduce((rank == 0)?MPI_IN_PLACE:partial_weights, (rank == 0)?partial_weights:NULL, size + 1, MPI_DOUBLE, MPI_SUM, 0, comm); #endif if (rank == 0) { printf("%d: total_count: %" sl_int_type_fmt " vs. %" sl_int_type_fmt "\n", rank, total_count, partial_counts[size]); d = 0.0; vmin = 1.0; vmax = 0.0; for (i = 0; i < size; ++i) { /* printf("%d: %" sl_int_type_fmt " %" sl_int_type_fmt " / %f - %" sl_int_type_fmt " / %f\n", rank, i, partial_counts[i], (double) partial_counts[i] / partial_counts[size], (partial_counts[size] / size) - partial_counts[i], fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size])));*/ d += fabs((partial_counts[size] / size) - partial_counts[i]); if (fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size])) < vmin) vmin = fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size])); if (fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size])) > vmax) vmax = fabs(1.0 - ((double) partial_counts[i] * size / partial_counts[size])); } printf("%d: min/max: %f / %f\n", rank, vmin, vmax); printf("%d: average_count: %" sl_int_type_fmt " - %f / %f\n", rank, partial_counts[size] / size, d / size, d / partial_counts[size]); printf("%d: total_weight: %f vs. %f\n", rank, total_weight, partial_weights[size]); d = 0.0; vmin = 1.0; vmax = 0.0; for (i = 0; i < size; ++i) { /* printf("%d: %" sl_int_type_fmt " %f / %f - %f / %f\n", rank, i, partial_weights[i], partial_weights[i] / partial_weights[size], (partial_weights[size] / size) - partial_weights[i], fabs(1.0 - (partial_weights[i] * size / partial_weights[size])));*/ d += fabs((partial_weights[size] / size) - partial_weights[i]); if (fabs(1.0 - (partial_weights[i] * size / partial_weights[size])) < vmin) vmin = fabs(1.0 - (partial_weights[i] * size / partial_weights[size])); if (fabs(1.0 - (partial_weights[i] * size / partial_weights[size])) > vmax) vmax = fabs(1.0 - (partial_weights[i] * size / partial_weights[size])); } printf("%d: min/max: %f / %f\n", rank, vmin, vmax); printf("%d: average_weight: %f - %f / %f\n", rank, partial_weights[size] / size, d / size, d / partial_weights[size]); } #endif rti_tstop(rti_tid_mpi_partition_radix2); #if defined(TIMING_STATS) && defined(SL_USE_RTI_TIM) if (rank == 0) { printf("%d: mpi_partition_radix: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2)); printf("%d: mpi_partition_radix: sync: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_sync)); printf("%d: mpi_partition_radix: while: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while)); printf("%d: mpi_partition_radix: count: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_count)); printf("%d: mpi_partition_radix: allreduce: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_allreduce)); printf("%d: mpi_partition_radix: round1: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_round1)); printf("%d: mpi_partition_radix: allgather: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_round1_allgather)); printf("%d: mpi_partition_radix: exscan: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_exscan)); printf("%d: mpi_partition_radix: check: %f\n", rank, rti_tcumu(rti_tid_mpi_partition_radix2_while_check)); printf("%d: mpi_partition_radix: pre: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_check_pre)); printf("%d: mpi_partition_radix: classes: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_check_classes)); printf("%d: mpi_partition_radix: final: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_check_final)); printf("%d: mpi_partition_radix: post: %f\n", rank, rti_tlast(rti_tid_mpi_partition_radix2_while_check_post)); } #endif return 0; }
/* * Complete a remote file */ static unsigned char complete_remote(char *word, int list) { static StringList *dirlist; static char lastdir[MAXPATHLEN]; StringList *words; char dir[MAXPATHLEN]; char *file, *cp; int i; unsigned char rv; char *dummyargv[] = { "complete", dir, NULL }; if ((file = strrchr(word, '/')) == NULL) { dir[0] = '.'; dir[1] = '\0'; file = word; } else { cp = file; while (*cp == '/' && cp > word) cp--; (void)strlcpy(dir, word, (size_t)(cp - word + 2)); file++; } if (dirchange || strcmp(dir, lastdir) != 0) { /* dir not cached */ char *emesg; sl_free(dirlist, 1); dirlist = sl_init(); mflag = 1; emesg = NULL; #ifndef SMALL if (debug) (void)putc('\n', ttyout); #endif /* !SMALL */ while ((cp = remglob(dummyargv, 0, &emesg)) != NULL) { char *tcp; if (!mflag) continue; if (*cp == '\0') { mflag = 0; continue; } tcp = strrchr(cp, '/'); if (tcp) tcp++; else tcp = cp; tcp = strdup(tcp); if (tcp == NULL) errx(1, "Can't allocate memory for remote dir"); sl_add(dirlist, tcp); } if (emesg != NULL) { fprintf(ttyout, "\n%s\n", emesg); return (CC_REDISPLAY); } (void)strlcpy(lastdir, dir, sizeof lastdir); dirchange = 0; } words = sl_init(); for (i = 0; i < dirlist->sl_cur; i++) { cp = dirlist->sl_str[i]; if (strlen(file) > strlen(cp)) continue; if (strncmp(file, cp, strlen(file)) == 0) sl_add(words, cp); } rv = complete_ambiguous(file, list, words); sl_free(words, 0); return (rv); }
FILE * ftpd_popen(char *argv[], const char *ptype, int stderrfd) { FILE *iop; int argc, pdes[2], pid, isls; char **pop; StringList *sl; iop = NULL; isls = 0; if ((*ptype != 'r' && *ptype != 'w') || ptype[1]) return (NULL); if (!pids) { if ((fds = getdtablesize()) <= 0) return (NULL); if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL) return (NULL); memset(pids, 0, fds * sizeof(int)); } if (pipe(pdes) < 0) return (NULL); if ((sl = sl_init()) == NULL) goto pfree; /* glob each piece */ if (sl_add(sl, ftpd_strdup(argv[0])) == -1) goto pfree; for (argc = 1; argv[argc]; argc++) { glob_t gl; int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE|GLOB_LIMIT; memset(&gl, 0, sizeof(gl)); if (glob(argv[argc], flags, NULL, &gl)) { if (sl_add(sl, ftpd_strdup(argv[argc])) == -1) { globfree(&gl); goto pfree; } } else { for (pop = gl.gl_pathv; *pop; pop++) { if (sl_add(sl, ftpd_strdup(*pop)) == -1) { globfree(&gl); goto pfree; } } } globfree(&gl); } if (sl_add(sl, NULL) == -1) goto pfree; #ifndef NO_INTERNAL_LS isls = (strcmp(sl->sl_str[0], INTERNAL_LS) == 0); #endif pid = isls ? fork() : vfork(); switch (pid) { case -1: /* error */ (void)close(pdes[0]); (void)close(pdes[1]); goto pfree; /* NOTREACHED */ case 0: /* child */ if (*ptype == 'r') { if (pdes[1] != STDOUT_FILENO) { dup2(pdes[1], STDOUT_FILENO); (void)close(pdes[1]); } if (stderrfd == -1) (void)close(STDERR_FILENO); else dup2(stderrfd, STDERR_FILENO); (void)close(pdes[0]); } else { if (pdes[0] != STDIN_FILENO) { dup2(pdes[0], STDIN_FILENO); (void)close(pdes[0]); } (void)close(pdes[1]); } #ifndef NO_INTERNAL_LS if (isls) { /* use internal ls */ optreset = optind = optopt = 1; closelog(); exit(ls_main(sl->sl_cur - 1, sl->sl_str)); } #endif execv(sl->sl_str[0], sl->sl_str); _exit(1); } /* parent; assume fdopen can't fail... */ if (*ptype == 'r') { iop = fdopen(pdes[0], ptype); (void)close(pdes[1]); } else { iop = fdopen(pdes[1], ptype); (void)close(pdes[0]); } pids[fileno(iop)] = pid; pfree: if (sl) sl_free(sl, 1); return (iop); }
/* * Complete a local file */ static unsigned char complete_local(char *word, int list) { StringList *words; char dir[MAXPATHLEN]; char *file; DIR *dd; struct dirent *dp; unsigned char rv; size_t len; if ((file = strrchr(word, '/')) == NULL) { dir[0] = '.'; dir[1] = '\0'; file = word; } else { if (file == word) { dir[0] = '/'; dir[1] = '\0'; } else (void)strlcpy(dir, word, file - word + 1); file++; } if (dir[0] == '~') { char *p; if ((p = globulize(dir)) == NULL) return (CC_ERROR); (void)strlcpy(dir, p, sizeof(dir)); free(p); } if ((dd = opendir(dir)) == NULL) return (CC_ERROR); words = ftp_sl_init(); len = strlen(file); for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; #if defined(DIRENT_MISSING_D_NAMLEN) if (len > strlen(dp->d_name)) continue; #else if (len > dp->d_namlen) continue; #endif if (strncmp(file, dp->d_name, len) == 0) { char *tcp; tcp = ftp_strdup(dp->d_name); ftp_sl_add(words, tcp); } } closedir(dd); rv = complete_ambiguous(file, list, words); if (rv == CC_REFRESH) { struct stat sb; char path[MAXPATHLEN]; (void)strlcpy(path, dir, sizeof(path)); (void)strlcat(path, "/", sizeof(path)); (void)strlcat(path, words->sl_str[0], sizeof(path)); if (stat(path, &sb) >= 0) { char suffix[2] = " "; if (S_ISDIR(sb.st_mode)) suffix[0] = '/'; if (el_insertstr(el, suffix) == -1) rv = CC_ERROR; } } sl_free(words, 1); return (rv); }