]>
Commit | Line | Data |
---|---|---|
30a4f2a8 | 1 | /* |
6a54c60e | 2 | * $Id: disk.cc,v 1.82 1997/10/20 22:59:44 wessels Exp $ |
30a4f2a8 | 3 | * |
4 | * DEBUG: section 6 Disk I/O Routines | |
5 | * AUTHOR: Harvest Derived | |
6 | * | |
42c04c16 | 7 | * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ |
30a4f2a8 | 8 | * -------------------------------------------------------- |
9 | * | |
10 | * Squid is the result of efforts by numerous individuals from the | |
11 | * Internet community. Development is led by Duane Wessels of the | |
12 | * National Laboratory for Applied Network Research and funded by | |
13 | * the National Science Foundation. | |
14 | * | |
15 | * This program is free software; you can redistribute it and/or modify | |
16 | * it under the terms of the GNU General Public License as published by | |
17 | * the Free Software Foundation; either version 2 of the License, or | |
18 | * (at your option) any later version. | |
19 | * | |
20 | * This program is distributed in the hope that it will be useful, | |
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23 | * GNU General Public License for more details. | |
24 | * | |
25 | * You should have received a copy of the GNU General Public License | |
26 | * along with this program; if not, write to the Free Software | |
27 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
28 | * | |
29 | */ | |
30 | ||
31 | /* | |
32 | * Copyright (c) 1994, 1995. All rights reserved. | |
33 | * | |
34 | * The Harvest software was developed by the Internet Research Task | |
35 | * Force Research Group on Resource Discovery (IRTF-RD): | |
36 | * | |
37 | * Mic Bowman of Transarc Corporation. | |
38 | * Peter Danzig of the University of Southern California. | |
39 | * Darren R. Hardy of the University of Colorado at Boulder. | |
40 | * Udi Manber of the University of Arizona. | |
41 | * Michael F. Schwartz of the University of Colorado at Boulder. | |
42 | * Duane Wessels of the University of Colorado at Boulder. | |
43 | * | |
44 | * This copyright notice applies to software in the Harvest | |
45 | * ``src/'' directory only. Users should consult the individual | |
46 | * copyright notices in the ``components/'' subdirectories for | |
47 | * copyright information about other software bundled with the | |
48 | * Harvest source code distribution. | |
49 | * | |
50 | * TERMS OF USE | |
51 | * | |
52 | * The Harvest software may be used and re-distributed without | |
53 | * charge, provided that the software origin and research team are | |
54 | * cited in any use of the system. Most commonly this is | |
55 | * accomplished by including a link to the Harvest Home Page | |
56 | * (http://harvest.cs.colorado.edu/) from the query page of any | |
57 | * Broker you deploy, as well as in the query result pages. These | |
58 | * links are generated automatically by the standard Broker | |
59 | * software distribution. | |
60 | * | |
61 | * The Harvest software is provided ``as is'', without express or | |
62 | * implied warranty, and with no support nor obligation to assist | |
63 | * in its use, correction, modification or enhancement. We assume | |
64 | * no liability with respect to the infringement of copyrights, | |
65 | * trade secrets, or any patents, and are not responsible for | |
66 | * consequential damages. Proper use of the Harvest software is | |
67 | * entirely the responsibility of the user. | |
68 | * | |
69 | * DERIVATIVE WORKS | |
70 | * | |
71 | * Users may make derivative works from the Harvest software, subject | |
72 | * to the following constraints: | |
73 | * | |
74 | * - You must include the above copyright notice and these | |
75 | * accompanying paragraphs in all forms of derivative works, | |
76 | * and any documentation and other materials related to such | |
77 | * distribution and use acknowledge that the software was | |
78 | * developed at the above institutions. | |
79 | * | |
80 | * - You must notify IRTF-RD regarding your distribution of | |
81 | * the derivative work. | |
82 | * | |
83 | * - You must clearly notify users that your are distributing | |
84 | * a modified version and not the original Harvest software. | |
85 | * | |
86 | * - Any derivative product is also subject to these copyright | |
87 | * and use restrictions. | |
88 | * | |
89 | * Note that the Harvest software is NOT in the public domain. We | |
90 | * retain copyright, as specified above. | |
91 | * | |
92 | * HISTORY OF FREE SOFTWARE STATUS | |
93 | * | |
94 | * Originally we required sites to license the software in cases | |
95 | * where they were going to build commercial products/services | |
96 | * around Harvest. In June 1995 we changed this policy. We now | |
97 | * allow people to use the core Harvest software (the code found in | |
98 | * the Harvest ``src/'' directory) for free. We made this change | |
99 | * in the interest of encouraging the widest possible deployment of | |
100 | * the technology. The Harvest software is really a reference | |
101 | * implementation of a set of protocols and formats, some of which | |
102 | * we intend to standardize. We encourage commercial | |
103 | * re-implementations of code complying to this set of standards. | |
104 | */ | |
ed43818f | 105 | |
44a47c6e | 106 | #include "squid.h" |
090089c4 | 107 | |
108 | #define DISK_LINE_LEN 1024 | |
090089c4 | 109 | |
0a0bf5db | 110 | typedef struct disk_ctrl_t { |
111 | int fd; | |
112 | void *data; | |
113 | } disk_ctrl_t; | |
114 | ||
115 | ||
116 | typedef struct open_ctrl_t { | |
f17936ab | 117 | FOCB *callback; |
0a0bf5db | 118 | void *callback_data; |
119 | char *path; | |
120 | } open_ctrl_t; | |
121 | ||
711982d8 | 122 | #if UNUSED_CODE |
090089c4 | 123 | typedef struct _dwalk_ctrl { |
124 | int fd; | |
125 | off_t offset; | |
de866d20 | 126 | int cur_len; |
090089c4 | 127 | char *buf; /* line buffer */ |
582b6456 | 128 | FILE_WALK_HD *handler; |
2318883b | 129 | void *client_data; |
582b6456 | 130 | FILE_WALK_LHD *line_handler; |
2318883b | 131 | void *line_data; |
090089c4 | 132 | } dwalk_ctrl; |
6a54c60e | 133 | |
711982d8 | 134 | #endif |
090089c4 | 135 | |
de866d20 | 136 | static AIOCB diskHandleWriteComplete; |
137 | static AIOCB diskHandleReadComplete; | |
95d15928 | 138 | static PF diskHandleRead; |
139 | static PF diskHandleWrite; | |
0a0bf5db | 140 | static void file_open_complete _PARAMS((void *, int, int)); |
24382924 | 141 | |
711982d8 | 142 | #if UNUSED_CODE |
143 | static AIOCB diskHandleWalkComplete; | |
144 | static PF diskHandleWalk; | |
145 | #endif | |
146 | ||
090089c4 | 147 | /* initialize table */ |
b8d8561b | 148 | int |
0673c0ba | 149 | disk_init(void) |
090089c4 | 150 | { |
090089c4 | 151 | return 0; |
152 | } | |
153 | ||
154 | /* Open a disk file. Return a file descriptor */ | |
684c2720 | 155 | int |
9e4ad609 | 156 | file_open(const char *path, int mode, FOCB * callback, void *callback_data) |
090089c4 | 157 | { |
090089c4 | 158 | int fd; |
0a0bf5db | 159 | open_ctrl_t *ctrlp; |
160 | ||
161 | ctrlp = xmalloc(sizeof(open_ctrl_t)); | |
162 | ctrlp->path = xstrdup(path); | |
163 | ctrlp->callback = callback; | |
164 | ctrlp->callback_data = callback_data; | |
090089c4 | 165 | |
b59c7120 | 166 | if (mode & O_WRONLY) |
167 | mode |= O_APPEND; | |
4f92c80c | 168 | mode |= SQUID_NONBLOCK; |
b59c7120 | 169 | |
090089c4 | 170 | /* Open file */ |
0a0bf5db | 171 | #if USE_ASYNC_IO |
f17936ab | 172 | if (callback != NULL) { |
9e4ad609 | 173 | aioOpen(path, mode, 0644, file_open_complete, ctrlp); |
174 | return DISK_OK; | |
0a0bf5db | 175 | } |
f17936ab | 176 | #endif |
0a0bf5db | 177 | fd = open(path, mode, 0644); |
178 | file_open_complete(ctrlp, fd, errno); | |
179 | if (fd < 0) | |
180 | return DISK_ERROR; | |
181 | return fd; | |
0a0bf5db | 182 | } |
183 | ||
184 | ||
185 | static void | |
95d15928 | 186 | file_open_complete(void *data, int fd, int errcode) |
0a0bf5db | 187 | { |
188 | open_ctrl_t *ctrlp = (open_ctrl_t *) data; | |
76f87348 | 189 | fde *F; |
0a0bf5db | 190 | if (fd < 0) { |
191 | errno = errcode; | |
a3d5953d | 192 | debug(50, 0) ("file_open: error opening file %s: %s\n", ctrlp->path, |
0a0bf5db | 193 | xstrerror()); |
194 | if (ctrlp->callback) | |
195 | (ctrlp->callback) (ctrlp->callback_data, DISK_ERROR); | |
196 | xfree(ctrlp->path); | |
197 | xfree(ctrlp); | |
198 | return; | |
090089c4 | 199 | } |
365e5b34 | 200 | debug(6, 5) ("file_open: FD %d\n", fd); |
3ca60c86 | 201 | commSetCloseOnExec(fd); |
5c5783a2 | 202 | fd_open(fd, FD_FILE, ctrlp->path); |
76f87348 | 203 | F = &fd_table[fd]; |
0a0bf5db | 204 | if (ctrlp->callback) |
205 | (ctrlp->callback) (ctrlp->callback_data, fd); | |
206 | xfree(ctrlp->path); | |
207 | xfree(ctrlp); | |
208 | } | |
209 | ||
090089c4 | 210 | /* close a disk file. */ |
95d15928 | 211 | void |
b8d8561b | 212 | file_close(int fd) |
090089c4 | 213 | { |
76f87348 | 214 | fde *F = &fd_table[fd]; |
f88211e8 | 215 | assert(fd >= 0); |
76f87348 | 216 | assert(F->open); |
217 | if (BIT_TEST(F->flags, FD_WRITE_DAEMON)) { | |
218 | BIT_SET(F->flags, FD_CLOSE_REQUEST); | |
95d15928 | 219 | return; |
fb247d78 | 220 | } |
76f87348 | 221 | if (BIT_TEST(F->flags, FD_WRITE_PENDING)) { |
222 | BIT_SET(F->flags, FD_CLOSE_REQUEST); | |
95d15928 | 223 | return; |
224 | } | |
5c5783a2 | 225 | fd_close(fd); |
365e5b34 | 226 | debug(6, 5) ("file_close: FD %d\n", fd); |
0a0bf5db | 227 | #if USE_ASYNC_IO |
95d15928 | 228 | aioClose(fd); |
0a0bf5db | 229 | #else |
95d15928 | 230 | close(fd); |
0a0bf5db | 231 | #endif |
090089c4 | 232 | } |
233 | ||
090089c4 | 234 | |
235 | /* write handler */ | |
582b6456 | 236 | static void |
95d15928 | 237 | diskHandleWrite(int fd, void *unused) |
090089c4 | 238 | { |
4a86108c | 239 | int len = 0; |
0a0bf5db | 240 | disk_ctrl_t *ctrlp; |
241 | dwrite_q *q = NULL; | |
242 | dwrite_q *wq = NULL; | |
76f87348 | 243 | fde *F = &fd_table[fd]; |
244 | struct _fde_disk *fdd = &F->disk; | |
de866d20 | 245 | if (!fdd->write_q) |
582b6456 | 246 | return; |
0a0bf5db | 247 | /* We need to combine subsequent write requests after the first */ |
de866d20 | 248 | if (fdd->write_q->next != NULL && fdd->write_q->next->next != NULL) { |
249 | len = 0; | |
250 | for (q = fdd->write_q->next; q != NULL; q = q->next) | |
0a0bf5db | 251 | len += q->len - q->cur_offset; |
252 | wq = xcalloc(1, sizeof(dwrite_q)); | |
253 | wq->buf = xmalloc(len); | |
254 | wq->len = 0; | |
255 | wq->cur_offset = 0; | |
256 | wq->next = NULL; | |
257 | wq->free = xfree; | |
258 | do { | |
de866d20 | 259 | q = fdd->write_q->next; |
0a0bf5db | 260 | len = q->len - q->cur_offset; |
de866d20 | 261 | xmemcpy(wq->buf + wq->len, q->buf + q->cur_offset, len); |
0a0bf5db | 262 | wq->len += len; |
de866d20 | 263 | fdd->write_q->next = q->next; |
0a0bf5db | 264 | if (q->free) |
265 | (q->free) (q->buf); | |
266 | safe_free(q); | |
de866d20 | 267 | } while (fdd->write_q->next != NULL); |
268 | fdd->write_q_tail = wq; | |
269 | fdd->write_q->next = wq; | |
0a0bf5db | 270 | } |
271 | ctrlp = xcalloc(1, sizeof(disk_ctrl_t)); | |
272 | ctrlp->fd = fd; | |
8350fe9b | 273 | assert(fdd->write_q != NULL); |
274 | assert(fdd->write_q->len > fdd->write_q->cur_offset); | |
0a0bf5db | 275 | #if USE_ASYNC_IO |
276 | aioWrite(fd, | |
de866d20 | 277 | fdd->write_q->buf + fdd->write_q->cur_offset, |
278 | fdd->write_q->len - fdd->write_q->cur_offset, | |
0a0bf5db | 279 | diskHandleWriteComplete, |
cd1fb0eb | 280 | ctrlp); |
0a0bf5db | 281 | #else |
282 | len = write(fd, | |
de866d20 | 283 | fdd->write_q->buf + fdd->write_q->cur_offset, |
284 | fdd->write_q->len - fdd->write_q->cur_offset); | |
582b6456 | 285 | diskHandleWriteComplete(ctrlp, len, errno); |
0a0bf5db | 286 | #endif |
287 | } | |
288 | ||
de866d20 | 289 | static void |
b69f7771 | 290 | diskHandleWriteComplete(void *data, int len, int errcode) |
0a0bf5db | 291 | { |
292 | disk_ctrl_t *ctrlp = data; | |
0a0bf5db | 293 | int fd = ctrlp->fd; |
76f87348 | 294 | fde *F = &fd_table[fd]; |
295 | struct _fde_disk *fdd = &F->disk; | |
de866d20 | 296 | dwrite_q *q = fdd->write_q; |
297 | int status = DISK_OK; | |
0a0bf5db | 298 | errno = errcode; |
299 | safe_free(data); | |
b69f7771 | 300 | fd_bytes(fd, len, FD_WRITE); |
de866d20 | 301 | if (q == NULL) /* Someone aborted then write completed */ |
302 | return; | |
0a0bf5db | 303 | if (len < 0) { |
304 | if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { | |
de866d20 | 305 | (void) 0; |
0a0bf5db | 306 | } else { |
de866d20 | 307 | status = errno == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR; |
a3d5953d | 308 | debug(50, 1) ("diskHandleWrite: FD %d: disk write error: %s\n", |
0c77d853 | 309 | fd, xstrerror()); |
de866d20 | 310 | if (fdd->wrt_handle == NULL) { |
311 | /* FLUSH PENDING BUFFERS */ | |
312 | do { | |
313 | fdd->write_q = q->next; | |
314 | if (q->free) | |
315 | (q->free) (q->buf); | |
316 | safe_free(q); | |
317 | } while ((q = fdd->write_q)); | |
090089c4 | 318 | } |
0c77d853 | 319 | } |
de866d20 | 320 | len = 0; |
0a0bf5db | 321 | } |
8350fe9b | 322 | if (q != NULL) { |
323 | /* q might become NULL from write failure above */ | |
56878878 | 324 | q->cur_offset += len; |
325 | assert(q->cur_offset <= q->len); | |
326 | if (q->cur_offset == q->len) { | |
327 | /* complete write */ | |
328 | fdd->write_q = q->next; | |
329 | if (q->free) | |
330 | (q->free) (q->buf); | |
331 | safe_free(q); | |
332 | } | |
090089c4 | 333 | } |
de866d20 | 334 | if (fdd->write_q == NULL) { |
335 | /* no more data */ | |
336 | fdd->write_q_tail = NULL; | |
76f87348 | 337 | BIT_RESET(F->flags, FD_WRITE_PENDING); |
338 | BIT_RESET(F->flags, FD_WRITE_DAEMON); | |
de866d20 | 339 | } else { |
0a0bf5db | 340 | /* another block is queued */ |
de866d20 | 341 | commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0); |
76f87348 | 342 | BIT_SET(F->flags, FD_WRITE_DAEMON); |
4a86108c | 343 | } |
de866d20 | 344 | if (fdd->wrt_handle) |
d89d1fb6 | 345 | fdd->wrt_handle(fd, status, len, fdd->wrt_handle_data); |
76f87348 | 346 | if (BIT_TEST(F->flags, FD_CLOSE_REQUEST)) |
b59c7120 | 347 | file_close(fd); |
090089c4 | 348 | } |
349 | ||
350 | ||
090089c4 | 351 | /* write block to a file */ |
352 | /* write back queue. Only one writer at a time. */ | |
353 | /* call a handle when writing is complete. */ | |
b8d8561b | 354 | int |
3ebcfaa1 | 355 | file_write(int fd, |
684c2720 | 356 | char *ptr_to_buf, |
357 | int len, | |
d89d1fb6 | 358 | DWCB handle, |
684c2720 | 359 | void *handle_data, |
9e4ad609 | 360 | FREE * free_func) |
090089c4 | 361 | { |
c6ac7aae | 362 | dwrite_q *wq = NULL; |
76f87348 | 363 | fde *F; |
e7a22b88 | 364 | if (fd < 0) |
365 | fatal_dump("file_write: bad FD"); | |
76f87348 | 366 | F = &fd_table[fd]; |
367 | if (!F->open) { | |
429fdbec | 368 | debug_trap("file_write: FILE_NOT_OPEN"); |
090089c4 | 369 | return DISK_ERROR; |
429fdbec | 370 | } |
090089c4 | 371 | /* if we got here. Caller is eligible to write. */ |
30a4f2a8 | 372 | wq = xcalloc(1, sizeof(dwrite_q)); |
090089c4 | 373 | wq->buf = ptr_to_buf; |
090089c4 | 374 | wq->len = len; |
375 | wq->cur_offset = 0; | |
376 | wq->next = NULL; | |
86ee2017 | 377 | wq->free = free_func; |
76f87348 | 378 | F->disk.wrt_handle = handle; |
379 | F->disk.wrt_handle_data = handle_data; | |
090089c4 | 380 | |
381 | /* add to queue */ | |
76f87348 | 382 | BIT_SET(F->flags, FD_WRITE_PENDING); |
383 | if (!(F->disk.write_q)) { | |
090089c4 | 384 | /* empty queue */ |
76f87348 | 385 | F->disk.write_q = F->disk.write_q_tail = wq; |
090089c4 | 386 | } else { |
76f87348 | 387 | F->disk.write_q_tail->next = wq; |
388 | F->disk.write_q_tail = wq; | |
090089c4 | 389 | } |
390 | ||
76f87348 | 391 | if (!BIT_TEST(F->flags, FD_WRITE_DAEMON)) { |
0a0bf5db | 392 | #if USE_ASYNC_IO |
95d15928 | 393 | diskHandleWrite(fd, NULL); |
0a0bf5db | 394 | #else |
95d15928 | 395 | commSetSelect(fd, COMM_SELECT_WRITE, diskHandleWrite, NULL, 0); |
0a0bf5db | 396 | #endif |
76f87348 | 397 | BIT_SET(F->flags, FD_WRITE_DAEMON); |
429fdbec | 398 | } |
090089c4 | 399 | return DISK_OK; |
400 | } | |
401 | ||
402 | ||
403 | ||
404 | /* Read from FD */ | |
582b6456 | 405 | static void |
406 | diskHandleRead(int fd, void *data) | |
090089c4 | 407 | { |
582b6456 | 408 | dread_ctrl *ctrl_dat = data; |
711982d8 | 409 | fde *F = &fd_table[fd]; |
606bd3b5 | 410 | #if !USE_ASYNC_IO |
090089c4 | 411 | int len; |
606bd3b5 | 412 | #endif |
413 | disk_ctrl_t *ctrlp = xcalloc(1, sizeof(disk_ctrl_t)); | |
0a0bf5db | 414 | ctrlp->fd = fd; |
cd1fb0eb | 415 | ctrlp->data = ctrl_dat; |
0a0bf5db | 416 | #if USE_ASYNC_IO |
417 | aioRead(fd, | |
711982d8 | 418 | ctrl_dat->buf, |
419 | ctrl_dat->req_len, | |
0a0bf5db | 420 | diskHandleReadComplete, |
cd1fb0eb | 421 | ctrlp); |
0a0bf5db | 422 | #else |
711982d8 | 423 | if (F->disk.offset != ctrl_dat->offset) { |
6a54c60e | 424 | debug(6, 1) ("diskHandleRead: seeking to offset %d\n", |
425 | (int) ctrl_dat->offset); | |
711982d8 | 426 | lseek(fd, ctrl_dat->offset, SEEK_SET); /* XXX ignore return? */ |
427 | } | |
428 | len = read(fd, ctrl_dat->buf, ctrl_dat->req_len); | |
429 | F->disk.offset += len; | |
582b6456 | 430 | diskHandleReadComplete(ctrlp, len, errno); |
090089c4 | 431 | #endif |
0a0bf5db | 432 | } |
433 | ||
de866d20 | 434 | static void |
4f92c80c | 435 | diskHandleReadComplete(void *data, int len, int errcode) |
0a0bf5db | 436 | { |
437 | disk_ctrl_t *ctrlp = data; | |
438 | dread_ctrl *ctrl_dat = ctrlp->data; | |
439 | int fd = ctrlp->fd; | |
0a0bf5db | 440 | errno = errcode; |
441 | xfree(data); | |
4f92c80c | 442 | fd_bytes(fd, len, FD_READ); |
0a0bf5db | 443 | if (len < 0) { |
444 | if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { | |
445 | commSetSelect(fd, | |
446 | COMM_SELECT_READ, | |
cd1fb0eb | 447 | diskHandleRead, |
448 | ctrl_dat, | |
0a0bf5db | 449 | 0); |
de866d20 | 450 | return; |
0a0bf5db | 451 | } |
a3d5953d | 452 | debug(50, 1) ("diskHandleRead: FD %d: error reading: %s\n", |
0a0bf5db | 453 | fd, xstrerror()); |
711982d8 | 454 | ctrl_dat->handler(fd, |
455 | ctrl_dat->buf, | |
456 | 0, | |
0a0bf5db | 457 | DISK_ERROR, |
458 | ctrl_dat->client_data); | |
459 | safe_free(ctrl_dat); | |
de866d20 | 460 | return; |
090089c4 | 461 | } else if (len == 0) { |
462 | /* EOF */ | |
463 | ctrl_dat->end_of_file = 1; | |
464 | /* call handler */ | |
0a0bf5db | 465 | ctrl_dat->handler(fd, |
466 | ctrl_dat->buf, | |
711982d8 | 467 | len, |
0a0bf5db | 468 | DISK_EOF, |
098be23b | 469 | ctrl_dat->client_data); |
090089c4 | 470 | safe_free(ctrl_dat); |
de866d20 | 471 | return; |
090089c4 | 472 | } |
6a54c60e | 473 | ctrl_dat->handler(fd, |
474 | ctrl_dat->buf, | |
475 | len, | |
476 | DISK_OK, | |
477 | ctrl_dat->client_data); | |
478 | safe_free(ctrl_dat); | |
090089c4 | 479 | } |
480 | ||
481 | ||
482 | /* start read operation */ | |
483 | /* buffer must be allocated from the caller. | |
484 | * It must have at least req_len space in there. | |
485 | * call handler when a reading is complete. */ | |
b8d8561b | 486 | int |
d89d1fb6 | 487 | file_read(int fd, char *buf, int req_len, int offset, DRCB * handler, void *client_data) |
090089c4 | 488 | { |
489 | dread_ctrl *ctrl_dat; | |
711982d8 | 490 | assert(fd >= 0); |
30a4f2a8 | 491 | ctrl_dat = xcalloc(1, sizeof(dread_ctrl)); |
090089c4 | 492 | ctrl_dat->fd = fd; |
493 | ctrl_dat->offset = offset; | |
494 | ctrl_dat->req_len = req_len; | |
495 | ctrl_dat->buf = buf; | |
090089c4 | 496 | ctrl_dat->end_of_file = 0; |
497 | ctrl_dat->handler = handler; | |
498 | ctrl_dat->client_data = client_data; | |
0a0bf5db | 499 | #if USE_ASYNC_IO |
500 | diskHandleRead(fd, ctrl_dat); | |
501 | #else | |
b177367b | 502 | commSetSelect(fd, |
234967c9 | 503 | COMM_SELECT_READ, |
cd1fb0eb | 504 | diskHandleRead, |
505 | ctrl_dat, | |
b177367b | 506 | 0); |
0a0bf5db | 507 | #endif |
090089c4 | 508 | return DISK_OK; |
509 | } | |
510 | ||
511 | ||
711982d8 | 512 | #if UNUSED_CODE |
090089c4 | 513 | /* Read from FD and pass a line to routine. Walk to EOF. */ |
582b6456 | 514 | static void |
515 | diskHandleWalk(int fd, void *data) | |
090089c4 | 516 | { |
582b6456 | 517 | dwalk_ctrl *walk_dat = data; |
606bd3b5 | 518 | #if !USE_ASYNC_IO |
090089c4 | 519 | int len; |
606bd3b5 | 520 | #endif |
521 | disk_ctrl_t *ctrlp = xcalloc(1, sizeof(disk_ctrl_t)); | |
0a0bf5db | 522 | ctrlp->fd = fd; |
cd1fb0eb | 523 | ctrlp->data = walk_dat; |
0a0bf5db | 524 | #if USE_ASYNC_IO |
606bd3b5 | 525 | aioRead(fd, |
526 | walk_dat->buf, | |
0a0bf5db | 527 | DISK_LINE_LEN - 1, |
528 | diskHandleWalkComplete, | |
cd1fb0eb | 529 | ctrlp); |
0a0bf5db | 530 | #else |
090089c4 | 531 | len = read(fd, walk_dat->buf, DISK_LINE_LEN - 1); |
582b6456 | 532 | diskHandleWalkComplete(ctrlp, len, errno); |
090089c4 | 533 | #endif |
0a0bf5db | 534 | } |
711982d8 | 535 | #endif |
0a0bf5db | 536 | |
711982d8 | 537 | #if UNUSED_CODE |
de866d20 | 538 | static void |
0a0bf5db | 539 | diskHandleWalkComplete(void *data, int retcode, int errcode) |
540 | { | |
541 | disk_ctrl_t *ctrlp = (disk_ctrl_t *) data; | |
542 | dwalk_ctrl *walk_dat; | |
543 | int fd; | |
544 | int len; | |
545 | LOCAL_ARRAY(char, temp_line, DISK_LINE_LEN); | |
546 | int end_pos; | |
547 | int st_pos; | |
548 | int used_bytes; | |
0a0bf5db | 549 | walk_dat = (dwalk_ctrl *) ctrlp->data; |
550 | fd = ctrlp->fd; | |
551 | len = retcode; | |
552 | errno = errcode; | |
553 | xfree(data); | |
0a0bf5db | 554 | if (len < 0) { |
555 | if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { | |
582b6456 | 556 | commSetSelect(fd, COMM_SELECT_READ, diskHandleWalk, walk_dat, 0); |
de866d20 | 557 | return; |
0a0bf5db | 558 | } |
a3d5953d | 559 | debug(50, 1) ("diskHandleWalk: FD %d: error readingd: %s\n", |
0a0bf5db | 560 | fd, xstrerror()); |
561 | walk_dat->handler(fd, DISK_ERROR, walk_dat->client_data); | |
562 | safe_free(walk_dat->buf); | |
563 | safe_free(walk_dat); | |
de866d20 | 564 | return; |
090089c4 | 565 | } else if (len == 0) { |
566 | /* EOF */ | |
567 | walk_dat->handler(fd, DISK_EOF, walk_dat->client_data); | |
568 | safe_free(walk_dat->buf); | |
569 | safe_free(walk_dat); | |
de866d20 | 570 | return; |
090089c4 | 571 | } |
572 | /* emulate fgets here. Cut the into separate line. newline is excluded */ | |
573 | /* it throws last partial line, if exist, away. */ | |
574 | used_bytes = st_pos = end_pos = 0; | |
575 | while (end_pos < len) { | |
576 | if (walk_dat->buf[end_pos] == '\n') { | |
577 | /* new line found */ | |
e94df02d | 578 | xstrncpy(temp_line, walk_dat->buf + st_pos, end_pos - st_pos + 1); |
090089c4 | 579 | used_bytes += end_pos - st_pos + 1; |
090089c4 | 580 | /* invoke line handler */ |
581 | walk_dat->line_handler(fd, temp_line, strlen(temp_line), | |
582 | walk_dat->line_data); | |
090089c4 | 583 | /* skip to next line */ |
584 | st_pos = end_pos + 1; | |
585 | } | |
586 | end_pos++; | |
587 | } | |
090089c4 | 588 | /* update file pointer to the next to be read character */ |
589 | walk_dat->offset += used_bytes; | |
090089c4 | 590 | /* reschedule it for next line. */ |
95d15928 | 591 | commSetSelect(fd, COMM_SELECT_READ, diskHandleWalk, walk_dat, 0); |
090089c4 | 592 | } |
711982d8 | 593 | #endif |
090089c4 | 594 | |
711982d8 | 595 | #if UNUSED_CODE |
090089c4 | 596 | /* start walk through whole file operation |
597 | * read one block and chop it to a line and pass it to provided | |
598 | * handler one line at a time. | |
599 | * call a completion handler when done. */ | |
b8d8561b | 600 | int |
601 | file_walk(int fd, | |
582b6456 | 602 | FILE_WALK_HD * handler, |
b8d8561b | 603 | void *client_data, |
582b6456 | 604 | FILE_WALK_LHD * line_handler, |
b8d8561b | 605 | void *line_data) |
090089c4 | 606 | { |
607 | dwalk_ctrl *walk_dat; | |
30a4f2a8 | 608 | walk_dat = xcalloc(1, sizeof(dwalk_ctrl)); |
090089c4 | 609 | walk_dat->fd = fd; |
610 | walk_dat->offset = 0; | |
30a4f2a8 | 611 | walk_dat->buf = xcalloc(1, DISK_LINE_LEN); |
090089c4 | 612 | walk_dat->cur_len = 0; |
613 | walk_dat->handler = handler; | |
614 | walk_dat->client_data = client_data; | |
615 | walk_dat->line_handler = line_handler; | |
616 | walk_dat->line_data = line_data; | |
0a0bf5db | 617 | #if USE_ASYNC_IO |
618 | diskHandleWalk(fd, walk_dat); | |
619 | #else | |
95d15928 | 620 | commSetSelect(fd, COMM_SELECT_READ, diskHandleWalk, walk_dat, 0); |
0a0bf5db | 621 | #endif |
090089c4 | 622 | return DISK_OK; |
623 | } | |
711982d8 | 624 | #endif |
090089c4 | 625 | |
b8d8561b | 626 | int |
627 | diskWriteIsComplete(int fd) | |
b59c7120 | 628 | { |
95d15928 | 629 | return fd_table[fd].disk.write_q ? 0 : 1; |
0a21bd84 | 630 | } |