void psi_mesh_destroy(psi_mesh* mesh) { psi_free(mesh->pos); psi_free(mesh->vel); psi_free(mesh->mass); psi_free(mesh->connectivity); }
/** Set the cwd and cwd_status fields of the procinfo structure * * Returns -1 on failure, 0 on success. */ static int set_cwd(struct psi_process *proci, const struct procentry64 *procent) { char *fname; char *link; int r; r = psi_asprintf(&fname, "/proc/%d/cwd", procent->pi_pid); if (r == -1) return -1; r = psi_readlink(&link, fname); psi_free(fname); if (r == -2) { PyErr_Clear(); proci->cwd_status = PSI_STATUS_PRIVS; return 0; } else if (r < 0) { PyErr_Clear(); if (procfs_check_pid(procent->pi_pid) < 0) return -1; else { proci->cwd_status = PSI_STATUS_NA; return 0; } } else { proci->cwd = link; proci->cwd_status = PSI_STATUS_OK; return 0; } }
/** Return list of process environment variables, ending in `\0\0' * * This wraps getevars(3) but allocates the string automatically using * psi_malloc() and guarantees the complete environment is returned. * * Returns -1 in case of an error and -2 if the process is gone. On success * the number of environment variables in the argument list is returned. */ static int mygetevars(struct procentry64 *procent, char **envp) { /* XXX `n' should be `usigned int' and args_sz & i `ssize_t' but getargs() * uses `int' for `args_sz' bizzarly enough. --flub */ char *ptr; int size = 250; /* size of `envp' */ int n; /* number of environment variables */ int r; *envp = (char*)psi_malloc(size); if (*envp == NULL) return -1; r = getevars(procent, sizeof(struct procentry64), *envp, size); if (r < 0) { psi_free(*envp); if (errno == ESRCH) /* proc gone walkies */ return -2; else { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "getevars()"); return -1; } } n = args_complete(*envp, size); while (n < 0) { size += 250; ptr = (char*)psi_realloc(*envp, size); if (ptr == NULL) { psi_free(*envp); return -1; } *envp = ptr; r = getevars(procent, sizeof(struct procentry64), *envp, size); if (r < 0) { psi_free(*envp); if (errno == ESRCH) /* proc gone walkies */ return -2; else { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "getevars()"); return -1; } } n = args_complete(*envp, size); } return n; }
/** Return list of process arguments, ending in `\0\0' * * This wraps getargs(3) but allocates the string automatically using * psi_malloc() and guarantees the complete argument list is returned. * * Returns -1 in case of an error and -2 if the process is gone. On success * the number of arguments in the argument list is returned. */ static int mygetargs(struct procentry64 *procbuff, char **args) { /* XXX nargs should be `usigned int' and args_sz & i `ssize_t' but getargs() * uses int for args_sz bizzarly enough. --flub */ char *ptr; int size = 250; /* size of `args' */ int nargs; int r; *args = (char*)psi_malloc(size); if (*args == NULL) return -1; r = getargs(procbuff, sizeof(struct procentry64), *args, size); if (r < 0) { psi_free(*args); if (errno == ESRCH) /* proc gone walkies */ return -2; else { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "getargs()"); return -1; } } nargs = args_complete(*args, size); while (nargs < 0) { size += 250; ptr = (char*)psi_realloc(*args, size); if (ptr == NULL) { psi_free(*args); return -1; } *args = ptr; r = getargs(procbuff, sizeof(struct procentry64), *args, size); if (r < 0) { psi_free(*args); if (errno == ESRCH) /* proc gone walkies */ return -2; else { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "getargs()"); return -1; } } nargs = args_complete(*args, size); } return nargs; }
static int set_env(struct psi_process *proci, struct procentry64 *procent) { char *envp; proci->envc = mygetevars(procent, &envp); if (proci->envc == -1) return -1; if (proci->envc == -2) { /* proc gone walkies */ proci->envc_status = PSI_STATUS_NA; proci->envv_status = PSI_STATUS_NA; return 0; } proci->envv = psi_strings_to_array(envp, proci->envc); psi_free(envp); if (proci->envv == NULL) return -1; proci->envc_status = PSI_STATUS_OK; proci->envv_status = PSI_STATUS_OK; return 0; }
int load_gadget2(psi_mesh* mesh, const char* filename) { int blksize, p, e, nside, ii, jj, kk, i, j, k; int elemind, locind, vertind; int load_mass; gadget2header header; psi_printf("Loading %s...\n", filename); FILE* f = fopen(filename, "r"); if(!f) { psi_printf("Failed to open %s.\n", filename); return 0; } e = fread(&blksize, sizeof(int), 1, f); e = fread(&header, sizeof(gadget2header), 1, f); e = fread(&blksize, sizeof(int), 1, f); // allocate mesh storage mesh->npart = header.npart[1]; mesh->nelem = header.npart[1]; load_mass = (header.mass[1] == 0); mesh->periodic = 1; mesh->elemtype = PSI_MESH_LINEAR; mesh->dim = 3; for(i = 0; i < 3; ++i) { mesh->box[0].xyz[i] = 0.0; mesh->box[1].xyz[i] = header.BoxSize; } float* tpos = (float*) psi_malloc(mesh->npart*sizeof(psi_rvec)); float* tvel = (float*) psi_malloc(mesh->npart*sizeof(psi_rvec)); int* tid = (int*) psi_malloc(mesh->npart*sizeof(psi_int)); printf("Hubble = %f\n", header.HubbleParam); printf("Box = %f\n", header.BoxSize); printf("load_mass = %d, mass = %f\n", load_mass, header.mass[1]); printf("n_part = %d\n", mesh->npart); // read in position data e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); e = fread(tpos, 3*sizeof(float), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); // read velocities e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); e = fread(tvel, 3*sizeof(float), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); // read ids e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==mesh->npart*sizeof(int)); e = fread(tid, sizeof(int), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==mesh->npart*sizeof(int)); // close the input file fclose(f); // make arrays for vertices // NOTE: assumes the arrays have been malloced! for(p = 0; p < mesh->npart; ++p) { mesh->pos[tid[p]].x = tpos[3*p+0]; mesh->pos[tid[p]].y = tpos[3*p+1]; mesh->pos[tid[p]].z = tpos[3*p+2]; mesh->vel[tid[p]].x = tvel[3*p+0]; mesh->vel[tid[p]].y = tvel[3*p+1]; mesh->vel[tid[p]].z = tvel[3*p+2]; mesh->mass[tid[p]] = header.mass[1]/mesh->npart; } psi_free(tpos); psi_free(tvel); psi_free(tid); // now build the mesh connectivity // trilinear elements naturally nside = floor(pow(mesh->npart+0.5, ONE_THIRD)); for(i = 0; i < nside; ++i) for(j = 0; j < nside; ++j) for(k = 0; k < nside; ++k) { elemind = nside*nside*i + nside*j + k; for(ii = 0; ii < 2; ++ii) for(jj = 0; jj < 2; ++jj) for(kk = 0; kk < 2; ++kk) { locind = 4*ii + 2*jj + kk; vertind = nside*nside*((i+ii)%nside) + nside*((j+jj)%nside) + ((k+kk)%nside); mesh->connectivity[8*elemind+locind] = vertind; } } psi_printf("...done.\n"); return 1; }
int load_gevolution(psi_mesh* mesh, const char* filename) { int blksize, p, e, nside, i, j, k; int elemind, locind, vertind, tile_nside; int load_mass; gadget2header header; psi_printf("Loading %s...\n", filename); FILE* f = fopen(filename, "r"); if(!f) { psi_printf("Failed to open %s.\n", filename); return 0; } e = fread(&blksize, sizeof(int), 1, f); e = fread(&header, sizeof(gadget2header), 1, f); e = fread(&blksize, sizeof(int), 1, f); // allocate mesh storage mesh->npart = header.npart[1]; mesh->nelem = header.npart[1]; load_mass = (header.mass[1] == 0); mesh->periodic = 1; mesh->elemtype = PSI_MESH_LINEAR; mesh->dim = 3; for(i = 0; i < 3; ++i) { mesh->box[0].xyz[i] = 0.0; mesh->box[1].xyz[i] = header.BoxSize; } float* tpos = (float*) psi_malloc(mesh->npart*sizeof(psi_rvec)); float* tvel = (float*) psi_malloc(mesh->npart*sizeof(psi_rvec)); long* tid = (long*) psi_malloc(mesh->npart*sizeof(psi_long)); printf("Hubble = %f\n", header.HubbleParam); printf("Box = %f\n", header.BoxSize); printf("z = %f\n", header.redshift); printf("load_mass = %d, mass = %f\n", load_mass, header.mass[1]); printf("n_part = %d\n", mesh->npart); // read in position data e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); e = fread(tpos, 3*sizeof(float), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); // read velocities e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); e = fread(tvel, 3*sizeof(float), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==3*mesh->npart*sizeof(float)); // read particle ids e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==mesh->npart*sizeof(long)); e = fread(tid, sizeof(long), mesh->npart, f); e = fread(&blksize, sizeof(int), 1, f); psi_assert(blksize==mesh->npart*sizeof(long)); // close the input file fclose(f); // make arrays for vertices // NOTE: assumes the arrays have been malloced! for(p = 0; p < mesh->npart; ++p) { mesh->pos[tid[p]].x = tpos[3*p+0]; mesh->pos[tid[p]].y = tpos[3*p+1]; mesh->pos[tid[p]].z = tpos[3*p+2]; mesh->vel[tid[p]].x = tvel[3*p+0]; mesh->vel[tid[p]].y = tvel[3*p+1]; mesh->vel[tid[p]].z = tvel[3*p+2]; mesh->mass[tid[p]] = header.mass[1]/mesh->npart; } psi_free(tpos); psi_free(tvel); psi_free(tid); // generate the mesh connectivity nside = floor(pow(mesh->npart+0.5, ONE_THIRD)); tile_nside = nside/gevolution_ntile; for(p = 0; p < mesh->npart; ++p) { gevolution_lagrangian_cube_indices(p, tile_nside, &mesh->connectivity[8*p]); } psi_printf("...done.\n"); return 1; }
psi_mountlist_t * psi_arch_mountlist(const int remote) { psi_mountlist_t *ml; psi_mountinfo_t *mounti; struct vmount *mnt; char *vmounts; int vmounts_size = sizeof(struct vmount); int nmounts; int offset = 0; int i; vmounts = psi_malloc(vmounts_size); if (vmounts == NULL) return NULL; nmounts = mntctl(MCTL_QUERY, vmounts_size, vmounts); if (nmounts == 0) { mnt = (struct vmount *)vmounts; vmounts_size = mnt->vmt_revision; psi_free(vmounts); vmounts = psi_malloc(vmounts_size); if (vmounts == NULL) return NULL; nmounts = mntctl(MCTL_QUERY, vmounts_size, vmounts); } if (nmounts == -1) { psi_free(vmounts); PyErr_SetFromErrno(PyExc_OSError); return NULL; } else if (nmounts == 0) { psi_free(vmounts); PyErr_SetString(PyExc_OSError, "Internal race condition"); return NULL; } ml = (psi_mountlist_t *)psi_calloc(sizeof(psi_mountlist_t)); if (ml == NULL) { psi_free(vmounts); return NULL; } ml->mounts = (psi_mountinfo_t **)psi_calloc( nmounts*sizeof(psi_mountinfo_t *)); if (ml->mounts == NULL) { psi_free(vmounts); psi_free(ml); return NULL; } ml->count = 0; for (i = 0; i < nmounts; i++) { mnt = (struct vmount *)(vmounts + offset); if (!remote && strcmp(vmt2dataptr(mnt, VMT_HOST), "-") != 0) continue; mounti = psi_calloc(sizeof(psi_mountinfo_t)); ml->mounts[ml->count] = mounti; ml->count += 1; if (set_vmount(mounti, mnt) < 0) { psi_free(vmounts); psi_free_mountlist(ml); return NULL; } if (posix_set_vfs(mounti) < 0) { psi_free(vmounts); psi_free_mountlist(ml); return NULL; } } return ml; }
/** Find the executable, argument list and environment * * This will also fill in the command attribute. * * The sysctl calls here don't use a wrapper as in darwin_prcesstable.c since * they know the size of the returned structure already. * * The layout of the raw argument space is documented in start.s, which is * part of the Csu project. In summary, it looks like: * * XXX: This layout does not match whith what the code does. The code seems * to think exec_path is in between the first argc and arg[0], also the data * returned by ssyctl() seems to be starting at the first argc according to * the code. * * /---------------\ 0x00000000 * : : * : : * |---------------| * | argc | * |---------------| * | arg[0] | * |---------------| * : : * : : * |---------------| * | arg[argc - 1] | * |---------------| * | 0 | * |---------------| * | env[0] | * |---------------| * : : * : : * |---------------| * | env[n] | * |---------------| * | 0 | * |---------------| <-- Beginning of data returned by sysctl() is here. * | argc | * |---------------| * | exec_path | * |:::::::::::::::| * | | * | String area. | * | | * |---------------| <-- Top of stack. * : : * : : * \---------------/ 0xffffffff */ static int set_exe(struct psi_process *proci, struct kinfo_proc *p) { int mib[3], argmax, nargs; size_t size; char *procargs, *cp; int i; int env_start = 0; /* Get the maximum process arguments size. */ mib[0] = CTL_KERN; mib[1] = KERN_ARGMAX; size = sizeof(argmax); if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) { PyErr_SetFromErrnoWithFilename(PyExc_OSError, "sysctl() argmax"); return -1; } /* Allocate space for the arguments. */ procargs = (char *)psi_malloc(argmax); if (procargs == NULL) return -1; /* Make a sysctl() call to get the raw argument space of the process. */ mib[0] = CTL_KERN; mib[1] = KERN_PROCARGS2; mib[2] = p->kp_proc.p_pid; size = (size_t)argmax; if (sysctl(mib, 3, procargs, &size, NULL, 0) == -1) { /* We failed to get the exe info, but it's not fatal. We probably just * didn't have permission to access the KERN_PROCARGS2 for this * process. */ psi_free(procargs); proci->exe_status = PSI_STATUS_PRIVS; proci->argc_status = PSI_STATUS_PRIVS; proci->argv_status = PSI_STATUS_PRIVS; proci->envc_status = PSI_STATUS_PRIVS; proci->envv_status = PSI_STATUS_PRIVS; proci->command_status = PSI_STATUS_PRIVS; return 0; } memcpy(&nargs, procargs, sizeof(nargs)); cp = procargs + sizeof(nargs); /* Save the exe */ proci->exe = psi_strdup(cp); if (proci->exe == NULL) { psi_free(procargs); return -1; } proci->exe_status = PSI_STATUS_OK; /* Skip over the exe. */ cp += strlen(cp); if (cp == &procargs[size]) { psi_free(procargs); PyErr_SetString(PyExc_OSError, "Did not find args and env"); return -1; } /* Skip trailing '\0' characters. */ for (; cp < &procargs[size]; cp++) { if (*cp != '\0') { /* Beginning of first argument reached. */ break; } } if (cp == &procargs[size]) { psi_free(procargs); /* We dont' have any arguments or environment */ if (nargs == 0) { proci->argc = 0; proci->argc_status = PSI_STATUS_OK; proci->argv = NULL; proci->argv_status = PSI_STATUS_OK; proci->envc = 0; proci->envc_status = PSI_STATUS_OK; proci->envv = NULL; proci->envv_status = PSI_STATUS_OK; /* Update proci->command */ if (command_from_argv(&proci->command, proci->argv, proci->argc) < 0) { psi_free(procargs); return -1; } proci->command_status = PSI_STATUS_OK; return 0; } else { PyErr_SetString(PyExc_OSError, "Did not find args and env"); return -1; } } /* The argument list */ proci->argc = nargs; proci->argc_status = PSI_STATUS_OK; proci->argv = psi_strings_to_array(cp, nargs); if (proci->argv == NULL) { psi_free(procargs); return -1; } proci->argv_status = PSI_STATUS_OK; if (command_from_argv(&proci->command, proci->argv, proci->argc) < 0) { psi_free(procargs); return -1; } proci->command_status = PSI_STATUS_OK; /* The environment */ for (i = 0; i < nargs; i++) { env_start += strlen(proci->argv[i])+1; } env_start--; proci->envc = 0; for (i = 0; ; i++) { if (*(cp+env_start + i) == '\0') { if (*(cp+env_start + i + 1) == '\0') break; else proci->envc++; } } proci->envc_status = PSI_STATUS_OK; proci->envv = psi_strings_to_array(cp+env_start+1, proci->envc); psi_free(procargs); if (proci->envv == NULL) return -1; proci->envv_status = PSI_STATUS_OK; return 0; }