int msync_f( int argc, char **argv) { off64_t offset; ssize_t length; void *start; int c, flags = 0; size_t blocksize, sectsize; while ((c = getopt(argc, argv, "ais")) != EOF) { switch (c) { case 'a': flags |= MS_ASYNC; break; case 'i': flags |= MS_INVALIDATE; break; case 's': flags |= MS_SYNC; break; default: return command_usage(&msync_cmd); } } if (optind == argc) { offset = mapping->offset; length = mapping->length; } else if (optind == argc - 2) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; length = cvtnum(blocksize, sectsize, argv[optind]); if (length < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } } else { return command_usage(&msync_cmd); } start = check_mapping_range(mapping, offset, length, 1); if (!start) return 0; if (msync(start, length, flags) < 0) perror("msync"); return 0; }
static int extsize_f( int argc, char **argv) { size_t blocksize, sectsize; int c; recurse_all = recurse_dir = 0; init_cvtnum(&blocksize, §size); while ((c = getopt(argc, argv, "DR")) != EOF) { switch (c) { case 'D': recurse_all = 0; recurse_dir = 1; break; case 'R': recurse_all = 1; recurse_dir = 0; break; default: return command_usage(&extsize_cmd); } } if (optind < argc) { extsize = (long)cvtnum(blocksize, sectsize, argv[optind]); if (extsize < 0) { printf(_("non-numeric extsize argument -- %s\n"), argv[optind]); return 0; } } else { extsize = -1; } if (recurse_all || recurse_dir) nftw(file->name, (extsize >= 0) ? set_extsize_callback : get_extsize_callback, 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH); else if (extsize >= 0) set_extsize(file->name, file->fd, extsize); else get_extsize(file->name, file->fd); return 0; }
int mremap_f( int argc, char **argv) { ssize_t new_length; void *new_addr; int flags = 0; int c; size_t blocksize, sectsize; while ((c = getopt(argc, argv, "fm")) != EOF) { switch (c) { case 'f': flags = MREMAP_FIXED|MREMAP_MAYMOVE; break; case 'm': flags = MREMAP_MAYMOVE; break; default: return command_usage(&mremap_cmd); } } init_cvtnum(&blocksize, §size); new_length = cvtnum(blocksize, sectsize, argv[optind]); if (new_length < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } new_addr = mremap(mapping->addr, mapping->length, new_length, flags); if (new_addr == MAP_FAILED) perror("mremap"); else { mapping->addr = new_addr; mapping->length = new_length; } return 0; }
static int truncate_f( int argc, char **argv) { off64_t offset; size_t blocksize, sectsize; init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[1]); if (offset < 0) { printf(_("non-numeric truncate argument -- %s\n"), argv[1]); return 0; } if (ftruncate64(file->fd, offset) < 0) { perror("ftruncate"); return 0; } return 0; }
int madvise_f( int argc, char **argv) { off64_t offset, llength; size_t length; void *start; int advise = MADV_NORMAL, c; size_t blocksize, sectsize; while ((c = getopt(argc, argv, "drsw")) != EOF) { switch (c) { case 'd': /* Don't need these pages */ advise = MADV_DONTNEED; break; case 'r': /* Expect random page references */ advise = MADV_RANDOM; break; case 's': /* Expect sequential page references */ advise = MADV_SEQUENTIAL; break; case 'w': /* Will need these pages */ advise = MADV_WILLNEED; break; default: return command_usage(&madvise_cmd); } } if (optind == argc) { offset = mapping->offset; length = mapping->length; } else if (optind == argc - 2) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; llength = cvtnum(blocksize, sectsize, argv[optind]); if (llength < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } else if (llength > (size_t)llength) { printf(_("length argument too large -- %lld\n"), (long long)llength); return 0; } else length = (size_t)llength; } else { return command_usage(&madvise_cmd); } start = check_mapping_range(mapping, offset, length, 1); if (!start) return 0; if (madvise(start, length, advise) < 0) { perror("madvise"); return 0; } return 0; }
static int pread_f( int argc, char **argv) { size_t bsize; off64_t offset; unsigned int zeed = 0; long long count, total, tmp; size_t fsblocksize, fssectsize; struct timeval t1, t2; char s1[64], s2[64], ts[64]; char *sp; int Cflag, qflag, uflag, vflag; int eof = 0, direction = IO_FORWARD; int c; Cflag = qflag = uflag = vflag = 0; init_cvtnum(&fsblocksize, &fssectsize); bsize = fsblocksize; while ((c = getopt(argc, argv, "b:BCFRquvV:Z:")) != EOF) { switch (c) { case 'b': tmp = cvtnum(fsblocksize, fssectsize, optarg); if (tmp < 0) { printf(_("non-numeric bsize -- %s\n"), optarg); return 0; } bsize = tmp; break; case 'C': Cflag = 1; break; case 'F': direction = IO_FORWARD; break; case 'B': direction = IO_BACKWARD; break; case 'R': direction = IO_RANDOM; break; case 'q': qflag = 1; break; case 'u': uflag = 1; break; case 'v': vflag = 1; break; #ifdef HAVE_PREADV case 'V': vectors = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric vector count == %s\n"), optarg); return 0; } break; #endif case 'Z': zeed = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric seed -- %s\n"), optarg); return 0; } break; default: return command_usage(&pread_cmd); } } if (optind != argc - 2) return command_usage(&pread_cmd); offset = cvtnum(fsblocksize, fssectsize, argv[optind]); if (offset < 0 && (direction & (IO_RANDOM|IO_BACKWARD))) { eof = -1; /* read from EOF */ } else if (offset < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } optind++; count = cvtnum(fsblocksize, fssectsize, argv[optind]); if (count < 0 && (direction & (IO_RANDOM|IO_FORWARD))) { eof = -1; /* read to EOF */ } else if (count < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } if (alloc_buffer(bsize, uflag, 0xabababab) < 0) return 0; gettimeofday(&t1, NULL); switch (direction) { case IO_RANDOM: if (!zeed) /* srandom seed */ zeed = time(NULL); c = read_random(file->fd, offset, count, &total, zeed, eof); break; case IO_FORWARD: c = read_forward(file->fd, offset, count, &total, vflag, 0, eof); if (eof) count = total; break; case IO_BACKWARD: c = read_backward(file->fd, &offset, &count, &total, eof); break; default: ASSERT(0); } if (c < 0) return 0; if (qflag) return 0; gettimeofday(&t2, NULL); t2 = tsub(t2, t1); /* Finally, report back -- -C gives a parsable format */ timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); if (!Cflag) { cvtstr((double)total, s1, sizeof(s1)); cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); printf(_("read %lld/%lld bytes at offset %lld\n"), total, count, (long long)offset); printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), s1, c, ts, s2, tdiv((double)c, t2)); } else {/* bytes,ops,time,bytes/sec,ops/sec */ printf("%lld,%d,%s,%.3f,%.3f\n", total, c, ts, tdiv((double)total, t2), tdiv((double)c, t2)); } return 0; }
static int reflink_f( int argc, char **argv) { off64_t soffset = 0, doffset = 0; long long count = 0, total; char s1[64], s2[64], ts[64]; char *infile = NULL; int Cflag, qflag, wflag, Wflag; struct xfs_ioctl_clone_range_args args; size_t fsblocksize, fssectsize; struct timeval t1, t2; int c, fd = -1; Cflag = qflag = wflag = Wflag = 0; init_cvtnum(&fsblocksize, &fssectsize); while ((c = getopt(argc, argv, "CqwW")) != EOF) { switch (c) { case 'C': Cflag = 1; break; case 'q': qflag = 1; break; case 'w': wflag = 1; break; case 'W': Wflag = 1; break; default: return command_usage(&reflink_cmd); } } if (optind != argc - 4 && optind != argc - 1) return command_usage(&reflink_cmd); infile = argv[optind]; optind++; if (optind == argc) goto clone_all; soffset = cvtnum(fsblocksize, fssectsize, argv[optind]); if (soffset < 0) { printf(_("non-numeric src offset argument -- %s\n"), argv[optind]); return 0; } optind++; doffset = cvtnum(fsblocksize, fssectsize, argv[optind]); if (doffset < 0) { printf(_("non-numeric dest offset argument -- %s\n"), argv[optind]); return 0; } optind++; count = cvtnum(fsblocksize, fssectsize, argv[optind]); if (count < 1) { printf(_("non-positive length argument -- %s\n"), argv[optind]); return 0; } clone_all: c = IO_READONLY; fd = openfile(infile, NULL, c, 0); if (fd < 0) return 0; gettimeofday(&t1, NULL); if (count) { args.src_fd = fd; args.src_offset = soffset; args.src_length = count; args.dest_offset = doffset; c = ioctl(file->fd, XFS_IOC_CLONE_RANGE, &args); } else { c = ioctl(file->fd, XFS_IOC_CLONE, fd); } if (c < 0) { perror(_("reflink")); goto done; } total = count; c = 1; if (Wflag) fsync(file->fd); if (wflag) fdatasync(file->fd); if (qflag) goto done; gettimeofday(&t2, NULL); t2 = tsub(t2, t1); /* Finally, report back -- -C gives a parsable format */ timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); if (!Cflag) { cvtstr((double)total, s1, sizeof(s1)); cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); printf(_("linked %lld/%lld bytes at offset %lld\n"), total, count, (long long)doffset); printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), s1, c, ts, s2, tdiv((double)c, t2)); } else {/* bytes,ops,time,bytes/sec,ops/sec */ printf("%lld,%d,%s,%.3f,%.3f\n", total, c, ts, tdiv((double)total, t2), tdiv((double)c, t2)); } done: close(fd); return 0; }
static int pwrite_f( int argc, char **argv) { size_t bsize; off64_t offset, skip = 0; long long count, total, tmp; unsigned int zeed = 0, seed = 0xcdcdcdcd; size_t fsblocksize, fssectsize; struct timeval t1, t2; char s1[64], s2[64], ts[64]; char *sp, *infile = NULL; int Cflag, qflag, uflag, dflag, wflag, Wflag; int direction = IO_FORWARD; int c, fd = -1; Cflag = qflag = uflag = dflag = wflag = Wflag = 0; init_cvtnum(&fsblocksize, &fssectsize); bsize = fsblocksize; while ((c = getopt(argc, argv, "b:Cdf:i:qs:S:uwWZ:")) != EOF) { switch (c) { case 'b': tmp = cvtnum(fsblocksize, fssectsize, optarg); if (tmp < 0) { printf(_("non-numeric bsize -- %s\n"), optarg); return 0; } bsize = tmp; break; case 'C': Cflag = 1; break; case 'F': direction = IO_FORWARD; break; case 'B': direction = IO_BACKWARD; break; case 'R': direction = IO_RANDOM; break; case 'd': dflag = 1; break; case 'f': case 'i': infile = optarg; break; case 's': skip = cvtnum(fsblocksize, fssectsize, optarg); if (skip < 0) { printf(_("non-numeric skip -- %s\n"), optarg); return 0; } break; case 'S': seed = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric seed -- %s\n"), optarg); return 0; } break; case 'q': qflag = 1; break; case 'u': uflag = 1; break; case 'w': wflag = 1; break; case 'W': Wflag = 1; break; case 'Z': zeed = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric seed -- %s\n"), optarg); return 0; } break; default: return command_usage(&pwrite_cmd); } } if (((skip || dflag) && !infile) || (optind != argc - 2)) return command_usage(&pwrite_cmd); if (infile && direction != IO_FORWARD) return command_usage(&pwrite_cmd); offset = cvtnum(fsblocksize, fssectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; count = cvtnum(fsblocksize, fssectsize, argv[optind]); if (count < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } if (alloc_buffer(bsize, uflag, seed) < 0) return 0; c = IO_READONLY | (dflag ? IO_DIRECT : 0); if (infile && ((fd = openfile(infile, NULL, c, 0)) < 0)) return 0; gettimeofday(&t1, NULL); switch (direction) { case IO_RANDOM: if (!zeed) /* srandom seed */ zeed = time(NULL); c = write_random(offset, count, zeed, &total); break; case IO_FORWARD: c = write_buffer(offset, count, bsize, fd, skip, &total); break; case IO_BACKWARD: c = write_backward(offset, &count, &total); break; default: total = 0; ASSERT(0); } if (c < 0) goto done; if (Wflag) fsync(file->fd); if (wflag) fdatasync(file->fd); if (qflag) goto done; gettimeofday(&t2, NULL); t2 = tsub(t2, t1); /* Finally, report back -- -C gives a parsable format */ timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); if (!Cflag) { cvtstr((double)total, s1, sizeof(s1)); cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); printf(_("wrote %lld/%lld bytes at offset %lld\n"), total, count, (long long)offset); printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), s1, c, ts, s2, tdiv((double)c, t2)); } else {/* bytes,ops,time,bytes/sec,ops/sec */ printf("%lld,%d,%s,%.3f,%.3f\n", total, c, ts, tdiv((double)total, t2), tdiv((double)c, t2)); } done: if (infile) close(fd); return 0; }
static int pread_f( int argc, char **argv) { size_t bsize; off64_t offset; unsigned int zeed = 0; long long count, total, tmp; size_t fsblocksize, fssectsize; struct timeval t1, t2; char *sp; int Cflag, qflag, uflag, vflag; int eof = 0, direction = IO_FORWARD; int c; Cflag = qflag = uflag = vflag = 0; init_cvtnum(&fsblocksize, &fssectsize); bsize = fsblocksize; while ((c = getopt(argc, argv, "b:BCFRquvV:Z:")) != EOF) { switch (c) { case 'b': tmp = cvtnum(fsblocksize, fssectsize, optarg); if (tmp < 0) { printf(_("non-numeric bsize -- %s\n"), optarg); return 0; } bsize = tmp; break; case 'C': Cflag = 1; break; case 'F': direction = IO_FORWARD; break; case 'B': direction = IO_BACKWARD; break; case 'R': direction = IO_RANDOM; break; case 'q': qflag = 1; break; case 'u': uflag = 1; break; case 'v': vflag = 1; break; #ifdef HAVE_PREADV case 'V': vectors = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric vector count == %s\n"), optarg); return 0; } break; #endif case 'Z': zeed = strtoul(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric seed -- %s\n"), optarg); return 0; } break; default: return command_usage(&pread_cmd); } } if (optind != argc - 2) return command_usage(&pread_cmd); offset = cvtnum(fsblocksize, fssectsize, argv[optind]); if (offset < 0 && (direction & (IO_RANDOM|IO_BACKWARD))) { eof = -1; /* read from EOF */ } else if (offset < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } optind++; count = cvtnum(fsblocksize, fssectsize, argv[optind]); if (count < 0 && (direction & (IO_RANDOM|IO_FORWARD))) { eof = -1; /* read to EOF */ } else if (count < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } if (alloc_buffer(bsize, uflag, 0xabababab) < 0) return 0; gettimeofday(&t1, NULL); switch (direction) { case IO_RANDOM: if (!zeed) /* srandom seed */ zeed = time(NULL); c = read_random(file->fd, offset, count, &total, zeed, eof); break; case IO_FORWARD: c = read_forward(file->fd, offset, count, &total, vflag, 0, eof); if (eof) count = total; break; case IO_BACKWARD: c = read_backward(file->fd, &offset, &count, &total, eof); break; default: ASSERT(0); } if (c < 0) return 0; if (qflag) return 0; gettimeofday(&t2, NULL); t2 = tsub(t2, t1); report_io_times("read", &t2, (long long)offset, count, total, c, Cflag); return 0; }
int mincore_f( int argc, char **argv) { off64_t offset, llength; size_t length; size_t blocksize, sectsize; void *start; void *current, *previous; unsigned char *vec; int i; if (argc == 1) { offset = mapping->offset; length = mapping->length; } else if (argc == 3) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[1]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[1]); return 0; } llength = cvtnum(blocksize, sectsize, argv[2]); if (llength < 0) { printf(_("non-numeric length argument -- %s\n"), argv[2]); return 0; } else if (llength > (size_t)llength) { printf(_("length argument too large -- %lld\n"), (long long)llength); return 0; } else length = (size_t)llength; } else { return command_usage(&mincore_cmd); } start = check_mapping_range(mapping, offset, length, 1); if (!start) return 0; vec = calloc(length/pagesize, sizeof(unsigned char)); if (!vec) { perror("calloc"); return 0; } if (mincore(start, length, vec) < 0) { perror("mincore"); free(vec); return 0; } previous = NULL; current = start; for (i = 0; i < length/pagesize; i++, current += pagesize) { if (vec[i]) { if (!previous) { /* print start address */ printf("0x%lx - ", (unsigned long)current); previous = start + (i * pagesize); } } else if (previous) { /* print end and page count */ printf(_("0x%lx %lu pages (%llu : %lu)\n"), (unsigned long)current, (unsigned long)(current - previous) / pagesize, (unsigned long long)offset + (unsigned long long)(previous - start), (unsigned long)(current - previous)); previous = NULL; } } if (previous) printf(_("0x%lx %lu pages (%llu : %lu)\n"), (unsigned long)current, (unsigned long)(current - previous) / pagesize, (unsigned long long)offset + (unsigned long long)(previous - start), (unsigned long)(current - previous)); free(vec); return 0; }
static int sendfile_f( int argc, char **argv) { off64_t offset = 0; long long count, total; size_t blocksize, sectsize; struct timeval t1, t2; char s1[64], s2[64], ts[64]; char *infile = NULL; int Cflag, qflag; int c, fd = -1; Cflag = qflag = 0; init_cvtnum(&blocksize, §size); while ((c = getopt(argc, argv, "Cf:i:q")) != EOF) { switch (c) { case 'C': Cflag = 1; break; case 'q': qflag = 1; break; case 'f': fd = atoi(argv[1]); if (fd < 0 || fd >= filecount) { printf(_("value %d is out of range (0-%d)\n"), fd, filecount-1); return 0; } break; case 'i': infile = optarg; break; default: return command_usage(&sendfile_cmd); } } if (infile && fd != -1) return command_usage(&sendfile_cmd); if (!infile) fd = filetable[fd].fd; else if ((fd = openfile(infile, NULL, IO_READONLY, 0)) < 0) return 0; if (optind == argc - 2) { offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); goto done; } optind++; count = cvtnum(blocksize, sectsize, argv[optind]); if (count < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); goto done; } } else { struct stat64 stat; if (fstat64(fd, &stat) < 0) { perror("fstat64"); goto done; } count = stat.st_size; } gettimeofday(&t1, NULL); c = send_buffer(offset, count, fd, &total); if (c < 0) goto done; if (qflag) goto done; gettimeofday(&t2, NULL); t2 = tsub(t2, t1); /* Finally, report back -- -C gives a parsable format */ timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); if (!Cflag) { cvtstr((double)total, s1, sizeof(s1)); cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); printf(_("sent %lld/%lld bytes from offset %lld\n"), total, count, (long long)offset); printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), s1, c, ts, s2, tdiv((double)c, t2)); } else {/* bytes,ops,time,bytes/sec,ops/sec */ printf("%lld,%d,%s,%.3f,%.3f\n", total, c, ts, tdiv((double)total, t2), tdiv((double)c, t2)); } done: if (infile) close(fd); return 0; }
int mwrite_f( int argc, char **argv) { off64_t offset, tmp; ssize_t length; void *start; char *sp; int seed = 'X'; int rflag = 0; int c; size_t blocksize, sectsize; while ((c = getopt(argc, argv, "rS:")) != EOF) { switch (c) { case 'r': rflag = 1; break; case 'S': seed = (int)strtol(optarg, &sp, 0); if (!sp || sp == optarg) { printf(_("non-numeric seed -- %s\n"), optarg); return 0; } break; default: return command_usage(&mwrite_cmd); } } if (optind == argc) { offset = mapping->offset; length = mapping->length; } else if (optind == argc - 2) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; length = cvtnum(blocksize, sectsize, argv[optind]); if (length < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } } else { return command_usage(&mwrite_cmd); } start = check_mapping_range(mapping, offset, length, 0); if (!start) return 0; offset -= mapping->offset; if (rflag) { for (tmp = offset + length -1; tmp >= offset; tmp--) ((char *)mapping->addr)[tmp] = seed; } else { for (tmp = offset; tmp < offset + length; tmp++) ((char *)mapping->addr)[tmp] = seed; } return 0; }
int mread_f( int argc, char **argv) { off64_t offset, tmp, dumpoffset, printoffset; ssize_t length; size_t dumplen, cnt = 0; char *bp; void *start; int dump = 0, rflag = 0, c; size_t blocksize, sectsize; while ((c = getopt(argc, argv, "frv")) != EOF) { switch (c) { case 'f': dump = 2; /* file offset dump */ break; case 'r': rflag = 1; /* read in reverse */ break; case 'v': dump = 1; /* mapping offset dump */ break; default: return command_usage(&mread_cmd); } } if (optind == argc) { offset = mapping->offset; length = mapping->length; } else if (optind == argc - 2) { init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; length = cvtnum(blocksize, sectsize, argv[optind]); if (length < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } } else { return command_usage(&mread_cmd); } start = check_mapping_range(mapping, offset, length, 0); if (!start) return 0; dumpoffset = offset - mapping->offset; if (dump == 2) printoffset = offset; else printoffset = dumpoffset; if (alloc_buffer(pagesize, 0, 0) < 0) return 0; bp = (char *)buffer; dumplen = length % pagesize; if (!dumplen) dumplen = pagesize; if (rflag) { for (tmp = length - 1, c = 0; tmp >= 0; tmp--, c = 1) { *bp = *(((char *)mapping->addr) + dumpoffset + tmp); cnt++; if (c && cnt == dumplen) { if (dump) { dump_buffer(printoffset, dumplen); printoffset += dumplen; } bp = (char *)buffer; dumplen = pagesize; cnt = 0; } else { bp++; } } } else { for (tmp = 0, c = 0; tmp < length; tmp++, c = 1) { *bp = *(((char *)mapping->addr) + dumpoffset + tmp); cnt++; if (c && cnt == dumplen) { if (dump) dump_buffer(printoffset + tmp - (dumplen - 1), dumplen); bp = (char *)buffer; dumplen = pagesize; cnt = 0; } else { bp++; } } } return 0; }
static int mmap_f( int argc, char **argv) { off64_t offset; ssize_t length; void *address; char *filename; size_t blocksize, sectsize; int c, prot = 0; if (argc == 1) { if (mapping) return maplist_f(); fprintf(stderr, file ? _("no mapped regions, try 'help mmap'\n") : _("no files are open, try 'help open'\n")); return 0; } else if (argc == 2) { if (mapping) return mapset_f(argc, argv); fprintf(stderr, file ? _("no mapped regions, try 'help mmap'\n") : _("no files are open, try 'help open'\n")); return 0; } else if (!file) { fprintf(stderr, _("no files are open, try 'help open'\n")); return 0; } while ((c = getopt(argc, argv, "rwx")) != EOF) { switch (c) { case 'r': prot |= PROT_READ; break; case 'w': prot |= PROT_WRITE; break; case 'x': prot |= PROT_EXEC; break; default: return command_usage(&mmap_cmd); } } if (!prot) prot = PROT_READ | PROT_WRITE | PROT_EXEC; if (optind != argc - 2) return command_usage(&mmap_cmd); init_cvtnum(&blocksize, §size); offset = cvtnum(blocksize, sectsize, argv[optind]); if (offset < 0) { printf(_("non-numeric offset argument -- %s\n"), argv[optind]); return 0; } optind++; length = cvtnum(blocksize, sectsize, argv[optind]); if (length < 0) { printf(_("non-numeric length argument -- %s\n"), argv[optind]); return 0; } filename = strdup(file->name); if (!filename) { perror("strdup"); return 0; } address = mmap(NULL, length, prot, MAP_SHARED, file->fd, offset); if (address == MAP_FAILED) { perror("mmap"); free(filename); return 0; } /* Extend the control array of mmap'd regions */ maptable = (mmap_region_t *)realloc(maptable, /* growing */ ++mapcount * sizeof(mmap_region_t)); if (!maptable) { perror("realloc"); mapcount = 0; munmap(address, length); free(filename); return 0; } /* Finally, make this the new active mapping */ mapping = &maptable[mapcount - 1]; mapping->addr = address; mapping->length = length; mapping->offset = offset; mapping->name = filename; mapping->prot = prot; return 0; }