Revision 5dafc53f vl.c

b/vl.c
6198 6198
#define IO_BUF_SIZE 32768
6199 6199

  
6200 6200
struct QEMUFile {
6201
    FILE *outfile;
6202
    BlockDriverState *bs;
6203
    int is_file;
6204
    int is_writable;
6205
    int64_t base_offset;
6201
    QEMUFilePutBufferFunc *put_buffer;
6202
    QEMUFileGetBufferFunc *get_buffer;
6203
    QEMUFileCloseFunc *close;
6204
    QEMUFileRateLimit *rate_limit;
6205
    void *opaque;
6206

  
6206 6207
    int64_t buf_offset; /* start of buffer when writing, end of buffer
6207 6208
                           when reading */
6208 6209
    int buf_index;
......
6210 6211
    uint8_t buf[IO_BUF_SIZE];
6211 6212
};
6212 6213

  
6214
typedef struct QEMUFileFD
6215
{
6216
    int fd;
6217
    QEMUFile *file;
6218
} QEMUFileFD;
6219

  
6220
static void fd_put_notify(void *opaque)
6221
{
6222
    QEMUFileFD *s = opaque;
6223

  
6224
    /* Remove writable callback and do a put notify */
6225
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
6226
    qemu_file_put_notify(s->file);
6227
}
6228

  
6229
static int fd_put_buffer(void *opaque, const uint8_t *buf,
6230
                         int64_t pos, int size)
6231
{
6232
    QEMUFileFD *s = opaque;
6233
    ssize_t len;
6234

  
6235
    do {
6236
        len = write(s->fd, buf, size);
6237
    } while (len == -1 && errno == EINTR);
6238

  
6239
    if (len == -1)
6240
        len = -errno;
6241

  
6242
    /* When the fd becomes writable again, register a callback to do
6243
     * a put notify */
6244
    if (len == -EAGAIN)
6245
        qemu_set_fd_handler2(s->fd, NULL, NULL, fd_put_notify, s);
6246

  
6247
    return len;
6248
}
6249

  
6250
static int fd_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
6251
{
6252
    QEMUFileFD *s = opaque;
6253
    ssize_t len;
6254

  
6255
    do {
6256
        len = read(s->fd, buf, size);
6257
    } while (len == -1 && errno == EINTR);
6258

  
6259
    if (len == -1)
6260
        len = -errno;
6261

  
6262
    return len;
6263
}
6264

  
6265
static int fd_close(void *opaque)
6266
{
6267
    QEMUFileFD *s = opaque;
6268
    qemu_free(s);
6269
    return 0;
6270
}
6271

  
6272
QEMUFile *qemu_fopen_fd(int fd)
6273
{
6274
    QEMUFileFD *s = qemu_mallocz(sizeof(QEMUFileFD));
6275

  
6276
    if (s == NULL)
6277
        return NULL;
6278

  
6279
    s->fd = fd;
6280
    s->file = qemu_fopen_ops(s, fd_put_buffer, fd_get_buffer, fd_close, NULL);
6281
    return s->file;
6282
}
6283

  
6284
typedef struct QEMUFileStdio
6285
{
6286
    FILE *outfile;
6287
} QEMUFileStdio;
6288

  
6289
static void file_put_buffer(void *opaque, const uint8_t *buf,
6290
                            int64_t pos, int size)
6291
{
6292
    QEMUFileStdio *s = opaque;
6293
    fseek(s->outfile, pos, SEEK_SET);
6294
    fwrite(buf, 1, size, s->outfile);
6295
}
6296

  
6297
static int file_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
6298
{
6299
    QEMUFileStdio *s = opaque;
6300
    fseek(s->outfile, pos, SEEK_SET);
6301
    return fread(buf, 1, size, s->outfile);
6302
}
6303

  
6304
static int file_close(void *opaque)
6305
{
6306
    QEMUFileStdio *s = opaque;
6307
    fclose(s->outfile);
6308
    qemu_free(s);
6309
    return 0;
6310
}
6311

  
6213 6312
QEMUFile *qemu_fopen(const char *filename, const char *mode)
6214 6313
{
6215
    QEMUFile *f;
6314
    QEMUFileStdio *s;
6216 6315

  
6217
    f = qemu_mallocz(sizeof(QEMUFile));
6218
    if (!f)
6316
    s = qemu_mallocz(sizeof(QEMUFileStdio));
6317
    if (!s)
6219 6318
        return NULL;
6220
    if (!strcmp(mode, "wb")) {
6221
        f->is_writable = 1;
6222
    } else if (!strcmp(mode, "rb")) {
6223
        f->is_writable = 0;
6224
    } else {
6225
        goto fail;
6226
    }
6227
    f->outfile = fopen(filename, mode);
6228
    if (!f->outfile)
6319

  
6320
    s->outfile = fopen(filename, mode);
6321
    if (!s->outfile)
6229 6322
        goto fail;
6230
    f->is_file = 1;
6231
    return f;
6232
 fail:
6233
    if (f->outfile)
6234
        fclose(f->outfile);
6235
    qemu_free(f);
6323

  
6324
    if (!strcmp(mode, "wb"))
6325
        return qemu_fopen_ops(s, file_put_buffer, NULL, file_close, NULL);
6326
    else if (!strcmp(mode, "rb"))
6327
        return qemu_fopen_ops(s, NULL, file_get_buffer, file_close, NULL);
6328

  
6329
fail:
6330
    if (s->outfile)
6331
        fclose(s->outfile);
6332
    qemu_free(s);
6236 6333
    return NULL;
6237 6334
}
6238 6335

  
6239
static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
6336
typedef struct QEMUFileBdrv
6337
{
6338
    BlockDriverState *bs;
6339
    int64_t base_offset;
6340
} QEMUFileBdrv;
6341

  
6342
static void bdrv_put_buffer(void *opaque, const uint8_t *buf,
6343
                            int64_t pos, int size)
6344
{
6345
    QEMUFileBdrv *s = opaque;
6346
    bdrv_pwrite(s->bs, s->base_offset + pos, buf, size);
6347
}
6348

  
6349
static int bdrv_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
6350
{
6351
    QEMUFileBdrv *s = opaque;
6352
    return bdrv_pread(s->bs, s->base_offset + pos, buf, size);
6353
}
6354

  
6355
static int bdrv_fclose(void *opaque)
6356
{
6357
    QEMUFileBdrv *s = opaque;
6358
    qemu_free(s);
6359
    return 0;
6360
}
6361

  
6362
QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_writable)
6363
{
6364
    QEMUFileBdrv *s;
6365

  
6366
    s = qemu_mallocz(sizeof(QEMUFileBdrv));
6367
    if (!s)
6368
        return NULL;
6369

  
6370
    s->bs = bs;
6371
    s->base_offset = offset;
6372

  
6373
    if (is_writable)
6374
        return qemu_fopen_ops(s, bdrv_put_buffer, NULL, bdrv_fclose, NULL);
6375

  
6376
    return qemu_fopen_ops(s, NULL, bdrv_get_buffer, bdrv_fclose, NULL);
6377
}
6378

  
6379
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
6380
                         QEMUFileGetBufferFunc *get_buffer,
6381
                         QEMUFileCloseFunc *close,
6382
                         QEMUFileRateLimit *rate_limit)
6240 6383
{
6241 6384
    QEMUFile *f;
6242 6385

  
6243 6386
    f = qemu_mallocz(sizeof(QEMUFile));
6244 6387
    if (!f)
6245 6388
        return NULL;
6246
    f->is_file = 0;
6247
    f->bs = bs;
6248
    f->is_writable = is_writable;
6249
    f->base_offset = offset;
6389

  
6390
    f->opaque = opaque;
6391
    f->put_buffer = put_buffer;
6392
    f->get_buffer = get_buffer;
6393
    f->close = close;
6394
    f->rate_limit = rate_limit;
6395

  
6250 6396
    return f;
6251 6397
}
6252 6398

  
6253 6399
void qemu_fflush(QEMUFile *f)
6254 6400
{
6255
    if (!f->is_writable)
6401
    if (!f->put_buffer)
6256 6402
        return;
6403

  
6257 6404
    if (f->buf_index > 0) {
6258
        if (f->is_file) {
6259
            fseek(f->outfile, f->buf_offset, SEEK_SET);
6260
            fwrite(f->buf, 1, f->buf_index, f->outfile);
6261
        } else {
6262
            bdrv_pwrite(f->bs, f->base_offset + f->buf_offset,
6263
                        f->buf, f->buf_index);
6264
        }
6405
        f->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index);
6265 6406
        f->buf_offset += f->buf_index;
6266 6407
        f->buf_index = 0;
6267 6408
    }
......
6271 6412
{
6272 6413
    int len;
6273 6414

  
6274
    if (f->is_writable)
6415
    if (!f->get_buffer)
6275 6416
        return;
6276
    if (f->is_file) {
6277
        fseek(f->outfile, f->buf_offset, SEEK_SET);
6278
        len = fread(f->buf, 1, IO_BUF_SIZE, f->outfile);
6279
        if (len < 0)
6280
            len = 0;
6281
    } else {
6282
        len = bdrv_pread(f->bs, f->base_offset + f->buf_offset,
6283
                         f->buf, IO_BUF_SIZE);
6284
        if (len < 0)
6285
            len = 0;
6286
    }
6417

  
6418
    len = f->get_buffer(f->opaque, f->buf, f->buf_offset, IO_BUF_SIZE);
6419
    if (len < 0)
6420
        len = 0;
6421

  
6287 6422
    f->buf_index = 0;
6288 6423
    f->buf_size = len;
6289 6424
    f->buf_offset += len;
6290 6425
}
6291 6426

  
6292
void qemu_fclose(QEMUFile *f)
6427
int qemu_fclose(QEMUFile *f)
6293 6428
{
6294
    if (f->is_writable)
6295
        qemu_fflush(f);
6296
    if (f->is_file) {
6297
        fclose(f->outfile);
6298
    }
6429
    int ret = 0;
6430
    qemu_fflush(f);
6431
    if (f->close)
6432
        ret = f->close(f->opaque);
6299 6433
    qemu_free(f);
6434
    return ret;
6435
}
6436

  
6437
void qemu_file_put_notify(QEMUFile *f)
6438
{
6439
    f->put_buffer(f->opaque, NULL, 0, 0);
6300 6440
}
6301 6441

  
6302 6442
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
......
6370 6510
        /* SEEK_END not supported */
6371 6511
        return -1;
6372 6512
    }
6373
    if (f->is_writable) {
6513
    if (f->put_buffer) {
6374 6514
        qemu_fflush(f);
6375 6515
        f->buf_offset = pos;
6376 6516
    } else {
......
6381 6521
    return pos;
6382 6522
}
6383 6523

  
6524
int qemu_file_rate_limit(QEMUFile *f)
6525
{
6526
    if (f->rate_limit)
6527
        return f->rate_limit(f->opaque);
6528

  
6529
    return 0;
6530
}
6531

  
6384 6532
void qemu_put_be16(QEMUFile *f, unsigned int v)
6385 6533
{
6386 6534
    qemu_put_byte(f, v >> 8);

Also available in: Unified diff