2 * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3 * All rights reserved. See COPYRIGHT.
5 * 7 Oct 1997 added checks for 0 data.
12 /* this streams writes */
15 #include <sys/types.h>
21 #include <atalk/dsi.h>
22 #include <netatalk/endian.h>
25 #define MIN(a,b) ((a) < (b) ? (a) : (b))
28 /* initialize relevant things for dsi_write. this returns the amount
29 * of data in the data buffer. the interface has been reworked to allow
30 * for arbitrary buffers. */
31 size_t dsi_writeinit(DSI *dsi, void *buf, const size_t buflen)
33 const struct itimerval none = {{0, 0}, {0, 0}};
36 /* figure out how much data we have. do a couple checks for 0
38 header = ntohl(dsi->header.dsi_code);
39 dsi->datasize = header ? ntohl(dsi->header.dsi_len) - header : 0;
40 if (dsi->datasize > 0) {
41 len = MIN(sizeof(dsi->commands) - header, dsi->datasize);
43 /* write last part of command buffer into buf */
44 memcpy(buf, dsi->commands + header, len);
46 /* recalculate remaining data */
51 /* deal with signals. i'm doing it this way to ensure that we don't
52 * get confused if a writeflush on zero remaining data is, for some
54 sigprocmask(SIG_BLOCK, &dsi->sigblockset, NULL);
55 setitimer(ITIMER_REAL, &none, &dsi->savetimer);
59 /* fill up buf and then return. this should be called repeatedly
60 * until all the data has been read. i block alarm processing
61 * during the transfer to avoid sending unnecessary tickles. */
62 size_t dsi_write(DSI *dsi, void *buf, const size_t buflen)
66 if (((length = MIN(buflen, dsi->datasize)) > 0) &&
67 ((length = dsi_stream_read(dsi, buf, length)) > 0)) {
68 dsi->datasize -= length;
72 setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
73 sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
77 /* flush any unread buffers. */
78 void dsi_writeflush(DSI *dsi)
82 while (dsi->datasize > 0) {
83 length = dsi_stream_read(dsi, dsi->data,
84 MIN(sizeof(dsi->data), dsi->datasize));
86 dsi->datasize -= length;
91 setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
92 sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);