1 /*
2 * chunk.c
3 * (C)2001-2011 by Marc Huber <Marc.Huber@web.de>
4 * All rights reserved.
5 *
6 * $Id: chunk.c,v 1.15 2015/03/14 06:11:24 marc Exp marc $
7 *
8 */
9
10 #include "headers.h"
11 #include "misc/sysconf.h"
12
13 static const char rcsid[]
14 __attribute__ ((used)) = "$Id: chunk.c,v 1.15 2015/03/14 06:11:24 marc Exp marc $";
15
chunk_get(struct context * ctx,off_t * offset)16 int chunk_get(struct context *ctx, off_t * offset)
17 {
18 int result = 0;
19 ssize_t len = 0;
20
21 DebugIn(DEBUG_BUFFER);
22
23 Debug((DEBUG_PROC, "remaining is %lu\n", (long unsigned) ctx->remaining));
24 if (ctx->remaining && bufsize > buffer_getlen(ctx->dbufi)) {
25 #ifdef WITH_MMAP
26 if (ctx->iomode == IOMODE_mmap) {
27 struct buffer *b = buffer_get_mmap();
28 if (offset && *offset) {
29 ctx->offset = pagesize * (*offset / pagesize);
30 b->offset = (size_t) (*offset - ctx->offset);
31 ctx->remaining -= *offset;
32 }
33 if (bufsize_mmap)
34 b->length = (size_t) (MIN((off_t) b->offset + ctx->remaining, (off_t) bufsize_mmap));
35 else
36 b->length = (size_t) (b->offset + (off_t) ctx->remaining);
37
38 b->size = b->length;
39
40 b->buf = (char *) mmap(0, b->length, PROT_READ, MAP_SHARED, ctx->ffn, ctx->offset);
41
42 if (b->buf == MAP_FAILED) {
43 if (offset && *offset) {
44 ctx->remaining += ctx->offset;
45 ctx->offset = 0;
46 }
47 if (ctx->iomode_fixed) {
48 logerr("mmap (%s:%d): %s", __FILE__, __LINE__, ctx->filename);
49 ctx->remaining = 0, len = 0, result = -1;
50 } else {
51 ctx->iomode = IOMODE_read, ctx->iomode_fixed = 1;
52 buffer_free_all(b);
53 }
54 } else {
55 if (offset)
56 *offset = 0;
57 ctx->iomode_fixed = 1;
58 ctx->dbufi = buffer_append(ctx->dbufi, b);
59 madvise(b->buf, b->length, MADV_SEQUENTIAL);
60 ctx->remaining -= b->length - b->offset, ctx->offset += b->length;
61 if (!ctx->dbufi || ctx->dbufi->length == 0)
62 result = -1;
63 }
64 }
65 #endif /* WITH_MMAP */
66 if (ctx->iomode == IOMODE_read) {
67 struct buffer *buf = buffer_get();
68 if (offset && *offset) {
69 ctx->offset = lseek(ctx->ffn, *offset, SEEK_SET);
70 ctx->remaining -= *offset;
71 *offset = 0;
72 }
73 len = read(ctx->ffn, buf->buf, (size_t) MIN(ctx->remaining, (off_t) buf->size));
74 if (len <= 0) {
75 if (len < 0)
76 logerr("read (%s:%d): %s", __FILE__, __LINE__, ctx->filename);
77 ctx->remaining = 0, result = -1;
78 buffer_free(buf);
79 } else {
80 ctx->remaining -= len, ctx->offset += len, buf->length = len;
81 ctx->dbufi = buffer_append(ctx->dbufi, buf);
82 }
83 }
84 }
85 if (ctx->dbufi) {
86 ctx->chunk_start = ctx->dbufi->buf + ctx->dbufi->offset;
87 ctx->chunk_length = ctx->dbufi->length - ctx->dbufi->offset;
88 } else {
89 ctx->chunk_start = NULL;
90 ctx->chunk_length = 0;
91 }
92 DebugOut(DEBUG_BUFFER);
93 return result;
94 }
95
chunk_release(struct context * ctx,off_t len)96 int chunk_release(struct context *ctx, off_t len)
97 {
98 DebugIn(DEBUG_BUFFER);
99
100 ctx->dbufi = buffer_release(ctx->dbufi, &len);
101 if (ctx->dbufi) {
102 ctx->chunk_start = ctx->dbufi->buf + ctx->dbufi->offset;
103 ctx->chunk_length = ctx->dbufi->length - ctx->dbufi->offset;
104 } else {
105 ctx->chunk_start = NULL;
106 ctx->chunk_length = 0;
107 }
108 DebugOut(DEBUG_BUFFER);
109 return 0;
110 }
111