/* * open_file() -- open and validate file when registering a file segment. * remember fd in segment struct. */ static int open_file(segment_t *segp) { glctx_t *gcp = &glctx; struct stat stbuf; int fd, flags; if (stat(segp->seg_path, &stbuf) < 0) { int err = errno; fprintf(stderr, "%s: can't stat %s - %s\n", gcp->program_name, segp->seg_path, strerror(err)); free_seg_slot(segp); return SEG_ERR; } /* * TODO: for now, just regular files. later? */ if (!S_ISREG(stbuf.st_mode)) { fprintf(stderr, "%s: %s - is not a regular file\n", gcp->program_name, segp->seg_path); free_seg_slot(segp); return SEG_ERR; } /* * Open file with maximal privileges; adjust segment mapping * protections if permissions don't allow full R/W access. */ if (!access(segp->seg_path, R_OK|W_OK)) flags = O_RDWR; else if (!access(segp->seg_path, R_OK)) { flags = O_RDONLY; segp->seg_prot &= ~PROT_WRITE; } else if (!access(segp->seg_path, W_OK)) { flags = O_WRONLY; segp->seg_prot &= ~PROT_READ; } else { fprintf(stderr, "%s: can't access %s\n", gcp->program_name, segp->seg_path); free_seg_slot(segp); return SEG_ERR; } fd = open(segp->seg_path, flags); if (fd < 0) { int err = errno; fprintf(stderr, "%s: can't open %s - %s\n", gcp->program_name, segp->seg_path, strerror(err)); free_seg_slot(segp); return SEG_ERR; } segp->seg_fd = fd; return SEG_OK; }
/* * called from memtoy "at exit" cleanup(). * primarily to remove any shm segments created. */ void segment_cleanup(struct global_context *gcp) { segment_t *segp, **segpp; segpp = gcp->seglist; if (segpp == NULL) return; for (; (segp = *segpp); ++segpp) { if (segp->seg_type != SEGT_SHM) { continue; } free_seg_slot(segp); /* to remove shared mem */ } }
/* * segment_remove() - remove the specified segment, if exists. */ int segment_remove(char *name) { glctx_t *gcp = &glctx; segment_t *segp; segp = segment_get(name); if (segp == NULL) { fprintf(stderr, "%s: no such segment: %s\n", gcp->program_name, name); return SEG_ERR; } unmap_segment(segp); free_seg_slot(segp); return SEG_OK; }
/* * get_shm_segment() -- create [shmget] a new shared memory segment */ static int get_shm_segment(segment_t * segp) { glctx_t *gcp = &glctx; int shmid; shmid = shmget(IPC_PRIVATE, segp->seg_length, SHM_R | SHM_W); if (shmid == -1) { int err = errno; fprintf(stderr, "%s: failed to get shm segment %s - %s\n", gcp->program_name, segp->seg_name, strerror(err)); free_seg_slot(segp); return SEG_ERR; } segp->seg_shmid = shmid; vprint("%s: shm seg %s id: %d\n", gcp->program_name, segp->seg_name, segp->seg_shmid); return SEG_OK; }