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