static PedExceptionOption do_throw () { PedExceptionOption ex_opt; ped_exception = 1; if (ex_fetch_count) { return PED_EXCEPTION_UNHANDLED; } else { ex_opt = ex_handler (ex); ped_exception_catch (); return ex_opt; } }
/** * Throw an exception. * * You can also use this in a program using libparted. * "message" is a printf-like format string, so you can do * * \code * ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_CANCEL, * "Can't open %s", file_name); * \endcode * * Returns the option selected to resolve the exception. If the exception was * unhandled, PED_EXCEPTION_UNHANDLED is returned. */ PedExceptionOption ped_exception_throw (PedExceptionType ex_type, PedExceptionOption ex_opts, const char* message, ...) { va_list arg_list; int result; static int size = 1000; if (ex) ped_exception_catch (); ex = (PedException*) malloc (sizeof (PedException)); if (!ex) goto no_memory; ex->type = ex_type; ex->options = ex_opts; while (message) { ex->message = (char*) malloc (size * sizeof (char)); if (!ex->message) goto no_memory; va_start (arg_list, message); result = vsnprintf (ex->message, size, message, arg_list); va_end (arg_list); if (result > -1 && result < size) break; size += 10; free (ex->message); } return do_throw (); no_memory: fputs ("Out of memory in exception handler!\n", stderr); va_start (arg_list, message); vfprintf (stderr, message, arg_list); va_end (arg_list); return PED_EXCEPTION_UNHANDLED; }
static int beos_write (PedDevice* dev, const void* buffer, PedSector start, PedSector count) { BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev); int status; PedExceptionOption ex_status; size_t write_length = count * dev->sector_size; PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0); if (dev->read_only) { if (ped_exception_throw ( PED_EXCEPTION_ERROR, PED_EXCEPTION_IGNORE_CANCEL, _("Can't write to %s, because it is opened read-only."), dev->path) != PED_EXCEPTION_IGNORE) return 0; else return 1; } while(1) { if (lseek(arch_specific->fd,start * dev->sector_size,SEEK_SET) == start * dev->sector_size) break; ex_status = ped_exception_throw ( PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL, _("%s during seek for write on %s"), strerror (errno), dev->path); switch (ex_status) { case PED_EXCEPTION_IGNORE: return 1; case PED_EXCEPTION_RETRY: break; case PED_EXCEPTION_UNHANDLED: ped_exception_catch (); case PED_EXCEPTION_CANCEL: return 0; } } #ifdef READ_ONLY printf ("ped_device_write (\"%s\", %p, %d, %d)\n", dev->path, buffer, (int) start, (int) count); #else dev->dirty = 1; while(1) { status = write (arch_specific->fd, buffer, write_length); if (status == count * dev->sector_size) break; if (status > 0) { write_length -= status; buffer += status; continue; } ex_status = ped_exception_throw ( PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL, _("%s during write on %s"), strerror (errno), dev->path); switch (ex_status) { case PED_EXCEPTION_IGNORE: return 1; case PED_EXCEPTION_RETRY: break; case PED_EXCEPTION_UNHANDLED: ped_exception_catch (); case PED_EXCEPTION_CANCEL: return 0; } } #endif /* !READ_ONLY */ return 1; }
/* Return a new store in STORE which contains a remap store of partition PART from the contents of SOURCE; SOURCE is consumed. */ error_t store_part_create (struct store *source, int index, int flags, struct store **store) { static pthread_mutex_t parted_lock = PTHREAD_MUTEX_INITIALIZER; static int version_check; error_t err = 0; PedDevice *dev; PedDisk *disk; PedPartition *part; struct store_run run; if ((source->block_size < PED_SECTOR_SIZE && PED_SECTOR_SIZE % source->block_size != 0) || (source->block_size > PED_SECTOR_SIZE && source->block_size % PED_SECTOR_SIZE != 0)) return EINVAL; pthread_mutex_lock (&parted_lock); /* Since Parted provides no source-level information about version compatibility, we have to check at run time. */ if (version_check == 0) { const char *version = ped_get_version (); version_check = -1; if (version == 0) error (0, 0, "cannot get version of Parted library!"); else if (strverscmp (version, NEED_PARTED_VERSION) < 0) error (0, 0, "Parted library version %s older than needed %s", version, NEED_PARTED_VERSION); else version_check = 1; } if (version_check <= 0) { error (0, 0, "the `part' store type is not available"); pthread_mutex_unlock (&parted_lock); return ENOTSUP; } ped_exception_fetch_all (); dev = ped_device_new_from_store (source); if (! dev) { ped_exception_catch (); err = EIO; goto out; } assert (ped_device_open (dev) != 0); disk = ped_disk_new (dev); if (! disk) { ped_exception_catch (); err = EIO; goto out_with_dev; } for (part = ped_disk_next_partition (disk, NULL); part; part = ped_disk_next_partition (disk, part)) { if (part->type != PED_PARTITION_LOGICAL && part->type != 0 /* PED_PARTITION_PRIMARY */) continue; assert (part->num); if (part->num == index) break; } if (! part) { err = EIO; goto out_with_disk; } if (source->block_size == PED_SECTOR_SIZE) { run.start = part->geom.start; run.length = part->geom.length; } else if (source->block_size < PED_SECTOR_SIZE) { run.start = part->geom.start * (PED_SECTOR_SIZE / source->block_size); run.length = part->geom.length * (PED_SECTOR_SIZE / source->block_size); } else /* source->block_size > PED_SECTOR_SIZE */ { run.start = part->geom.start * PED_SECTOR_SIZE; if (run.start % source->block_size != 0) err = EIO; else { run.start /= source->block_size; run.length = part->geom.length * PED_SECTOR_SIZE; if (run.length % source->block_size != 0) err = EIO; else run.length /= source->block_size; } } out_with_disk: assert (ped_device_close (dev) != 0); ped_disk_destroy (disk); out_with_dev: ped_device_destroy (dev); out: ped_exception_leave_all (); pthread_mutex_unlock (&parted_lock); if (! err) err = store_remap (source, &run, 1, store); return err; }
static int beos_read (const PedDevice* dev, void* buffer, PedSector start, PedSector count) { BEOSSpecific* arch_specific = BEOS_SPECIFIC(dev); int status; PedExceptionOption ex_status; size_t read_length = count * dev->sector_size; PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0); /* First, try to seek */ while(1) { if (lseek(arch_specific->fd, start * dev->sector_size, SEEK_SET) == start * dev->sector_size) break; ex_status = ped_exception_throw ( PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL, _("%s during seek for read on %s"), strerror (errno), dev->path); switch (ex_status) { case PED_EXCEPTION_IGNORE: return 1; case PED_EXCEPTION_RETRY: break /* out of switch */; case PED_EXCEPTION_UNHANDLED: ped_exception_catch (); case PED_EXCEPTION_CANCEL: return 0; } } /* If we seeked ok, now is the time to read */ while (1) { status = read(arch_specific->fd, buffer, read_length); if (status == count * dev->sector_size) break; if (status > 0) { read_length -= status; buffer += status; continue; } ex_status = ped_exception_throw ( PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL, _("%s during read on %s"), strerror (errno), dev->path); switch (ex_status) { case PED_EXCEPTION_IGNORE: return 1; case PED_EXCEPTION_RETRY: break; case PED_EXCEPTION_UNHANDLED: ped_exception_catch (); case PED_EXCEPTION_CANCEL: return 0; } } return 1; }