2 * $Id: dsi_write.c,v 1.4 2005-04-28 20:50:02 bfernhomberg Exp $
4 * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
5 * All rights reserved. See COPYRIGHT.
7 * 7 Oct 1997 added checks for 0 data.
12 #endif /* HAVE_CONFIG_H */
14 /* this streams writes */
18 #endif /* HAVE_UNISTD_H */
19 #include <sys/types.h>
24 #endif /* HAVE_FCNTL_H */
27 #include <atalk/dsi.h>
28 #include <netatalk/endian.h>
31 #define MIN(a,b) ((a) < (b) ? (a) : (b))
34 /* initialize relevant things for dsi_write. this returns the amount
35 * of data in the data buffer. the interface has been reworked to allow
36 * for arbitrary buffers. */
37 size_t dsi_writeinit(DSI *dsi, void *buf, const size_t buflen _U_)
40 const struct itimerval none = {{0, 0}, {0, 0}};
44 /* figure out how much data we have. do a couple checks for 0
46 header = ntohl(dsi->header.dsi_code);
47 dsi->datasize = header ? ntohl(dsi->header.dsi_len) - header : 0;
48 if (dsi->datasize > 0) {
49 len = MIN(sizeof(dsi->commands) - header, dsi->datasize);
51 /* write last part of command buffer into buf */
52 memcpy(buf, dsi->commands + header, len);
54 /* recalculate remaining data */
60 /* deal with signals. i'm doing it this way to ensure that we don't
61 * get confused if a writeflush on zero remaining data is, for some
63 sigprocmask(SIG_BLOCK, &dsi->sigblockset, &dsi->oldset);
65 setitimer(ITIMER_REAL, &none, &dsi->savetimer);
70 /* fill up buf and then return. this should be called repeatedly
71 * until all the data has been read. i block alarm processing
72 * during the transfer to avoid sending unnecessary tickles. */
73 size_t dsi_write(DSI *dsi, void *buf, const size_t buflen)
77 if (((length = MIN(buflen, dsi->datasize)) > 0) &&
78 ((length = dsi_stream_read(dsi, buf, length)) > 0)) {
79 dsi->datasize -= length;
83 setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
84 sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
89 /* flush any unread buffers. */
90 void dsi_writeflush(DSI *dsi)
94 while (dsi->datasize > 0) {
95 length = dsi_stream_read(dsi, dsi->data,
96 MIN(sizeof(dsi->data), dsi->datasize));
98 dsi->datasize -= length;
103 setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
104 sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);