RIOMMapFileObj *r_io_def_mmap_create_new_file(RIO *io, const char *filename, int mode, int flags) { if (!io) { return NULL; } RIOMMapFileObj *mmo = R_NEW0 (RIOMMapFileObj); if (!mmo) { return NULL; } mmo->nocache = !strncmp (filename, "nocache://", 10); if (mmo->nocache) { filename += 10; } mmo->filename = strdup (filename); mmo->mode = mode; mmo->flags = flags; mmo->io_backref = io; if (flags & R_IO_WRITE) { mmo->fd = r_sandbox_open (filename, O_CREAT|O_RDWR, mode); } else { mmo->fd = r_sandbox_open (filename, O_RDONLY, mode); } if (mmo->fd == -1) { free (mmo->filename); free (mmo); return NULL; } if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { mmo->rawio = 1; if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { r_io_def_mmap_free (mmo); mmo = NULL; } } return mmo; }
RIOMMapFileObj *r_io_def_mmap_create_new_file(RIO *io, const char *filename, int mode, int perm) { if (!io) { return NULL; } RIOMMapFileObj *mmo = R_NEW0 (RIOMMapFileObj); if (!mmo) { return NULL; } mmo->nocache = !strncmp (filename, "nocache://", 10); if (mmo->nocache) { filename += 10; } mmo->filename = strdup (filename); mmo->mode = mode; mmo->perm = perm; mmo->io_backref = io; const int posixFlags = (perm & R_PERM_W) ? (perm & R_PERM_CREAT) ? (O_RDWR | O_CREAT) : O_RDWR : O_RDONLY; mmo->fd = r_sandbox_open (filename, posixFlags, mode); if (mmo->fd == -1) { free (mmo->filename); free (mmo); return NULL; } if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { mmo->rawio = 1; if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { r_io_def_mmap_free (mmo); mmo = NULL; } } return mmo; }
RIOMMapFileObj *r_io_def_mmap_create_new_file(RIO *io, const char *filename, int mode, int flags) { RIOMMapFileObj *mmo = NULL; if (!io) return NULL; mmo = R_NEW0 (RIOMMapFileObj); if (!mmo) return NULL; mmo->filename = strdup (filename); mmo->mode = mode; mmo->flags = flags; mmo->io_backref = io; if (flags & R_IO_WRITE) mmo->fd = r_sandbox_open (filename, O_CREAT|O_RDWR, mode); else mmo->fd = r_sandbox_open (filename, O_RDONLY, mode); if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { mmo->rawio = 1; if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { r_io_def_mmap_free (mmo); mmo = NULL; } } return mmo; }
static int r_io_def_mmap_write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { RIOMMapFileObj *mmo; int len = -1; ut64 addr = io->off; if (!fd || !fd->data || !buf) return -1; mmo = fd->data; if (mmo && mmo->buf) { if (!(mmo->flags & R_IO_WRITE)) return -1; if ( (count + addr > mmo->buf->length) || mmo->buf->empty) { ut64 sz = count + addr; r_file_truncate (mmo->filename, sz); } } len = r_file_mmap_write (mmo->filename, io->off, buf, count); if (len != count) { // aim to hack some corner cases? if (lseek (fd->fd, addr, 0) < 0) return -1; len = write (fd->fd, buf, count); } if (!r_io_def_mmap_refresh_def_mmap_buf (mmo) ) { eprintf ("io_def_mmap: failed to refresh the def_mmap backed buffer.\n"); // XXX - not sure what needs to be done here (error handling). } return len; }
static int r_io_def_mmap_truncate(RIOMMapFileObj *mmo, ut64 size) { int res = r_file_truncate (mmo->filename, size); if (res && !r_io_def_mmap_refresh_def_mmap_buf (mmo) ) { eprintf ("r_io_def_mmap_truncate: Error trying to refresh the def_mmap'ed file."); res = false; } else if (!res) eprintf ("r_io_def_mmap_truncate: Error trying to resize the file."); return res; }
RIOMMapFileObj *r_io_def_mmap_create_new_file(RIO *io, const char *filename, int mode, int flags) { RIOMMapFileObj *mmo = NULL; if (!io) return NULL; mmo = R_NEW0 (RIOMMapFileObj); if (!mmo) return NULL; mmo->filename = strdup (filename); mmo->fd = r_num_rand (0xFFFF); // XXX: Use r_io_fd api mmo->mode = mode; mmo->flags = flags; mmo->io_backref = io; if (!r_io_def_mmap_refresh_def_mmap_buf (mmo)) { r_io_def_mmap_free (mmo); mmo = NULL; } return mmo; }
static int r_io_def_mmap_write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { RIOMMapFileObj *mmo; int len = -1; ut64 addr = io->off; if (!fd || !fd->data || !buf) { return -1; } mmo = fd->data; if (!mmo) { return -1; } if (mmo->rawio) { if (fd->obsz) { char *a_buf; int a_count; // only do aligned reads in aligned offsets const int aligned = fd->obsz; //512; // XXX obey fd->obsz? or it may be too slow? 128K.. //ut64 a_off = (io->off >> 9 ) << 9; //- (io->off & aligned); ut64 a_off = io->off - (io->off % aligned); //(io->off >> 9 ) << 9; //- (io->off & aligned); int a_delta = io->off - a_off; if (a_delta < 0) { return -1; } a_count = count + (aligned - (count % aligned)); a_buf = malloc (a_count + aligned); if (a_buf) { int i; memset (a_buf, 0xff, a_count+aligned); for (i = 0; i < a_count; i += aligned) { (void)lseek (mmo->fd, a_off + i, SEEK_SET); (void)read (mmo->fd, a_buf + i, aligned); } memcpy (a_buf+a_delta, buf, count); for (i = 0; i < a_count; i += aligned) { (void)lseek (mmo->fd, a_off + i, SEEK_SET); (void)write (mmo->fd, a_buf + i, aligned); } } free (a_buf); return count; } if (lseek (mmo->fd, addr, 0) < 0) { return -1; } len = write (mmo->fd, buf, count); return len; } if (mmo && mmo->buf) { if (!(mmo->flags & R_IO_WRITE)) return -1; if ( (count + addr > mmo->buf->length) || mmo->buf->empty) { ut64 sz = count + addr; r_file_truncate (mmo->filename, sz); } } len = r_file_mmap_write (mmo->filename, io->off, buf, count); if (len != count) { // aim to hack some corner cases? if (lseek (fd->fd, addr, 0) < 0) { return -1; } len = write (fd->fd, buf, count); } if (!r_io_def_mmap_refresh_def_mmap_buf (mmo) ) { eprintf ("io_def_mmap: failed to refresh the def_mmap backed buffer.\n"); // XXX - not sure what needs to be done here (error handling). } return len; }