/* * Copyright (c) 2026 Mirocom Laboratories and MSP engineers. * All Rights Reserved. */ #include #include #include #include #include #include #include "mvm/balloon.h" int balloon_init(struct mvm_balloon *bp, size_t cap) { if (bp == NULL || cap == 0) { errno = EINVAL; return -1; } assert(cap > BALLOON_INIT_SIZE && "cap must be bigger than minimum"); bp->cap = cap; bp->size = BALLOON_INIT_SIZE; bp->data = calloc(bp->size, sizeof(char)); if (bp->data == NULL) { errno = ENOMEM; return -1; } return 0; } int balloon_memcpy(struct mvm_balloon *dest, off_t off, void *source, size_t count) { size_t overflow, newsize; size_t delta; void *p; if (dest == NULL || source == NULL) { errno = EINVAL; return -1; } if (count == 0) { errno = EINVAL; return -1; } /* Compute how far off this will push us */ overflow = off + count; /* If we are overflowing size and have room to expand, do it */ if (overflow >= dest->size && dest->size < dest->cap) { delta = overflow - dest->size; newsize = dest->size + delta; /* Attempt to resize the pool */ if ((p = realloc(dest->data, newsize)) == NULL) { errno = -ENOMEM; return -1; } dest->size = newsize; dest->data = p; } else if (overflow >= dest->cap) { errno = -ENOSPC; return -1; } memcpy((char *)dest->data + off, source, count); return 0; }