int vzctl2_get_env_status_info(struct vzctl_env_handle *h, vzctl_env_status_t *status, int mask) { int ret, exists = 0; char path[512]; const char *ve_private = h->env_param->fs->ve_private; const char *ve_root = h->env_param->fs->ve_root; memset(status, 0, sizeof(vzctl_env_status_t)); /* get running state */ if (mask & ENV_STATUS_RUNNING) { if (is_env_run(h) == 1) { status->mask |= ENV_STATUS_RUNNING; get_env_ops()->env_get_cpt_state(h, &status->mask); } } /* do exit if only running status requested */ if (mask == ENV_STATUS_RUNNING) return 0; if ((ret = check_var(ve_private, "VE_PRIVATE not set"))) return ret; vzctl2_get_env_conf_path(EID(h), path, sizeof(path)); if (stat_file(path) == 1 && stat_file(ve_private) == 1) { if (mask & ENV_SKIP_OWNER) exists = 1; else if (vzctl2_check_owner(ve_private) == 0) exists = 1; } if ((mask & ENV_STATUS_EXISTS) && exists) status->mask |= ENV_STATUS_EXISTS; /* get mounted state */ if (mask & (ENV_STATUS_MOUNTED | ENV_STATUS_MOUNTED_FAST) && exists) { if ((ret = check_var(ve_root, "VE_ROOT not set"))) return ret; ret = (mask & ENV_STATUS_MOUNTED) ? vzctl2_env_is_mounted(h) : fs_is_mounted_check_by_target(ve_root); if (ret == 1) status->mask |= ENV_STATUS_MOUNTED; } /* get suspended state */ if ((mask & ENV_STATUS_SUSPENDED) && exists && !(status->mask & ENV_STATUS_RUNNING)) { vzctl2_get_dump_file(h, path, sizeof(path)); if (stat_file(path) == 1) status->mask |= ENV_STATUS_SUSPENDED; } read_env_transition(EID(h), h->env_param->opts->lockdir, status); return 0; }
int check_incr_op(is_incr_op* node) { is_type_native type; char* typeA; int errors = 0; errors += check_var(node->var); if (errors == 0) { if (node->var->s_type->type != t_type_decl_array_decl) { type = operators_incr_op[node->var->s_type->data.type_object->type]; if (type == ERROR) { errors++; pretty_error(node->line, "increment operation with %s type is invalid", typeA = string_type_decl(node->var->s_type)); free(typeA); } else if (!node->var->initialized) { errors++; pretty_error(node->line, "variable used in a increment op without being initialized "); } else node->s_type = duplicate_type_decl(node->var->s_type); } else { errors++; pretty_error(node->line, "increment operations are invalid between array types"); } } return errors; }
/*---NAME WILBE SAME AS VALUE---*/ void add_value(char name[],KindType k,char *val) { float f; int count,i; if(Lexicon.count == number_of_token) reassign_mem(); f = get_num(val); count = Lexicon.count; if(check_var(name)==1) { i = get_count(name); Lexicon.Entry[i].info.val = f; } else { count ++; i = count; strcpy(Lexicon.Entry[i].name,name); Lexicon.Entry[i].kind = k; Lexicon.Entry[i].str = NULL; Lexicon.Entry[i].info.val = f; Lexicon.count += 1; } }
static int dev_create(const char *root, dev_res *dev) { char buf1[STR_SIZE]; char buf2[STR_SIZE]; struct stat st, st2; const char* udev_paths[] = { "/lib/udev/devices", "/etc/udev/devices", NULL}; int i; if (!dev->name) return 0; if (check_var(root, "VE_ROOT is not set")) return VZ_VE_ROOT_NOTSET; /* Get device information from CT0 and create it in CT */ snprintf(buf1, sizeof(buf1), "%s/dev/%s", root, dev->name); snprintf(buf2, sizeof(buf2), "/dev/%s", dev->name); if (stat(buf2, &st)) { if (errno == ENOENT) logger(-1, 0, "Incorrect name or no such device %s", buf2); else logger(-1, errno, "Unable to stat device %s", buf2); return VZ_SET_DEVICES; } if (!S_ISCHR(st.st_mode) && !S_ISBLK(st.st_mode)) { logger(-1, 0, "The %s is not block or character device", buf2); return VZ_SET_DEVICES; } if (make_dir(buf1, 0)) return VZ_SET_DEVICES; unlink(buf1); if (mknod(buf1, st.st_mode, st.st_rdev)) { logger(-1, errno, "Unable to create device %s", buf1); return VZ_SET_DEVICES; } /* Try to create static device node for udev */ for (i = 0; udev_paths[i] != NULL; i++) { if (stat(udev_paths[i], &st2) == 0) { if (S_ISDIR(st2.st_mode)) { snprintf(buf1, sizeof(buf1), "%s/%s/%s", root, udev_paths[i], dev->name); make_dir(buf1, 0); unlink(buf1); mknod(buf1, st.st_mode, st.st_rdev); break; } } } return 0; }
/* * resizes OLD_PNT to SIZE bytes and return the new space after either copying * all of OLD_PNT to the new area or truncating */ EXPORT char *realloc(char * old_pnt, unsigned int new_size) { char *newp; #if ALLOW_REALLOC_NULL if (old_pnt == NULL) return malloc(new_size); #endif if (check_debug_vars(_malloc_file, _malloc_line) != NOERROR) return REALLOC_ERROR; check_var(_malloc_file, _malloc_line, old_pnt); newp = (char *)_chunk_realloc(_malloc_file, _malloc_line, old_pnt, new_size); check_var(_malloc_file, _malloc_line, newp); in_alloc = FALSE; return newp; }
void aff_prompt(t_vars *p) { char *cwd; char empty; empty = '\0'; if ((p->username = check_var("USER", p)) == NULL) p->username = ∅ if ((p->hostname = check_var("HOST", p)) == NULL) p->hostname = ∅ my_printf("\033[2m%s\033[0m", p->username); my_printf("\033[2m%s\033[0m", p->hostname); my_printf("\033[33m•\033[0m\033[2m%d\033[0m\033[33m•\033[0m", p->cur_cmd++); my_printf("\033[32m%s\033[0m» ", cwd = get_cur_dir()); free(cwd); if (p->username[0] != '\0') free(p->username); if (p->hostname[0] != '\0') free(p->hostname); }
// Mostly used to make skew vars... void varpower::var(int v, int e, intarray &result) { if (e == 0) result.append(1); else { check_var(v,e); // Sets ERROR if a problem... result.append(3); result.append(v); result.append(e); } }
/* * allocate and return a SIZE block of bytes */ EXPORT char *malloc(unsigned int size) { char *newp; if (check_debug_vars(_malloc_file, _malloc_line) != NOERROR) return MALLOC_ERROR; newp = (char *)_chunk_malloc(_malloc_file, _malloc_line, size); check_var(_malloc_file, _malloc_line, newp); in_alloc = FALSE; return newp; }
void read_command_line() { int i=1; if(gargc<2)return; for(;i<gargc;i++) { if(gargv[i][0]=='-') { if(gargv[i][1]=='-')check_var(gargv[i]+2,COMMAND_LINE_LONG_VAR); else { char str[200]; if(strchr(gargv[i], '=') != NULL) { //eg -u=name safe_snprintf(str,sizeof(str),"%s",gargv[i]); } else if(i>=gargc-1 || gargv[i+1][0] == '-') { //eg -uname safe_snprintf(str,sizeof(str),"%s",gargv[i]); } else { //eg -u name safe_snprintf(str,sizeof(str),"%s %s",gargv[i],gargv[i+1]); } check_var(str+1,COMMAND_LINE_SHORT_VAR); } } } }
void varpower::from_arrayint(M2_arrayint m, intarray &result) { int *result_vp = result.alloc(m->len+1); *result_vp++ = m->len+1; int *melems = m->array; for (int i=0; i<m->len; i+=2) { int v = *melems++; int e = *melems++; check_var(v,e); *result_vp++ = v; *result_vp++ = e; } }
/* * release PNT in the heap, returning FREE_[NO]ERROR */ EXPORT int free(char * pnt) { int ret; if (!pnt) return NOERROR; if (check_debug_vars(_malloc_file, _malloc_line) != NOERROR) return FREE_ERROR; check_var(_malloc_file, _malloc_line, pnt); ret = _chunk_free(_malloc_file, _malloc_line, pnt); in_alloc = FALSE; return ret; }
/* Authenticate the user in a the Container * @param id Container id * @param user User name * @param password User password * @param gid if >= 0 user checked to be a member of group gid. * @param type 0 - system, 1 - pleskadmin * @return */ int vzctl2_env_auth(struct vzctl_env_handle *h, const char *user, const char *passwd, int gid, int type) { int is_mounted = 0; int pid, ret; struct vzctl_env_param *env; if (user == NULL || passwd == NULL) return vzctl_err(VZCTL_E_INVAL, 0, "Invalid argument"); env = vzctl2_get_env_param(h); if (check_var(env->fs->ve_root, "VE_ROOT is not set")) return VZCTL_E_VE_ROOT_NOTSET; is_mounted = vzctl2_env_is_mounted(h); if (!is_mounted) { ret = vzctl2_env_mount(h, 0); if (ret) return ret; } if (!(pid = fork())) { int rootfd = -1; if (type == 0) { rootfd = open("/", O_RDONLY); if (rootfd == -1) _exit(vzctl_err(VZCTL_E_SYSTEM, errno, "failed to open '/' ")); } if ((ret = vzctl_chroot(env->fs->ve_root)) == 0) { if (type == 0) ret = userauth(user, passwd, gid, rootfd); else ret = pleskauth(user, passwd); } if (rootfd != -1) close(rootfd); _exit(ret); } ret = env_wait(pid, 0, NULL); if (!is_mounted) vzctl2_env_umount(h, 0); return ret; }
void check_command(SymTab *st, Command* c) { if(!c) return; switch(c->tag) { case COMMAND_IF: { check_exp(st, c->u.cif.exp); check_type_int(c->u.cif.exp); check_command(st, c->u.cif.comm); check_command(st, c->u.cif.celse); break; } case COMMAND_WHILE: { check_exp(st, c->u.cwhile.exp); check_type_int(c->u.cwhile.exp); check_command(st, c->u.cwhile.comm); break; } case COMMAND_ATTR: { check_var(st, c->u.attr.lvalue); check_exp(st, c->u.attr.rvalue); check_type_compatible(c->u.attr.lvalue->type, &(c->u.attr.rvalue), c->line); break; } case COMMAND_RET: { if(c->u.ret) { check_exp(st, c->u.ret); check_type_compatible(return_type, &(c->u.ret), c->line); } break; } case COMMAND_FUNCALL: { check_exp(st, c->u.funcall); break; } case COMMAND_BLOCK: { check_block(st, c->u.block); break; } } }
char *real_string_stringmode(char *base_string, unsigned char *data) { char *real_string; int size; int i = 0; size = (strlen(base_string) + 1); real_string = xmalloc(size * sizeof(char)); strncpy(real_string, base_string, size); while (check_var(real_string) == 1) { i = pose_var(real_string); real_string[i] = data[i]; } return (real_string); }
/* * allocate and return a block of bytes able to hold NUM_ELEMENTS of elements * of SIZE bytes and zero the block */ EXPORT char *calloc(unsigned int num_elements, unsigned int size) { char *newp; unsigned int len = num_elements * size; if (check_debug_vars(_malloc_file, _malloc_line) != NOERROR) return CALLOC_ERROR; /* needs to be done here */ _calloc_count++; /* alloc and watch for the die address */ newp = (char *)_chunk_malloc(_malloc_file, _malloc_line, len); check_var(_malloc_file, _malloc_line, newp); (void)memset(newp, NULLC, len); in_alloc = FALSE; return newp; }
/** Stop CT. * * @param h CT handler. * @param veid CT ID. * @param param CT parameters. * @param stop_mode stop mode, one of (M_REBOOT M_HALT M_KILL). * @param skip flag to skip run action script (SKIP_ACTION_SCRIPT) * @param action modules list, used to call cleanup() callback. * @return 0 on success. */ int vps_stop(vps_handler *h, envid_t veid, vps_param *param, int stop_mode, skipFlags skip, struct mod_action *action) { int ret; char buf[64]; vps_res *res = ¶m->res; if (check_var(res->fs.root, "VE_ROOT is not set")) return VZ_VE_ROOT_NOTSET; if (!vps_is_run(h, veid)) { logger(-1, 0, "Unable to stop: container is not running"); return 0; } if (!(skip & SKIP_ACTION_SCRIPT)) { snprintf(buf, sizeof(buf), VPS_CONF_DIR "%d.%s", veid, STOP_PREFIX); if (stat_file(buf)) { if (vps_exec_script(h, veid, res->fs.root, NULL, NULL, buf, NULL, 0)) { return VZ_ACTIONSCRIPT_ERROR; } } } /* get CT IP addresses for cleanup */ get_vps_ip(h, veid, ¶m->del_res.net.ip); if ((ret = env_stop(h, veid, res->fs.root, stop_mode))) goto end; mod_cleanup(h, veid, action, param); /* Cleanup CT IPs */ run_net_script(veid, DEL, ¶m->del_res.net.ip, STATE_STOPPING, param->res.net.skip_arpdetect); ret = vps_umount(h, veid, res->fs.root, skip); end: free_str_param(¶m->del_res.net.ip); return ret; }
int vps_start_custom(vps_handler *h, envid_t veid, vps_param *param, skipFlags skip, struct mod_action *mod, env_create_FN fn, void *data) { int wait_p[2]; int old_wait_p[2]; int err_p[2]; int ret, err; char buf[64]; char *dist_name; struct sigaction act; vps_res *res = ¶m->res; dist_actions actions; memset(&actions, 0, sizeof(actions)); if (check_var(res->fs.root, "VE_ROOT is not set")) return VZ_VE_ROOT_NOTSET; if (vps_is_run(h, veid)) { logger(-1, 0, "Container is already running"); return VZ_VE_RUNNING; } if ((ret = check_ub(&res->ub))) return ret; dist_name = get_dist_name(&res->tmpl); ret = read_dist_actions(dist_name, DIST_DIR, &actions); free(dist_name); if (ret) return ret; logger(0, 0, "Starting container ..."); if (vps_is_mounted(res->fs.root)) { /* if CT is mounted -- umount first, to cleanup mount state */ vps_umount(h, veid, res->fs.root, skip); } if (!vps_is_mounted(res->fs.root)) { /* increase quota to perform setup */ quota_inc(&res->dq, 100); if ((ret = vps_mount(h, veid, &res->fs, &res->dq, skip))) return ret; quota_inc(&res->dq, -100); } /* Fedora 14/15 hacks */ if (fix_ve_devconsole(res->fs.root) != 0) return VZ_FS_BAD_TMPL; if (fix_ve_systemd(res->fs.root) != 0) return VZ_FS_BAD_TMPL; if (pipe(wait_p) < 0) { logger(-1, errno, "Can not create pipe"); return VZ_RESOURCE_ERROR; } /* old_wait_p is needed for backward compatibility with older kernels, * while for recent ones (that support CPT_SET_LOCKFD2) we use wait_p. * * If old_wait_p is closed without writing any data, it's "OK to go" * signal, and if data are received from old_wait_p it's "no go" * signal". Note that such thing doesn't work if vzctl segfaults, * because in this case the descriptor will be closed without * sending data. */ if (pipe(old_wait_p) < 0) { logger(-1, errno, "Can not create pipe"); return VZ_RESOURCE_ERROR; } if (pipe(err_p) < 0) { close(wait_p[0]); close(wait_p[1]); logger(-1, errno, "Can not create pipe"); return VZ_RESOURCE_ERROR; } sigemptyset(&act.sa_mask); act.sa_handler = SIG_IGN; act.sa_flags = 0; sigaction(SIGPIPE, &act, NULL); fix_numiptent(&res->ub); fix_cpu(&res->cpu); ret = vz_env_create(h, veid, res, wait_p, old_wait_p, err_p, fn, data); if (ret) goto err; if ((ret = vps_setup_res(h, veid, &actions, &res->fs, param, STATE_STARTING, skip, mod))) { goto err; } if (!(skip & SKIP_ACTION_SCRIPT)) { snprintf(buf, sizeof(buf), VPS_CONF_DIR "%d.%s", veid, START_PREFIX); if (stat_file(buf)) { if (vps_exec_script(h, veid, res->fs.root, NULL, NULL, buf, NULL, 0)) { ret = VZ_ACTIONSCRIPT_ERROR; goto err; } } } /* Tell the child that it's time to start /sbin/init */ err = 0; if (write(wait_p[1], &err, sizeof(err)) != sizeof(err)) logger(-1, errno, "Unable to write to waitfd to start init"); close(wait_p[1]); close(old_wait_p[1]); err: free_dist_actions(&actions); if (ret) { /* Kill environment */ logger(-1, 0, "Container start failed (try to check kernel " "messages, e.g. \"dmesg | tail\")"); /* Close wait fd without writing anything to it * to signal the child that we have failed to configure * the environment, so it should not start /sbin/init */ close(wait_p[1]); write(old_wait_p[1], &err, sizeof(err)); close(old_wait_p[1]); } else { if (!read(err_p[0], &ret, sizeof(ret))) { if (res->misc.wait == YES) { logger(0, 0, "Container start in progress" ", waiting ..."); err = vps_execFn(h, veid, res->fs.root, wait_on_fifo, NULL, 0); if (err) { logger(0, 0, "Container wait failed%s", err == VZ_EXEC_TIMEOUT ? \ " - timeout expired" : ""); ret = VZ_WAIT_FAILED; } else { logger(0, 0, "Container started" " successfully"); } } else { logger(0, 0, "Container start in progress..."); } } else { if (ret == VZ_FS_BAD_TMPL) logger(-1, 0, "Unable to start init, probably" " incorrect template"); logger(-1, 0, "Container start failed"); } } if (ret) { if (vps_is_run(h, veid)) env_stop(h, veid, res->fs.root, M_KILL); /* restore original quota values */ vps_set_quota(veid, &res->dq); if (vps_is_mounted(res->fs.root)) vps_umount(h, veid, res->fs.root, skip); } close(wait_p[0]); close(wait_p[1]); close(err_p[0]); close(err_p[1]); return ret; }
int check_assign_op(is_assign_op* node) { int errors = 0; char* typeA, *typeB; is_type_native type; SYMBOL* symbol; errors += check_var(node->var); errors += check_expr(node->expr); if (errors == 0) { switch (node->type) { case t_assign_op_eq: if (!type_type_assign_able(node->var->s_type, node->expr->s_type)) { errors++; pretty_error(node->line, "invalid assignment from %s to %s", typeA = string_type_decl(node->expr->s_type), typeB = string_type_decl(node->var->s_type) ); free(typeA); free(typeB); } else { if (node->var->type == t_var_id) { symbol = scope_lookup(symtab, node->var->data.id->name, t_symbol_var); symbol->data.var_data.initialized = true; } node->s_type = duplicate_type_decl(node->var->s_type); } break; default: if (node->var->s_type->type == t_type_decl_array_decl || node->expr->s_type->type == t_type_decl_array_decl) { errors++; pretty_error(node->line, "assignment operations are invalid between array types"); } else { type = operators_binary[node->type][node->var->s_type->data.type_object->type][node->expr->s_type->data.type_object->type]; if (type == ERROR) { errors++; pretty_error(node->line, "assignment operation invalid between %s and %s", typeA = string_type_decl(node->var->s_type), typeB = string_type_decl(node->expr->s_type) ); free(typeA); free(typeB); } else node->s_type = insert_type_decl_object(insert_type_object(type)); } break; } } return errors; }
int check_var(is_var* node) { int errors = 0; char *typeA; switch (node->type) { case t_var_id: node->symbol = scope_lookup(symtab, node->data.id->name, t_symbol_var); if (!node->symbol) { errors++; pretty_error(node->line, "undefined variable \"%s\"", node->data.id->name); node->initialized = false; } else { node->initialized = node->symbol->data.var_data.initialized; node->s_type = duplicate_type_decl(node->symbol->data.var_data.type); } break; case t_var_new_op: errors += check_new_op(node->data.new_op); node->s_type = duplicate_type_decl(node->data.new_op->s_type); node->initialized = true; break; case t_var_array: errors += check_var(node->data.array.var); errors += check_dims_sized(node->data.array.dims); if (errors == 0) { if (node->data.array.var->s_type->type == t_type_decl_array_decl) { node->s_type = decapsulate_type_decl(node->data.array.var->s_type); } else { errors++; pretty_error(node->line, "subscript of unsuscriptable type (%s)", typeA = string_type_decl(node->data.array.var->s_type) ); free(typeA); } } node->initialized = true; break; case t_var_func_call: errors += check_func_call(node->data.func_call.call); errors += check_dims_sized(node->data.array.dims); if (errors == 0) { if (node->data.func_call.call->s_type->type == t_type_decl_array_decl) { node->s_type = decapsulate_type_decl(node->data.func_call.call->s_type); } else { errors++; pretty_error(node->line, "subscript of unsuscriptable type (%s)", typeA = string_type_decl(node->data.func_call.call->s_type) ); free(typeA); } } node->initialized = true; break; } /* todo propagate node->initialized */ return errors; }
int vz_env_create(vps_handler *h, envid_t veid, vps_res *res, int wait_p[2], int old_wait_p[2], int err_p[2], env_create_FN fn, void *data) { int ret, pid, errcode; int old_wait_fd; int status_p[2]; struct sigaction act, actold; if (check_var(res->fs.root, "VE_ROOT is not set")) return VZ_VE_ROOT_NOTSET; if (pipe(status_p) < 0) { logger(-1, errno, "Can not create pipe"); return VZ_RESOURCE_ERROR; } sigaction(SIGCHLD, NULL, &actold); sigemptyset(&act.sa_mask); act.sa_handler = SIG_IGN; act.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &act, NULL); get_osrelease(res); if ((pid = fork()) < 0) { logger(-1, errno, "Can not fork"); ret = VZ_RESOURCE_ERROR; goto err; } else if (pid == 0) { dup2(status_p[1], STDIN_FILENO); close(status_p[0]); close(status_p[1]); fcntl(STDIN_FILENO, F_SETFD, FD_CLOEXEC); fcntl(err_p[1], F_SETFD, FD_CLOEXEC); close(err_p[0]); fcntl(wait_p[0], F_SETFD, FD_CLOEXEC); close(wait_p[1]); if (old_wait_p) { fcntl(old_wait_p[0], F_SETFD, FD_CLOEXEC); close(old_wait_p[1]); old_wait_fd = old_wait_p[0]; } else old_wait_fd = -1; ret = vz_real_env_create(h, veid, res, wait_p[0], old_wait_fd, err_p[1], fn, data); if (ret) write(STDIN_FILENO, &ret, sizeof(ret)); exit(ret); } /* Wait for environment created */ close(status_p[1]); close(wait_p[0]); if (old_wait_p) close(old_wait_p[0]); close(err_p[1]); ret = read(status_p[0], &errcode, sizeof(errcode)); if (ret > 0) { ret = errcode; switch(ret) { case VZ_NO_ACCES: logger(-1, 0, "Permission denied"); break; case VZ_BAD_KERNEL: logger(-1, 0, "Invalid kernel, or some kernel" " modules are not loaded"); break; case VZ_SET_CAP: logger(-1, 0, "Unable to set capability"); break; case VZ_RESOURCE_ERROR: logger(-1, 0, "Not enough resources" " to start environment"); break; case VZ_WAIT_FAILED: logger(0, 0, "Unable to set" " wait functionality"); break; case VZ_SET_OSRELEASE: logger(-1, 0, "Unable to set osrelease to %s", res->env.osrelease); break; } } err: close(status_p[1]); close(status_p[0]); sigaction(SIGCHLD, &actold, NULL); return ret; }
void check_exp(SymTab *st, Exp* e) { switch(e->tag) { case EXP_INT: e->type = ∭ break; case EXP_FLOAT: e->type = &tfloat; break; case EXP_STRING: e->type = &tstring; break; case EXP_VAR: check_var(st, e->u.var); e->type = (e->u.var)->type; break; case EXP_BINOP: { check_exp(st, e->u.binop.e1); if((e->u.binop.e1)->type->type == TK_TCHAR) insert_conv(&(e->u.binop.e1), TK_TINT); check_exp(st, e->u.binop.e2); if((e->u.binop.e2)->type->type == TK_TCHAR) insert_conv(&(e->u.binop.e2), TK_TINT); switch(e->u.binop.op) { case TK_EQ: case TK_LEQ: case TK_GEQ: case TK_NEQ: case '<': case '>': { check_type_relational(e); break; } case TK_AND: case TK_OR: { check_type_int(e->u.binop.e1); check_type_int(e->u.binop.e2); e->type = ∭ break; } case '+': case '-': case '*': case '/': { check_type_arith(e); break; } default: print_error("Bug in the compiler!", e->line); } break; } case EXP_NEG: { check_exp(st, e->u.exp); if((e->u.exp)->type->type == TK_TCHAR) insert_conv(&(e->u.exp), TK_TINT); if((e->u.exp)->type->dimensions != 0) print_error("cannot negate an array", e->line); e->type = (e->u.exp)->type; break; } case EXP_LNEG: { check_exp(st, e->u.exp); check_type_int(e->u.exp); e->type = ∭ break; } case EXP_FUNCALL: { Declr *func; ExpListNode *eln; DeclrListNode *pln; func = symtab_find(st, e->u.funcall.name); if(!func) print_error("calling undeclared function", e->line); eln = e->u.funcall.expl; pln = func->u.func.params; while(eln) { if(!pln) print_error("excess arguments in function call", e->line); check_exp(st, eln->exp); if(pln->declr != NULL) { check_type_compatible(pln->declr->type, &(eln->exp), e->line); pln = pln->next; } eln = eln->next; } if(pln && pln->declr) print_error("missing arguments in function call", e->line); e->u.funcall.func = func; e->type = func->type; break; } } }
/*---FUNCTION TO ADD VARIABLES IN LEXICON LIST OF VARIABLES---*/ void add_lexicon(char name[],KindType k,float f,char *val) { int count; int i,l; /*IF RUN OUT OF MEMORY,REALLOC*/ if(Lexicon.count == number_of_token) reassign_mem(); //VAL IS NULL => USE IT AS FLOAT VARIABLE if(val == NULL) { count = Lexicon.count; count++; //IF NAME ALREADY THERE,JUST CHANGE ITS VALUE if(check_var(name)==1) { i = get_count(name); Lexicon.Entry[i].info.val=f; Lexicon.Entry[i].str=NULL; } //ELSE ADD A NEW VARIABLE else { i = count; strcpy(Lexicon.Entry[i].name,name); Lexicon.Entry[i].info.val = f; Lexicon.Entry[i].str = NULL; Lexicon.count += 1; } } //ELSE ITS A STRING VARIABLE else { count = Lexicon.count; count++; if(check_var(name)==1) { i = get_count(name); //free(Lexicon.Entry[i].str); l = strlen(val); Lexicon.Entry[i].str = calloc(l+1,sizeof(char)); strcpy(Lexicon.Entry[i].str,val); } else { i = count; strcpy(Lexicon.Entry[i].name,name); Lexicon.Entry[i].kind = k; l = strlen(val); Lexicon.Entry[i].str = calloc(l+1,sizeof(char)); strcpy(Lexicon.Entry[i].str,val); Lexicon.count += 1; } } }
/** Lock container. * Create lock file $dir/$veid.lck. * @param veid CT ID. * @param dir lock directory. * @param status transition status. * @return 0 - success * 1 - locked * -1 - error. */ int vps_lock(envid_t veid, char *dir, char *status) { int fd, pid; char buf[STR_SIZE]; char lockfile[STR_SIZE]; char tmp_file[STR_SIZE]; struct stat st; int retry = 0; int ret = -1; if (check_var(dir, "lockdir is not set")) return -1; if (!stat_file(dir)) if (make_dir(dir, 1)) return -1; /* Create temp lock file */ snprintf(lockfile, sizeof(lockfile), "%s/%d.lck", dir, veid); snprintf(tmp_file, sizeof(tmp_file), "%sXXXXXX", lockfile); if ((fd = mkstemp(tmp_file)) < 0) { if (errno == EROFS) logger(-1, errno, "Unable to create" " lock file %s, use --skiplock option", tmp_file); else logger(-1, errno, "Unable to create" " temporary lock file: %s", tmp_file); return -1; } snprintf(buf, sizeof(buf), "%d\n%s\n", getpid(), status == NULL ? "" : status); write(fd, buf, strlen(buf)); close(fd); while (retry < 3) { /* vps locked */ if (!link(tmp_file, lockfile)) { ret = 0; break; } pid = getlockpid(lockfile); if (pid < 0) { /* Error read pid id */ usleep(500000); retry++; continue; } else if (pid == 0) { /* incorrect pid, remove lock file */ unlink(lockfile); } else { snprintf(buf, sizeof(buf), "/proc/%d", pid); if (!stat(buf, &st)) { ret = 1; break; } else { logger(0, 0, "Removing stale lock" " file %s", lockfile); unlink(lockfile); } } retry++; } unlink(tmp_file); return ret; }
int main(int argc, char *argv[]) { FILE *fout, *fasm, *fhdr = NULL, *frlist; const struct parsed_proto *pp; int no_decorations = 0; char comment_char = '#'; char words[20][256]; char word[256]; char line[256]; char last_sym[32]; unsigned long val; unsigned long cnt; const char *sym; enum dx_type type; char **pub_syms; int pub_sym_cnt = 0; int pub_sym_alloc; char **rlist; int rlist_cnt = 0; int rlist_alloc; int header_mode = 0; int is_ro = 0; int is_label; int is_bss; int wordc; int first; int arg_out; int arg = 1; int len; int w, i; char *p; char *p2; if (argc < 4) { // -nd: no symbol decorations printf("usage:\n%s [-nd] [-i] [-a] <.s> <.asm> <hdrf> [rlist]*\n" "%s -hdr <.h> <.asm>\n", argv[0], argv[0]); return 1; } for (arg = 1; arg < argc; arg++) { if (IS(argv[arg], "-nd")) no_decorations = 1; else if (IS(argv[arg], "-i")) g_cconv_novalidate = 1; else if (IS(argv[arg], "-a")) { comment_char = '@'; g_arm_mode = 1; } else if (IS(argv[arg], "-hdr")) header_mode = 1; else break; } arg_out = arg++; asmfn = argv[arg++]; fasm = fopen(asmfn, "r"); my_assert_not(fasm, NULL); if (!header_mode) { hdrfn = argv[arg++]; fhdr = fopen(hdrfn, "r"); my_assert_not(fhdr, NULL); } fout = fopen(argv[arg_out], "w"); my_assert_not(fout, NULL); pub_sym_alloc = 64; pub_syms = malloc(pub_sym_alloc * sizeof(pub_syms[0])); my_assert_not(pub_syms, NULL); rlist_alloc = 64; rlist = malloc(rlist_alloc * sizeof(rlist[0])); my_assert_not(rlist, NULL); for (; arg < argc; arg++) { frlist = fopen(argv[arg], "r"); my_assert_not(frlist, NULL); while (my_fgets(line, sizeof(line), frlist)) { p = sskip(line); if (*p == 0 || *p == ';') continue; p = next_word(words[0], sizeof(words[0]), p); if (words[0][0] == 0) continue; if (rlist_cnt >= rlist_alloc) { rlist_alloc = rlist_alloc * 2 + 64; rlist = realloc(rlist, rlist_alloc * sizeof(rlist[0])); my_assert_not(rlist, NULL); } rlist[rlist_cnt++] = strdup(words[0]); } fclose(frlist); frlist = NULL; } if (rlist_cnt > 0) qsort(rlist, rlist_cnt, sizeof(rlist[0]), cmpstringp); qsort(unwanted_syms, ARRAY_SIZE(unwanted_syms), sizeof(unwanted_syms[0]), cmpstringp); last_sym[0] = 0; while (1) { next_section(fasm, line); if (feof(fasm)) break; if (IS(line + 1, "text")) continue; if (IS(line + 1, "rdata")) { is_ro = 1; if (!header_mode) fprintf(fout, "\n.section .rodata\n"); } else if (IS(line + 1, "data")) { is_ro = 0; if (!header_mode) fprintf(fout, "\n.data\n"); } else aerr("unhandled section: '%s'\n", line); if (!header_mode) fprintf(fout, ".align %d\n", align_value(4)); while (my_fgets(line, sizeof(line), fasm)) { sym = NULL; asmln++; p = sskip(line); if (*p == 0) continue; if (*p == ';') { if (IS_START(p, ";org") && sscanf(p + 5, "%Xh", &i) == 1) { // ;org is only seen at section start, so assume . addr 0 i &= 0xfff; if (i != 0 && !header_mode) fprintf(fout, "\t\t .skip 0x%x\n", i); } continue; } for (wordc = 0; wordc < ARRAY_SIZE(words); wordc++) { p = sskip(next_word_s(words[wordc], sizeof(words[0]), p)); if (*p == 0 || *p == ';') { wordc++; break; } if (*p == ',') { p = sskip(p + 1); } } if (*p == ';') { p = sskip(p + 1); if (IS_START(p, "sctclrtype")) g_func_sym_pp = NULL; } if (wordc == 2 && IS(words[1], "ends")) break; if (wordc <= 2 && IS(words[0], "end")) break; if (wordc < 2) aerr("unhandled: '%s'\n", words[0]); // don't cares if (IS(words[0], "assume")) continue; if (IS(words[0], "align")) { if (header_mode) continue; val = parse_number(words[1]); fprintf(fout, "\t\t .align %d", align_value(val)); goto fin; } w = 1; type = parse_dx_directive(words[0]); if (type == DXT_UNSPEC) { type = parse_dx_directive(words[1]); sym = words[0]; w = 2; } if (type == DXT_UNSPEC) aerr("unhandled decl: '%s %s'\n", words[0], words[1]); if (sym != NULL) { if (header_mode) { int is_str = 0; fprintf(fout, "extern "); if (is_ro) fprintf(fout, "const "); switch (type) { case DXT_BYTE: for (i = w; i < wordc; i++) if (words[i][0] == '\'') is_str = 1; if (is_str) fprintf(fout, "char %s[];\n", sym); else fprintf(fout, "uint8_t %s;\n", sym); break; case DXT_WORD: fprintf(fout, "uint16_t %s;\n", sym); break; case DXT_DWORD: fprintf(fout, "uint32_t %s;\n", sym); break; default: fprintf(fout, "_UNKNOWN %s;\n", sym); break; } continue; } snprintf(last_sym, sizeof(last_sym), "%s", sym); pp = proto_parse(fhdr, sym, 1); if (pp != NULL) { g_func_sym_pp = NULL; // public/global name if (pub_sym_cnt >= pub_sym_alloc) { pub_sym_alloc *= 2; pub_syms = realloc(pub_syms, pub_sym_alloc * sizeof(pub_syms[0])); my_assert_not(pub_syms, NULL); } pub_syms[pub_sym_cnt++] = strdup(sym); } len = strlen(sym); fprintf(fout, "%s%s:", no_decorations ? "" : "_", sym); len += 2; if (len < 8) fprintf(fout, "\t"); if (len < 16) fprintf(fout, "\t"); if (len <= 16) fprintf(fout, " "); else fprintf(fout, " "); } else { if (header_mode) continue; fprintf(fout, "\t\t "); } // fill out some unwanted strings with zeroes.. if (type == DXT_BYTE && words[w][0] == '\'' && is_unwanted_sym(last_sym)) { len = 0; for (; w < wordc; w++) { if (words[w][0] == '\'') { p = words[w] + 1; for (; *p && *p != '\''; p++) len++; } else { // assume encoded byte len++; } } fprintf(fout, ".skip %d", len); goto fin; } else if (type == DXT_BYTE && (words[w][0] == '\'' || (w + 1 < wordc && words[w + 1][0] == '\''))) { // string; use asciz for most common case if (w == wordc - 2 && IS(words[w + 1], "0")) { fprintf(fout, ".asciz \""); wordc--; } else fprintf(fout, ".ascii \""); for (; w < wordc; w++) { if (words[w][0] == '\'') { p = words[w] + 1; p2 = strchr(p, '\''); if (p2 == NULL) aerr("unterminated string? '%s'\n", p); memcpy(word, p, p2 - p); word[p2 - p] = 0; fprintf(fout, "%s", escape_string(word)); } else { val = parse_number(words[w]); if (val & ~0xff) aerr("bad string trailing byte?\n"); // unfortunately \xHH is unusable - gas interprets // things like \x27b as 0x7b, so have to use octal here fprintf(fout, "\\%03lo", val); } } fprintf(fout, "\""); goto fin; } if (w == wordc - 2) { if (IS_START(words[w + 1], "dup(")) { cnt = parse_number(words[w]); p = words[w + 1] + 4; p2 = strchr(p, ')'); if (p2 == NULL) aerr("bad dup?\n"); memmove(word, p, p2 - p); word[p2 - p] = 0; val = 0; if (!IS(word, "?")) val = parse_number(word); fprintf(fout, ".fill 0x%02lx,%d,0x%02lx", cnt, type_size(type), val); goto fin; } } if (type == DXT_DWORD && words[w][0] == '\'' && words[w][5] == '\'' && strlen(words[w]) == 6) { if (w != wordc - 1) aerr("TODO\n"); p = words[w]; val = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4]; fprintf(fout, ".long 0x%lx", val); snprintf(g_comment, sizeof(g_comment), "%s", words[w]); goto fin; } if (type >= DXT_DWORD && strchr(words[w], '.')) { if (w != wordc - 1) aerr("TODO\n"); if (g_arm_mode && type == DXT_TEN) { fprintf(fout, ".fill 10"); snprintf(g_comment, sizeof(g_comment), "%s %s", type_name_float(type), words[w]); } else fprintf(fout, "%s %s", type_name_float(type), words[w]); goto fin; } first = 1; fprintf(fout, "%s ", type_name(type)); for (; w < wordc; w++) { if (!first) fprintf(fout, ", "); is_label = is_bss = 0; if (w <= wordc - 2 && IS(words[w], "offset")) { is_label = 1; w++; } else if (IS(words[w], "?")) { is_bss = 1; } else if (type == DXT_DWORD && !('0' <= words[w][0] && words[w][0] <= '9')) { // assume label is_label = 1; } if (is_bss) { fprintf(fout, "0"); } else if (is_label) { p = words[w]; if (IS_START(p, "loc_") || IS_START(p, "__imp") || strchr(p, '?') || strchr(p, '@') || bsearch(&p, rlist, rlist_cnt, sizeof(rlist[0]), cmpstringp)) { fprintf(fout, "0"); snprintf(g_comment, sizeof(g_comment), "%s", p); } else { pp = check_var(fhdr, sym, p); if (pp == NULL) { fprintf(fout, "%s%s", (no_decorations || p[0] == '_') ? "" : "_", p); } else { if (no_decorations) fprintf(fout, "%s", pp->name); else output_decorated_pp(fout, pp); } } } else { val = parse_number(words[w]); if (val < 10) fprintf(fout, "%ld", val); else fprintf(fout, "0x%lx", val); } first = 0; } fin: if (g_comment[0] != 0) { fprintf(fout, "\t\t%c %s", comment_char, g_comment); g_comment[0] = 0; } fprintf(fout, "\n"); } } fprintf(fout, "\n"); // dump public syms for (i = 0; i < pub_sym_cnt; i++) fprintf(fout, ".global %s%s\n", no_decorations ? "" : "_", pub_syms[i]); fclose(fout); fclose(fasm); if (fhdr != NULL) fclose(fhdr); return 0; }
static void process_reduction(expr_t* redexpr) { statement_t* stmt; int lineno; char* filename; statement_t* nextstmt; expr_t* assignexpr; expr_t* rhs; expr_t* lhs; int numdims = 0; datatype_t* pdt; char tempvarname[64]; symboltable_t* tempvar; expr_t* tempexpr; statement_t* assignstmt; int complete; expr_t* rhsreg; expr_t* tempreg=NULL; datatype_t* temparrdt; expr_t* dstreg; expr_t* srcreg; expr_t* dstmask; int dstmaskbit; expr_t* srcmask; int srcmaskbit; int staticreg; int try_using_dest_as_temp=1; int using_dest_as_temp=0; char* id; expr_t* tmp; statement_t* newstmt; statement_t* laststmt; int free=0; stmt = T_STMT(redexpr); lineno = T_LINENO(stmt); filename = T_FILENAME(stmt); nextstmt = T_NEXT(stmt); assignexpr = T_EXPR(stmt); if (!T_IS_ASSIGNOP(T_TYPE(assignexpr))) { return; } /* if the assignment is +=, etc. we can't use the dest as the temp storage */ if (T_TYPE(assignexpr) != BIASSIGNMENT) { try_using_dest_as_temp=0; } lhs = T_OPLS(assignexpr); rhs = T_NEXT(lhs); if (rhs != redexpr) { INT_FATAL(stmt,"Unexpected placement of reduction within statement"); } rhs = T_OPLS(rhs); rhsreg = T_TYPEINFO_REG(rhs); if (rhsreg == NULL) { /* if rhsreg is NULL, either the expression is a scalar (which is illegal and will be handled by typechecking), or it's an indexed array of arrays which has not yet had its indices inserted by a2nloops, and therefore evaluates as a scalar array. In this latter case, we search deeply to try and find something that tells the rank. */ numdims = expr_rank(rhs); if (numdims == 0) { free = expr_is_free(rhs); if (!free) { USR_FATAL_CONT(stmt,"Reduce of scalar expression"); return; } } } else { numdims = D_REG_NUM(T_TYPEINFO(rhsreg)); } dstreg = RMSCurrentRegion(); dstmask = RMSCurrentMask(&dstmaskbit); if (T_IDENT(dstreg) == pst_qreg[0]) { /* unresolved quote region */ if (free) { T_IDENT(dstreg) = pst_free; } else { T_IDENT(dstreg) = pst_qreg[numdims]; } } /* save destination region away for later use at codegen time since we will be playing games with scopes */ T_REGMASK2(redexpr) = T_REGION(build_reg_mask_scope(dstreg,NULL,0,NULL, lineno,filename)); complete = (T_REGMASK(redexpr) == NULL); if (complete) { srcreg = dstreg; srcmask = dstmask; srcmaskbit = dstmaskbit; dstreg = NULL; tempreg = NULL; } else { RMSPushScope(T_REGMASK(redexpr)); if (!RMSLegalReduce(stmt,numdims)) { RMSPopScope(T_REGMASK(redexpr)); return; } srcreg = RMSCurrentRegion(); srcmask = RMSCurrentMask(&srcmaskbit); if (T_IDENT(srcreg) == pst_qreg[0]) { /* unresolved quote region */ T_IDENT(srcreg) = pst_qreg[numdims]; } /* build temp region */ tempreg = create_red_reg(numdims,dstreg,srcreg,lineno,filename,&staticreg); RMSPopScope(T_REGMASK(redexpr)); } pdt = T_TYPEINFO(lhs); if (T_SUBTYPE(redexpr) != USER) { pdt = ensure_good_scanred_type(pdt); } if ((try_using_dest_as_temp) && (tempreg == dstreg)) { symboltable_t* lhsroot; datatype_t* lhsensdt; lhsroot = expr_find_root_pst(lhs); lhsensdt = datatype_find_ensemble(S_DTYPE(lhsroot)); if ((tempreg == NULL && lhsensdt == NULL) || (tempreg != NULL && lhsensdt != NULL && expr_equal(D_ENS_REG(lhsensdt), tempreg) && /* must be size of tempreg */ expr_find_ensemble_root(lhs) == lhs)) { /* must be whole array access */ using_dest_as_temp = 1; tempexpr = copy_expr(lhs); } } if (!using_dest_as_temp) { if (complete) { /* build scalar (grid) temp */ sprintf(tempvarname,"_red_data%d",full_red_buff_num++); tempvar = create_named_local_var(pdt,T_PARFCN(stmt),tempvarname); } else { /* build temp array */ sprintf(tempvarname, "_Red_data%d", part_red_buff_num++); temparrdt = build_ensemble_type(pdt,tempreg,0,1,lineno,filename); if (staticreg) { /* make global if we can */ tempvar = LU_INS(tempvarname); S_DTYPE(tempvar) = temparrdt; } else { /* otherwise, make it local */ tempvar = create_named_local_var(temparrdt,T_PARFCN(stmt),tempvarname); S_SETUP(tempvar) = 0; } } /* build expression for the reduction temp */ tempexpr = build_typed_0ary_op(VARIABLE,tempvar); } /* switch reduction argument, tag reduction's rank */ T_OPLS(redexpr) = tempexpr; T_RED_RANK(redexpr) = numdims; tempexpr = copy_expr(tempexpr); if (!using_dest_as_temp) { /* add on blank array references */ while (D_CLASS(pdt) == DT_ARRAY) { tempexpr = build_typed_Nary_op(ARRAY_REF, tempexpr, NULL); T_TYPEINFO_REG(tempexpr) = build_0ary_op(CONSTANT, pstGRID_SCALAR[numdims]); pdt = D_ARR_TYPE(pdt); } } /* build assignment to the reduction temp */ assignstmt = build_ident_expr(redexpr,pdt,tempexpr); /* wrap a scope around it for partial reduction */ if (!complete) { if (using_dest_as_temp) { /* use dest region */ assignstmt = build_reg_mask_scope(dstreg,NULL,MASK_NONE,assignstmt, lineno,filename); /* assignstmt = build_mloop_statement(dstreg, assignstmt, D_REG_NUM(T_TYPEINFO(dstreg)), NULL, MASK_NONE, lineno, filename);*/ } else { /* use temporary region that we created to describe internal temp */ genlist_t* newgls; /* open region scope */ assignstmt = build_reg_mask_scope(tempreg,NULL,MASK_NONE,assignstmt, lineno,filename); /* assignstmt = build_mloop_statement(tempreg, assignstmt, D_REG_NUM(T_TYPEINFO(tempreg)), NULL, MASK_NONE, lineno, filename);*/ if (!staticreg) { newgls = alloc_gen(); G_IDENT(newgls) = tempvar; T_PRE(assignstmt) = newgls; } } } newstmt = assignstmt; /* dbg_gen_stmtls(stdout, newstmt); printf("-------\n"); */ /* setup temp reduction region */ if (!complete && !staticreg && !using_dest_as_temp) { expr_t* fncall; expr_t* argexpr; expr_t* newarg; argexpr = copy_expr(srcreg); newarg = copy_expr(dstreg); T_NEXT(newarg) = argexpr; argexpr = newarg; newarg = copy_expr(tempreg); T_NEXT(newarg) = argexpr; argexpr = newarg; fncall = build_typed_Nary_op(FUNCTION,build_0ary_op(VARIABLE, pstCalcRedReg),argexpr); assignstmt = build_expr_statement(fncall,lineno,filename); insertafter_stmt(newstmt,assignstmt); newstmt = assignstmt; /* dbg_gen_stmtls(stdout, newstmt); printf("-------\n"); */ } /* build local part of reduction */ tempexpr = copy_expr(tempexpr); { expr_t* tmp; tmp = tempexpr; while (tmp) { T_FREE(tmp) = TRUE; tmp = T_OPLS(tmp); } } rhs = copy_exprls(rhs, T_PARENT(rhs)); if (T_SUBTYPE(redexpr) != USER) { assignexpr = build_typed_binary_op(BIOP_GETS, rhs, tempexpr); T_SUBTYPE(assignexpr) = T_SUBTYPE(redexpr); } else { symboltable_t* pst; tmp = rhs; while (T_NEXT(tmp) != NULL) { tmp = T_NEXT(tmp); } T_NEXT(tmp) = copy_expr(tempexpr); id = get_function_name(T_IDENT(redexpr), rhs, 1); if (id == NULL) { USR_FATALX(lineno, filename, "Missing local function for user defined reduction"); } assignexpr = build_typed_Nary_op(FUNCTION, build_0ary_op(VARIABLE, check_var(id)), rhs); pst = lu(id); if (pst != NULL) { subclass sc; symboltable_t* decls; decls = T_DECL(S_FUN_BODY(pst)); while (decls != NULL && S_CLASS(decls) != S_PARAMETER) { decls = S_SIBLING(decls); } while (decls != NULL) { sc = S_PAR_CLASS(decls); decls = S_SIBLING(decls); while (decls != NULL && S_CLASS(decls) != S_PARAMETER) { decls = S_SIBLING(decls); } } if (sc == SC_IN || sc == SC_CONST) { assignexpr = build_typed_binary_op(BIASSIGNMENT, assignexpr, tempexpr); if (!(equiv_datatypes(S_FUN_TYPE(pst), T_TYPEINFO(tempexpr)))) { USR_FATALX(lineno, filename, "local function for user defined reduction returns wrong type"); } } else { if (S_CLASS(S_FUN_TYPE(pst)) != DT_VOID) { USR_FATALX(lineno, filename, "by reference local function for user defined reduction must not return a value"); } } } } assignstmt = build_expr_statement(assignexpr,lineno,filename); if (numdims != 0) { /* don't put mloop around free reduce */ /* assignstmt = build_mloop_statement(srcreg, assignstmt, D_REG_NUM(T_TYPEINFO(srcreg)), srcmask, srcmaskbit, lineno, filename);*/ } insertbefore_stmt(newstmt, assignstmt); /* dbg_gen_stmtls(stdout, newstmt); printf("-------\n"); */ /* create actual reduction statement */ assignstmt = build_expr_statement(redexpr,lineno,filename); insertbefore_stmt(newstmt, assignstmt); /* dbg_gen_stmtls(stdout, newstmt); printf("-------\n"); */ /* wrap a scope around it for partial reduction */ if (!complete) { newstmt = build_reg_mask_scope(srcreg,srcmask,srcmaskbit,newstmt, lineno,filename); } insertbefore_stmt(newstmt,stmt); laststmt = stmt; /* dbg_gen_stmtls(stdout, newstmt); printf("-------\n"); */ if (!using_dest_as_temp) { /* build assignment of reduction result */ tempexpr = copy_expr(tempexpr); lhs = copy_expr(lhs); assignexpr = build_typed_binary_op(BIASSIGNMENT, tempexpr, lhs); assignstmt = build_expr_statement(assignexpr,lineno,filename); if (!complete) { /* assignstmt = build_mloop_statement(dstreg, assignstmt, D_REG_NUM(T_TYPEINFO(dstreg)), dstmask, dstmaskbit, lineno, filename);*/ } if (nextstmt == NULL) { T_NEXT(stmt) = assignstmt; T_PREV(assignstmt) = stmt; T_PARFCN(assignstmt) = T_PARFCN(stmt); } else { insertbefore_stmt(assignstmt,nextstmt); laststmt = nextstmt; } } /* deallocate local array if there was one */ if (!complete && !staticreg && !using_dest_as_temp) { genlist_t* newgls; newgls = alloc_gen(); G_IDENT(newgls) = tempvar; T_POST(assignstmt) = newgls; } /* convert original statement into a simple reduction expression */ /* T_EXPR(stmt) = redexpr;*/ T_PRE(newstmt) = cat_genlist_ls(T_PRE(newstmt), T_PRE(stmt)); T_POST(laststmt) = cat_genlist_ls(T_POST(laststmt), T_POST(stmt)); remove_stmt(stmt); /* for user defined reductions, find or create a global reduction function */ if (T_SUBTYPE(redexpr) == USER) { expr_t* copyexpr; char gfn[256]; statement_t* body; statement_t* comp_stmt; symboltable_t* pst; expr_t* oldarg1; expr_t* newarg1; expr_t* oldarg2; expr_t* newarg2; sprintf(gfn, "_ZPLGLOBALREDUCE_%s", S_IDENT(T_IDENT(redexpr))); pst = lu(gfn); if (pst != NULL) { T_IDENT(redexpr) = pst; } else { symboltable_t* locals; tempexpr = copy_expr(tempexpr); copyexpr = copy_expr(tempexpr); T_NEXT(tempexpr) = copyexpr; id = get_function_name(T_IDENT(redexpr), tempexpr, 1); if (id == NULL) { USR_FATALX(lineno, filename, "Missing global function for user defined reduction"); } pst = lu(id); if (pst == NULL) { USR_FATALX(lineno, filename, "Missing global function for user defined reduction"); } locals = T_DECL(S_FUN_BODY(pst)); oldarg1 = build_typed_0ary_op(VARIABLE, T_DECL(S_FUN_BODY(pst))); oldarg2 = build_typed_0ary_op(VARIABLE, S_SIBLING(T_DECL(S_FUN_BODY(pst)))); body = copy_stmtls(T_STLS(S_FUN_BODY(pst))); pst = insert_function(gfn,pdtVOID,2,T_TYPEINFO(tempexpr),SC_INOUT, T_TYPEINFO(tempexpr),SC_INOUT); S_STD_CONTEXT(pst) = FALSE; if (T_TYPE(body) != S_COMPOUND) { comp_stmt = build_compound_statement( NULL, body, lineno, filename); } else { comp_stmt = body; } S_SIBLING(S_SIBLING(T_DECL(S_FUN_BODY(pst)))) = locals; T_DECL(T_CMPD(comp_stmt)) = T_DECL(S_FUN_BODY(pst)); T_STLS(S_FUN_BODY(pst)) = comp_stmt; fix_stmtls(comp_stmt, NULL, S_FUN_BODY(pst)); newarg1 = build_typed_0ary_op(VARIABLE, T_DECL(S_FUN_BODY(pst))); newarg2 = build_typed_0ary_op(VARIABLE, S_SIBLING(T_DECL(S_FUN_BODY(pst)))); replaceall_stmtls(body, oldarg1, newarg1); replaceall_stmtls(body, oldarg2, newarg2); /* we can do this because we know it is not recursive! */ body = returns2assigns(body, newarg2); T_IDENT(redexpr) = pst; } } }
int main(int argc, char *argv[], char *envp[]) { FILE *fdata; /* .data file (input)*/ FILE *fmodel; /* .model file (output) */ FILE *fauc; /* .model.1st file (output) */ int atnl; /* at newline (flag) */ char *aucname; /* file name of the AUC file */ double baseline; char c; int divider; /* #of bins to divide in this round */ int failures_seen; /* in this bin */ int i, j, k, l; int maxrounds; /* max(@ROUNDS) */ int numbins; /* misnomer, really "this round" */ char *sca0, *sca, *scc; /* tmp variables */ int t; /* XXX - some kind of counter? */ int this_first, this_last; double this_pauc; double randnum; int *rand_seed = NULL; int total_failures; int num_scores; int init_permute_flag = 1; int unknown_meth = REL_ORDER; Score *p; Score *best; double min_auc; gargc = argc; gargv = argv; genvp = envp; /* * Make sure we grok NaNs * (unknown entries in the input file, given as '?', are * stored as not-a-number values) */ if (!isnan(nan(""))) errx(1, "Implementation does not understand NaNs"); /* * PARSE ARGUMENTS */ if (argc < 3) usage(); if ((fdata = fopen(argv[1], "r")) == NULL) err(1, "cannot open %s for reading", argv[1]); if ((fmodel = fopen(argv[2], "w")) == NULL) err(1, "cannot open %s for writing", argv[2]); if ((aucname = (char *)calloc(strlen(argv[2]) + sizeof (".1st"), 1)) == NULL) err(1, "allocating aucname"); strcpy(aucname, argv[2]); strcat(aucname, ".1st"); if ((fauc = fopen(aucname, "w")) == NULL) err(1, "cannot open %s for writing", aucname); argc -= 3; argv += 3; while (argc > 0) { if (!strcmp(argv[0], "rounds") || !strcmp(argv[0], "--rounds")) { if (argc < 2) usage(); if ((sca0 = sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); while (*sca == ',') /* strip leading commas, if any */ sca++; scc = sca + strlen(sca); if (scc == sca) /* must have at least one digit! */ usage(); while (*--scc == ',') /* strip trailing commas */ *scc = '\0'; if (strchr(sca, ',')) { /* * comma-separated list of rounds, parse */ n_rounds = 0; for (scc = sca; *scc; scc++) if (*scc == ',') n_rounds++; n_rounds++; if ((rounds = (int *)calloc(n_rounds, sizeof (*rounds))) == NULL) err(1, "calloc %d rounds", n_rounds); for (i = 0; i < n_rounds; i++) { rounds[i] = strtol(sca, &scc, 10); if (rounds[i] <= 0) errx(1, "round %d must be positive", i); sca = scc + 1; } } else { n_rounds = strtol(sca, NULL, 10); } if (n_rounds <= 0) usage(); argc -= 2; argv += 2; } else if (!strcmp(argv[0], "topk") || !strcmp(argv[0], "--topk")) { if (argc < 2) usage(); if ((sca0 = sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); scc = sca + strlen(sca); if (scc == sca) /* must have at least one digit! */ usage(); topk = strtol(sca, NULL, 10); if (topk <= 0) usage(); argc -= 2; argv += 2; } else if (!strcmp(argv[0], "miss-limit") || !strcmp(argv[0], "--miss-limit")) { if (argc < 2) usage(); if ((sca0 = sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); scc = sca + strlen(sca); if (scc == sca) /* must have at least one digit! */ usage(); unknown_limit = atof(sca); if (unknown_limit < 0 || unknown_limit > 1) usage(); argc -= 2; argv += 2; } else if (!strcmp(argv[0], "--no-prob-dist")) { prob_dist_flag = 0; argc -= 1; argv += 1; } else if (!strcmp(argv[0], "--no-permute") || !strcmp(argv[0], "no-permute")) { init_permute_flag = 0; argc -= 1; argv += 1; } else if (!strcmp(argv[0], "--sort-unknowns") || !strcmp(argv[0], "sort-unknowns")) { if (argc < 2) usage(); if ((sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); unknown_meth = atoi(sca); if (unknown_meth != RAND_ORDER || unknown_meth != REL_ORDER) { usage(); } argc -= 2; argv += 2; } else if (!strcmp(argv[0], "seed") || !strcmp(argv[0], "--seed")) { if (argc < 2) usage(); if ((sca0 = sca = strdup(argv[1])) == NULL) err(1, "strdup: copying %s", argv[1]); scc = sca + strlen(sca); if (scc == sca) { //must have one digit usage(); } if ((rand_seed = (int *) malloc(sizeof(int))) == NULL) err(1, "calloc one integer", 1); *rand_seed = atoi(sca); argc -= 2; argv += 2; } else { /* No other options supported */ usage(); } } /* * if we got a single number as the "rounds" argument, we * interpret it as the list 1,2,...,n */ if (rounds == NULL) { if ((rounds = (int *)calloc(n_rounds, sizeof (*rounds))) == NULL) err(1, "calloc %d rounds", n_rounds); for (i = 0; i < n_rounds; i++) rounds[i] = i+1; } /* * Prep @F and @last */ /* * find the max value in rounds[], * needed for allocating space for failures[][] and last[][] */ for (i = 0, maxrounds = 0; i < n_rounds; i++) if (maxrounds < rounds[i]) maxrounds = rounds[i]; if ((failures = (int **)calloc(n_rounds + 3, sizeof (*failures))) == NULL) err(1, "calloc %d failures", n_rounds); if ((last = (int **)calloc(n_rounds + 3, sizeof (*last))) == NULL) err(1, "calloc %d last", n_rounds); for (i = 0; i <= n_rounds; i++) { if ((failures[i] = (int *)calloc(maxrounds + 3, sizeof (**failures))) == NULL) err(1, "calloc failures[%d]", i); if ((last[i] = (int *)calloc(maxrounds + 3, sizeof (**last))) == NULL) err(1, "calloc last[%d]", i); } /* * COUNT NAMES and IDS */ /* * Start reading the first line, counting fields */ //first check to make sure there is data in the file c = fgetc(fdata); if (c == EOF) { fclose(fdata); err(1, "Error: Data file %s is empty\n", gargv[1]); } n_names = 1; /* at least one! */ /* attributes a comma separated. So count the number of commas in the first line to calculate the number of attributes in the data. */ while (!isnewline(c) && c != EOF) { if (c == ',') n_names++; c = fgetc(fdata); } /* * We've read the first line; let's keep counting lines. * There is some cruftiness in the code in order to deal with * text files with lines ending in \r\n and not just \n */ n_ids = 1; /* we've already read one line! */ atnl = 0; while ((c = fgetc(fdata)) != EOF) if (isnewline(c)) { if (!atnl) { n_ids++; atnl++; } } else { atnl = 0; } fclose(fdata); if ((fdata = fopen(gargv[1], "r")) == NULL) err(1, "cannot open %s for reading", gargv[1]); if ((tabula = (double **)calloc(n_ids, sizeof (*tabula))) == NULL) err(1, "allocating tabula"); for (i = 0; i < n_ids; i++) { if ((tabula[i] = (double *)calloc(n_names, sizeof (**tabula))) == NULL) err(1, "allocating %d-th row of table\n", i); for (j = 0; j < n_names - 1; j++) if (fscanf(fdata, "%lg,", &tabula[i][j]) != 1) { tabula[i][j] = nan(""); while (fgetc(fdata) != ',') ; } fscanf(fdata, "%lg", &tabula[i][j]); /* * XXX - a well-formed file * MUST not have the result * value (last column) be a '?' * DOUBLE_CHECK */ } total_failures = 0; for (i = 0; i < n_ids; i++) total_failures += tabula[i][n_names - 1]; printf("data_file = %s\n", gargv[1]); printf("model = %s\n", gargv[2]); printf("nr rounds = %d\tnr splits=", n_rounds); for (i = 0; i < n_rounds; i++) printf(" %d", rounds[i]); printf("\nnr_examples = %d\ttotal_failures = %d", n_ids, total_failures); printf("\tnr_attribs = %d\n", n_names); // seed random no generator if (rand_seed == NULL) { srand((unsigned)time(NULL)); } else { srand(*rand_seed); //don't need rand_seed anymore... free(rand_seed); rand_seed = NULL; } if ((order = (int *)calloc(n_ids, sizeof (*order))) == NULL) err(1, "calloc %d order", n_ids); if ((sublist_order = (int *)calloc(n_ids, sizeof (*sublist_order))) == NULL) err(1, "calloc %d sublist_order", n_ids); if ((scores = (Score *)calloc(MAX_VARS, sizeof (Score))) == NULL) err(1, "calloc %d scores", MAX_VARS); for (i = 0; i < MAX_VARS; i++) { scores[i].auc = 0; if ((scores[i].order = (int *)calloc(n_ids, sizeof (*(scores[i].order)))) == NULL) err(1, "calloc %d scores[%d].order", n_ids, i); } if ((ignore_set = (int *)calloc(n_names-1, sizeof (*ignore_set))) == NULL) err(1, "calloc %d ignore_set", n_names-1); if ((this_order = (int *)calloc(n_ids, sizeof (*this_order))) == NULL) err(1, "calloc %d this_order", n_ids); if ((best_order = (int *)calloc(n_ids, sizeof (*best_order))) == NULL) err(1, "calloc %d best_order", n_ids); /* randomize initial ordering */ if (init_permute_flag) { for (i = 0; i < n_ids; i++) order[i] = -1; for (i = 0; i < n_ids; i++) { randnum = (double)rand()/((unsigned)RAND_MAX+1); // [0,1) j = (int)(randnum*n_ids); while (order[j] != -1) j = (j + 1) % n_ids; order[j] = i; } } else { for (i = 0; i < n_ids; i++) { order[i] = i; } } /* find variables to ignore */ for (i = 0; i < n_names-1; i++) { ignore_set[i] = 0; if (check_var(i,n_ids, unknown_limit) < 0) ignore_set[i] = 1; } /* iteration over rounds */ for (numbins = 1; numbins <= n_rounds; numbins++) { printf("round = %d\tsplits = %d\n", numbins, rounds[numbins - 1]); t = 0; failures_seen = 0; for (divider = 0; divider < rounds[numbins - 1]; divider++) { while ((failures_seen < ((divider + 1) * (double)total_failures / rounds[numbins - 1])) && (t < n_ids)) { failures_seen += tabula[order[t]][n_names-1]; t++; } last[numbins][divider] = t - 1; failures[numbins][divider] = failures_seen; if (divider == (rounds[numbins - 1] - 1)) failures[numbins][divider+1] = total_failures - failures_seen; } this_first = 0; /* find the first element of the sublist */ /* iteration over bins in this round */ for (j = 0; j < rounds[numbins - 1]; j++) { if (j < rounds[numbins - 1] - 1) this_last = last[numbins][j]; else this_last = n_ids - 1; printf("\tbin %d: [%d..%d] %d failures", j, this_first, this_last, failures[numbins][j] - (j ? failures[numbins][j-1] : 0)); printf("\t(%.12f%%)\n", (this_last - this_first + 1) * 100.0 / n_ids); // ordering from previous round for (k = this_first; k <= this_last; k++) sublist_order[k - this_first] = order[k]; baseline = pauc(sublist_order, this_last - this_first + 1); // reset scores for (k = 1; k < MAX_VARS; k++) scores[k].auc = 0; min_score_ptr = NULL; num_scores = 0; /* iteration over variables for this bin */ for (exti = 0; exti < n_names - 1; exti++) { if (ignore_set[exti]) continue; /* variable ascending */ for (k = this_first; k <= this_last; k++) this_order[k - this_first] = sublist_order[k - this_first]; if (sort_examples((void *)this_order, this_last - this_first + 1, sizeof (*this_order), compasc, unknown_meth) < 0) err(1, "sort_examples this_order ascending"); this_pauc = pauc(this_order, this_last - this_first + 1); if (numbins == 1) fprintf(fauc, "VAR=%d AUC=%f DIR=asc\n", exti, this_pauc); if (this_pauc > baseline) insert_score(scores, &num_scores, exti, "a", this_pauc, this_order, this_last - this_first + 1); /* variable descending */ for (k = this_first; k <= this_last; k++) this_order[k - this_first] = sublist_order[k - this_first]; if (sort_examples((void *)this_order, this_last - this_first + 1, sizeof (*this_order), compdesc, unknown_meth) < 0) err(1, "sort_examples this_order descending"); this_pauc = pauc(this_order, this_last - this_first + 1); if (numbins == 1) fprintf(fauc, "VAR=%d AUC=%f DIR=desc\n", exti, this_pauc); if (this_pauc > baseline) insert_score(scores, &num_scores, exti, "d", this_pauc, this_order, this_last - this_first + 1); } /* end variables loop */ if (num_scores > 0) { // sort scores in desc order of auc if (mergesort((void *)scores, num_scores, sizeof (*scores), comp_auc_desc) < 0) err(1, "mergesort scores descending"); if (prob_dist_flag) { // pick top variable probabilistically // XXX: pick topk vars and compute avg sort auc_to_dist(scores, num_scores); best = weighted_rand(scores, num_scores); } else best = scores; // merge results into main array for (k = this_first; k <= this_last; k++) order[k] = (*best).order[k - this_first]; // update model fprintf(fmodel, "%.12f,%1d,%s", (this_last + 1) / (double) n_ids, best->var, best->dir); fflush(fmodel); } else { fprintf(fmodel, "%.12f,nop", (this_last + 1) / (double) n_ids); fflush(fmodel); } if (j < rounds[numbins - 1] - 1) { fprintf(fmodel, ";"); fflush(fmodel); } this_first = this_last + 1; } /* end bins loop */ fprintf(fmodel, "\n"); fflush(fmodel); printf(" Overall training AUC %.6f\n", pauc(order, n_ids)); } /* end rounds loop */ fclose(fmodel); fclose(fauc); exit(0); }
int check_expr(is_expr* node) { char *typeA, *typeB; int errors = 0; switch (node->type) { case t_expr_var: errors += check_var(node->data.var); if (errors == 0) { node->s_type = duplicate_type_decl(node->data.var->s_type); if (!node->data.var->initialized) { errors++; pretty_error(node->line, "variable used without being initialized"); } } break; case t_expr_new_op: errors += check_new_op(node->data.new_op); if (errors == 0) node->s_type = duplicate_type_decl(node->data.new_op->s_type); break; case t_expr_type_cast: errors += check_expr(node->data.type_cast.expr); errors += check_type_decl(node->data.type_cast.type); if (errors == 0) { if (!type_type_cast_able(node->data.type_cast.type, node->data.type_cast.expr->s_type)) { errors++; typeA = string_type_decl(node->data.type_cast.type); typeB = string_type_decl(node->data.type_cast.expr->s_type); pretty_error(node->line, "invalid typecast from %s to %s", typeA, typeB); free(typeA); free(typeB); } else node->s_type = duplicate_type_decl(node->data.type_cast.type); } break; case t_expr_constant: errors += check_constant(node->data.constant); if (errors == 0) node->s_type = duplicate_type_decl(node->data.constant->s_type); break; case t_expr_func_call: errors += check_func_call(node->data.func_call); if (errors == 0) node->s_type = duplicate_type_decl(node->data.func_call->s_type); break; case t_expr_operation: errors += check_expr_op(node->data.operation); if (errors == 0) node->s_type = duplicate_type_decl(node->data.operation->s_type); break; } return errors; }
void read_config() { FILE *f = NULL; int k; char str[250]; #ifndef WINDOWS char el_ini[256]; DIR *d = NULL; strcpy(configdir, getenv("HOME")); strcat(configdir, "/.elc/"); d=opendir(configdir); if(!d) mkdir(configdir,0755); else { strcpy(el_ini, configdir); strcat(el_ini, "el.ini"); closedir(d); f=fopen(el_ini,"rb"); //try to load local settings } if(!f) //use global settings { strcpy(el_ini, datadir); strcat(el_ini, "el.ini"); f=fopen(el_ini,"rb"); } #else f=fopen("el.ini","rb"); #endif if(!f)//oops, the file doesn't exist, use the defaults { char str[120]; sprintf(str, "Fatal: Can't read el.ini\n"); log_error(str); SDL_Quit(); exit(1); } while(fgets(str,250,f)) { if(str[0]=='#') { check_var(str+1,1);//check only for the long strings } } #ifndef WINDOWS chdir(datadir); #endif if(password_str[0])//We have a password { for(k=0;k<(int)strlen(password_str);k++) display_password_str[k]='*'; display_password_str[k]=0; } else if(username_str[0])//We have a username but not a password... { username_box_selected=0; password_box_selected=1; } fclose(f); }
static statement_t* build_ident_expr(expr_t* redexpr,datatype_t* pdt, expr_t* tempexpr) { char name[256]; char *id; symboltable_t* identpst; expr_t* identexpr; expr_t* assignexpr; statement_t* assignstmt; switch (T_SUBTYPE(redexpr)) { case PLUS: sprintf(name,"_ADD"); break; case TIMES: sprintf(name,"_MULT"); break; case MIN: sprintf(name,"_MIN"); break; case MAX: sprintf(name,"_MAX"); break; case AND: sprintf(name,"_AND"); break; case OR: sprintf(name,"_OR"); break; case BAND: sprintf(name,"_BAND"); break; case BOR: sprintf(name,"_BOR"); break; case BXOR: sprintf(name,"_XOR"); break; case USER: id = get_function_name(T_IDENT(redexpr), NULL, 1); if (id == NULL) { id = get_function_name(T_IDENT(redexpr), tempexpr, 1); identpst = lu(id); if (id == NULL || S_CLASS(S_FUN_TYPE(identpst)) != DT_VOID) { USR_FATALX(T_LINENO(T_STMT(redexpr)), T_FILENAME(T_STMT(redexpr)), "Missing identity function for user defined reduction"); } identexpr = build_Nary_op(FUNCTION, build_0ary_op(VARIABLE, check_var(id)), tempexpr); assignstmt = build_expr_statement(identexpr,T_LINENO(T_STMT(redexpr)),T_FILENAME(T_STMT(redexpr))); return assignstmt; } if (get_function_name(T_IDENT(redexpr), tempexpr, 1)) { USR_FATALX(T_LINENO(T_STMT(redexpr)), T_FILENAME(T_STMT(redexpr)), "Multiple identity functions for user defined reduction"); } identpst = lu(id); if (!(equiv_datatypes(pdt, S_FUN_TYPE(identpst)))) { USR_FATALX(T_LINENO(T_STMT(redexpr)), T_FILENAME(T_STMT(redexpr)), "Identity function for user defined reduction returns wrong type"); } identexpr = build_Nary_op(FUNCTION, build_0ary_op(VARIABLE, check_var(id)), NULL); assignexpr = build_typed_binary_op(BIASSIGNMENT, identexpr, tempexpr); assignstmt = build_expr_statement(assignexpr,T_LINENO(T_STMT(redexpr)),T_FILENAME(T_STMT(redexpr))); return assignstmt; break; default: sprintf(name,"_NOP"); break; } append_sr_pdt(name,pdt); sprintf(name,"%s_IDENTITY",name); identpst = lookup(S_VARIABLE,name); if (identpst == NULL) { INT_FATAL(T_STMT(redexpr),"Couldn't find identity %s\n",name); } identexpr = build_typed_0ary_op(CONSTANT,identpst); assignexpr = build_typed_binary_op(BIASSIGNMENT, identexpr, tempexpr); assignstmt = build_expr_statement(assignexpr,T_LINENO(T_STMT(redexpr)),T_FILENAME(T_STMT(redexpr))); return assignstmt; }
static int _env_create(vps_handler *h, envid_t veid, int wait_p, int err_p, void *data) { struct vzctl_env_create_data env_create_data; struct env_create_param3 create_param; int fd, ret; vps_res *res; char *argv[] = {"init", "-z", " ", NULL}; char *envp[] = {"HOME=/", "TERM=linux", NULL}; res = (vps_res *) data; memset(&create_param, 0, sizeof(create_param)); create_param.iptables_mask = get_ipt_mask(res->env.ipt_mask); logger(3, 0, "Set iptables mask %#10.8llx", (unsigned long long) create_param.iptables_mask); clean_hardlink_dir("/"); if (res->cpu.vcpus != NULL) create_param.total_vcpus = *res->cpu.vcpus; env_create_data.veid = veid; env_create_data.class_id = 0; env_create_data.flags = VE_CREATE | VE_EXCLUSIVE; env_create_data.data = &create_param; env_create_data.datalen = sizeof(create_param); create_param.feature_mask = res->env.features_mask; create_param.known_features = res->env.features_known; /* sysfs enabled by default, unless explicitly disabled */ if (! (res->env.features_known & VE_FEATURE_SYSFS)) { create_param.feature_mask |= VE_FEATURE_SYSFS; create_param.known_features |= VE_FEATURE_SYSFS; } logger(3, 0, "Set features mask %016llx/%016llx", create_param.feature_mask, create_param.known_features); /* Close all fds except stdin. stdin is status pipe */ close(STDERR_FILENO); close(STDOUT_FILENO); close_fds(0, wait_p, err_p, h->vzfd, -1); try: ret = vz_env_create_data_ioctl(h, &env_create_data); if (ret < 0) { switch(errno) { case EINVAL: ret = VZ_ENVCREATE_ERROR; /* Run-time kernel did not understand the * latest create_param -- so retry with * the old env_create_param structs. */ switch (env_create_data.datalen) { case sizeof(struct env_create_param3): env_create_data.datalen = sizeof(struct env_create_param2); goto try; case sizeof(struct env_create_param2): env_create_data.datalen = sizeof(struct env_create_param); goto try; } break; case EACCES: /* License is not loaded */ ret = VZ_NO_ACCES; break; case ENOTTY: /* Some vz modules are not present */ ret = VZ_BAD_KERNEL; break; default: logger(-1, errno, "env_create error"); ret = VZ_ENVCREATE_ERROR; break; } goto env_err; } if (res->env.osrelease != NULL) { ret = vz_env_configure(h->vzfd, veid, res->env.osrelease); if (ret != 0) goto env_err; } close(h->vzfd); /* Create /fastboot to skip run fsck */ fd = open("/fastboot", O_CREAT | O_RDONLY, 0644); close(fd); if (res->misc.wait == YES) { if (add_reach_runlevel_mark()) { ret = VZ_WAIT_FAILED; goto env_err; } } mount("proc", "/proc", "proc", 0, 0); if (stat_file("/sys")) mount("sysfs", "/sys", "sysfs", 0, 0); if (create_param.feature_mask & VE_FEATURE_NFSD) { mount("nfsd", "/proc/fs/nfsd", "nfsd", 0, 0); make_dir("/var/lib/nfs/rpc_pipefs", 1); mount("sunrpc", "/var/lib/nfs/rpc_pipefs", "rpc_pipefs", 0, 0); } configure_sysctl(); if (res->dq.ugidlimit != NULL) mk_quota_link(); /* Close status descriptor to report that * environment is created. */ close(STDIN_FILENO); /* Now we wait until CT setup will be done If no error, then start init, otherwise exit. */ if (read(wait_p, &ret, sizeof(ret)) == 0) return 0; if ((fd = open("/dev/null", O_RDWR)) != -1) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); } logger(10, 0, "Starting init"); execve("/sbin/init", argv, envp); execve("/etc/init", argv, envp); execve("/bin/init", argv, envp); ret = VZ_FS_BAD_TMPL; write(err_p, &ret, sizeof(ret)); env_err: return ret; } static int vz_real_env_create(vps_handler *h, envid_t veid, vps_res *res, int wait_p, int old_wait_p, int err_p, env_create_FN fn, void *data) { int ret, pid; if ((ret = vz_chroot(res->fs.root))) return ret; if ((ret = vz_setluid(veid))) return ret; if ((ret = setup_resource_management(h, veid, res))) return ret; /* Create another process for proper resource accounting */ if ((pid = fork()) < 0) { logger(-1, errno, "Unable to fork"); return VZ_RESOURCE_ERROR; } else if (pid == 0) { if ((ret = vps_set_cap(veid, &res->env, &res->cap))) goto env_err; if (fn == NULL) { ret = _env_create(h, veid, wait_p, err_p, (void *)res); } else { ret = fn(h, veid, wait_p, old_wait_p, err_p, data); } env_err: if (ret) write(STDIN_FILENO, &ret, sizeof(ret)); exit(ret); } return 0; } int vz_env_create(vps_handler *h, envid_t veid, vps_res *res, int wait_p[2], int old_wait_p[2], int err_p[2], env_create_FN fn, void *data) { int ret, pid, errcode; int old_wait_fd; int status_p[2]; struct sigaction act, actold; if (check_var(res->fs.root, "VE_ROOT is not set")) return VZ_VE_ROOT_NOTSET; if (pipe(status_p) < 0) { logger(-1, errno, "Can not create pipe"); return VZ_RESOURCE_ERROR; } sigaction(SIGCHLD, NULL, &actold); sigemptyset(&act.sa_mask); act.sa_handler = SIG_IGN; act.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &act, NULL); get_osrelease(res); if ((pid = fork()) < 0) { logger(-1, errno, "Can not fork"); ret = VZ_RESOURCE_ERROR; goto err; } else if (pid == 0) { dup2(status_p[1], STDIN_FILENO); close(status_p[0]); close(status_p[1]); fcntl(STDIN_FILENO, F_SETFD, FD_CLOEXEC); fcntl(err_p[1], F_SETFD, FD_CLOEXEC); close(err_p[0]); fcntl(wait_p[0], F_SETFD, FD_CLOEXEC); close(wait_p[1]); if (old_wait_p) { fcntl(old_wait_p[0], F_SETFD, FD_CLOEXEC); close(old_wait_p[1]); old_wait_fd = old_wait_p[0]; } else old_wait_fd = -1; ret = vz_real_env_create(h, veid, res, wait_p[0], old_wait_fd, err_p[1], fn, data); if (ret) write(STDIN_FILENO, &ret, sizeof(ret)); exit(ret); } /* Wait for environment created */ close(status_p[1]); close(wait_p[0]); if (old_wait_p) close(old_wait_p[0]); close(err_p[1]); ret = read(status_p[0], &errcode, sizeof(errcode)); if (ret > 0) { ret = errcode; switch(ret) { case VZ_NO_ACCES: logger(-1, 0, "Permission denied"); break; case VZ_BAD_KERNEL: logger(-1, 0, "Invalid kernel, or some kernel" " modules are not loaded"); break; case VZ_SET_CAP: logger(-1, 0, "Unable to set capability"); break; case VZ_RESOURCE_ERROR: logger(-1, 0, "Not enough resources" " to start environment"); break; case VZ_WAIT_FAILED: logger(0, 0, "Unable to set" " wait functionality"); break; case VZ_SET_OSRELEASE: logger(-1, 0, "Unable to set osrelease to %s", res->env.osrelease); break; } } err: close(status_p[1]); close(status_p[0]); sigaction(SIGCHLD, &actold, NULL); return ret; }