vm: change NO_MEM to a more impossible value
[minix.git] / servers / devman / buf.c
blob88c4c5cd90c36ff49ce8351cee975ee2218b9819
1 /* buf.c - by Alen Stojanov and David van Moolenbroek, taken from procfs */
2 #define _POSIX_SOURCE 1 /* tell headers to include POSIX stuff */
3 #define _MINIX 1 /* tell headers to include MINIX stuff */
4 #define _SYSTEM 1 /* tell headers that this is the kernel */
5 #define DEVMAN_SERVER 1
7 #include <minix/config.h>
8 #include <errno.h>
9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <lib.h>
14 #include <timers.h>
16 #include <minix/callnr.h>
17 #include <minix/type.h>
18 #include <minix/const.h>
19 #include <minix/com.h>
20 #include <minix/syslib.h>
21 #include <minix/sysutil.h>
22 #include <minix/vfsif.h>
23 #include <minix/endpoint.h>
24 #include <minix/sysinfo.h>
25 #include <minix/u64.h>
26 #include <minix/sysinfo.h>
27 #include <minix/type.h>
28 #include <minix/ipc.h>
30 #include <sys/time.h>
31 #include <sys/times.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
35 #include <minix/vtreefs.h>
37 #include <minix/devman.h>
40 #include <stdarg.h>
41 #include <assert.h>
42 #include <string.h>
43 #define BUF_SIZE 4096
45 static char buf[BUF_SIZE + 1];
46 static size_t off, left, used;
47 static off_t skip;
49 #define MIN(x,y) (x<y?x:y)
51 /*===========================================================================*
52 * buf_init *
53 *===========================================================================*/
54 void buf_init(off_t start, size_t len)
56 /* Initialize the buffer for fresh use. The first 'start' bytes of the
57 * produced output are to be skipped. After that, up to a total of
58 * 'len' bytes are requested.
61 skip = start;
62 left = MIN(len, BUF_SIZE);
63 off = 0;
64 used = 0;
67 /*===========================================================================*
68 * buf_printf *
69 *===========================================================================*/
70 void buf_printf(char *fmt, ...)
72 /* Add formatted text to the end of the buffer.
74 va_list args;
75 ssize_t len, max;
77 if (left == 0)
78 return;
80 /* There is no way to estimate how much space the result will take, so
81 * we need to produce the string even when skipping part of the start.
82 * If part of the result is to be skipped, do not memcpy; instead, save
83 * the offset of where the result starts within the buffer.
85 * The null terminating character is not part of the result, so room
86 * must be given for it to be stored after completely filling up the
87 * requested part of the buffer.
89 max = MIN(skip + left, BUF_SIZE);
91 va_start(args, fmt);
92 len = vsnprintf(&buf[off + used], max + 1, fmt, args);
93 va_end(args);
95 if (skip > 0) {
96 assert(off == 0);
97 assert(used == 0);
99 if (skip >= len) {
100 skip -= len;
102 return;
105 off = skip;
106 if (left > BUF_SIZE - off)
107 left = BUF_SIZE - off;
108 len -= off;
109 skip = 0;
112 assert(skip == 0);
113 assert(len >= 0);
114 assert((long) left >= 0);
116 if (len > (ssize_t) left)
117 len = left;
119 used += len;
120 left -= len;
123 /*===========================================================================*
124 * buf_append *
125 *===========================================================================*/
126 void buf_append(char *data, size_t len)
128 /* Add arbitrary data to the end of the buffer.
131 if (left == 0)
132 return;
134 if (skip > 0) {
135 if (skip >= (ssize_t) len) {
136 skip -= len;
138 return;
141 data += skip;
142 len -= skip;
143 skip = 0;
146 if (len > left)
147 len = left;
149 memcpy(&buf[off + used], data, len);
151 used += len;
152 left -= len;
155 /*===========================================================================*
156 * buf_get *
157 *===========================================================================*/
158 size_t buf_get(char **ptr)
160 /* Return the buffer's starting address and the length of the used
161 * part, not counting the trailing null character for the latter.
164 *ptr = &buf[off];
166 return used;