-dnl $Id: configure.in,v 1.179.2.3.2.6 2003-09-26 23:46:21 bfernhomberg Exp $
+dnl $Id: configure.in,v 1.179.2.3.2.7 2003-10-17 00:01:10 didg Exp $
dnl configure.in for netatalk
AC_INIT(bin/adv1tov2/adv1tov2.c)
)
if test x"$linux_sendfile" = "xyes"; then
- dnl --- added by Yoshinobu Ishizaki (2001.03.13) ---
- dnl ----- check if version is newer than 2.2.x
- changequote(<<,>>)
- majorvers="`uname -r | sed 's/\([0-9]\)..*/\1/'`"
- minorvers="`uname -r | sed 's/[0-9]\.\([0-9]\)\..*/\1/'`"
- if [ $majorvers -ge 2 ]; then
- if [ $minorvers -ge 2 ]; then
- changequote([,])
- AC_MSG_RESULT([ * found Linux 2.2.x or higher])
- AC_DEFINE(SENDFILE_FLAVOR_LINUX, 1, [Define if the sendfile() function uses Linux semantics])
- else
- AC_MSG_RESULT([ * found Linux 2.0.x ])
- fi
- fi
+ AC_CACHE_CHECK([for linux sendfile support],netatalk_cv_HAVE_SENDFILE,[
+ AC_TRY_LINK([#include <sys/sendfile.h>],
+[\
+int tofd, fromfd;
+off_t offset;
+size_t total;
+ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
+],
+netatalk_cv_HAVE_SENDFILE=yes,netatalk_cv_HAVE_SENDFILE=no)])
+
+# Try and cope with broken Linux sendfile....
+ AC_CACHE_CHECK([for broken linux sendfile support],samba_cv_HAVE_BROKEN_LINUX_SENDFILE,[
+ AC_TRY_LINK([\
+#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
+#undef _FILE_OFFSET_BITS
+#endif
+#include <sys/sendfile.h>],
+[\
+int tofd, fromfd;
+off_t offset;
+size_t total;
+ssize_t nwritten = sendfile(tofd, fromfd, &offset, total);
+],
+netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE=yes,netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE=no)])
+
+ if test x"$netatalk_cv_HAVE_SENDFILE" = x"yes"; then
+ AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available])
+ AC_DEFINE(SENDFILE_FLAVOR_LINUX,1,[Whether linux sendfile() API is available])
+ AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used])
+ elif test x"$netatalk_cv_HAVE_BROKEN_LINUX_SENDFILE" = x"yes"; then
+ AC_DEFINE(SENDFILE_FLAVOR_LINUX,1,[Whether linux sendfile() API is available])
+ AC_DEFINE(LINUX_BROKEN_SENDFILE_API,1,[Whether (linux) sendfile() is broken])
+ AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile should be used])
+ else
+ AC_MSG_RESULT(no);
+ fi
fi
dnl ----- Linux/alpha specific -----
/*
- * $Id: desktop.c,v 1.26.2.4.2.4 2003-09-28 13:58:55 didg Exp $
+ * $Id: desktop.c,v 1.26.2.4.2.5 2003-10-17 00:01:10 didg Exp $
*
* See COPYRIGHT.
*
/* do to the streaming nature, we have to exit if we encounter
* a problem. much confusion results otherwise. */
while (*rbuflen > 0) {
-#if defined(SENDFILE_FLAVOR_LINUX) || defined(SENDFILE_FLAVOR_BSD)
+#ifdef WITH_SENDFILE
if (!obj->options.flags & OPTION_DEBUG) {
-#ifdef SENDFILE_FLAVOR_LINUX
- if (sendfile(dsi->socket, si.sdt_fd, &offset, dsi->datasize) < 0)
- goto geticon_exit;
-#endif /* SENDFILE_FLAVOR_LINUX */
-
-#ifdef SENDFILE_FLAVOR_BSD
- if (sendfile(si.sdt_fd, dsi->socket, offset, rc, NULL, NULL, 0) < 0)
- goto geticon_exit;
-#endif /* SENDFILE_FLAVOR_BSD */
-
+ if (sys_sendfile(dsi->socket, si.sdt_fd, &offset, dsi->datasize) < 0) {
+ switch (errno) {
+ case ENOSYS:
+ case EINVAL: /* there's no guarantee that all fs support sendfile */
+ break;
+ default:
+ goto geticon_exit;
+ }
+ }
goto geticon_done;
}
-#endif /* SENDFILE_FLAVOR_LINUX || SENDFILE_FLAVOR_BSD */
-
+#endif
buflen = read(si.sdt_fd, rbuf, *rbuflen);
if (buflen < 0)
goto geticon_exit;
return( AFPERR_PARAM );
}
*rbuflen = rc;
- return AFP_OK;
}
+ return AFP_OK;
}
-
+/* ---------------------- */
static char hexdig[] = "0123456789abcdef";
char *dtfile(const struct vol *vol, u_char creator[], char *ext )
{
/*
- * $Id: file.c,v 1.92.2.2.2.3 2003-09-28 13:58:57 didg Exp $
+ * $Id: file.c,v 1.92.2.2.2.4 2003-10-17 00:01:11 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
ssize_t cc;
int err = AFP_OK;
char filebuf[8192];
-
+
#ifdef SENDFILE_FLAVOR_LINUX
+ off_t offset = 0;
+ size_t size;
struct stat st;
+ #define BUF 128*1024*1024
if (fstat(sfd, &st) == 0) {
- if ((cc = sendfile(dfd, sfd, NULL, st.st_size)) < 0) {
- switch (errno) {
- case EINVAL: /* there's no guarantee that all fs support sendfile */
- break;
- case EDQUOT:
- case EFBIG:
- case ENOSPC:
- return AFPERR_DFULL;
- case EROFS:
- return AFPERR_VLOCK;
- default:
- return AFPERR_PARAM;
+
+ while (1) {
+ if ( offset >= st.st_size) {
+ return AFP_OK;
+ }
+ size = (st.st_size -offset > BUF)?BUF:st.st_size -offset;
+ if ((cc = sys_sendfile(dfd, sfd, &offset, size)) < 0) {
+ switch (errno) {
+ case ENOSYS:
+ case EINVAL: /* there's no guarantee that all fs support sendfile */
+ goto no_sendfile;
+ case EDQUOT:
+ case EFBIG:
+ case ENOSPC:
+ return AFPERR_DFULL;
+ case EROFS:
+ return AFPERR_VLOCK;
+ default:
+ return AFPERR_PARAM;
+ }
}
- }
- else {
- return AFP_OK;
}
}
-#endif /* SENDFILE_FLAVOR_LINUX */
+ no_sendfile:
+#endif
while (1) {
if ((cc = read(sfd, filebuf, sizeof(filebuf))) < 0) {
/*
- * $Id: fork.c,v 1.51.2.2.2.3 2003-09-28 13:58:57 didg Exp $
+ * $Id: fork.c,v 1.51.2.2.2.4 2003-10-17 00:01:11 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include "desktop.h"
#include "volume.h"
+#ifdef DEBUG1
+#define Debug(a) ((a)->options.flags & OPTION_DEBUG)
+#else
+#define Debug(a) (0)
+#endif
+
struct ofork *writtenfork;
extern int getmetadata(struct vol *vol,
u_int16_t bitmap,
#define min(a,b) ((a)<(b)?(a):(b))
*rbuflen = min( reqcount, *rbuflen );
- err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen,
- xlate);
+ err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen, xlate);
if (err < 0)
goto afp_read_done;
#ifdef DEBUG1
if (obj->options.flags & OPTION_DEBUG) {
- printf( "(read) reply: %d/%d, %d\n", *rbuflen,
- (int) reqcount, dsi->clientID);
+ printf( "(read) reply: %d/%d, %d\n", *rbuflen,(int) reqcount, dsi->clientID);
bprint(rbuf, *rbuflen);
}
#endif
/* due to the nature of afp packets, we have to exit if we get
an error. we can't do this with translation on. */
-#ifdef HAVE_SENDFILE_READ
- if (!(xlate || (obj->options.flags & OPTION_DEBUG))) {
- if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset,
- dsi->datasize) < 0) {
- if (errno == EINVAL)
+#ifdef WITH_SENDFILE
+ if (!(xlate || Debug(obj) )) {
+ if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset, dsi->datasize) < 0) {
+ if (errno == EINVAL || errno == ENOSYS)
goto afp_read_loop;
else {
LOG(log_error, logtype_afpd, "afp_read: ad_readfile: %s", strerror(errno));
}
afp_read_loop:
-#endif /* HAVE_SENDFILE_READ */
+#endif
/* fill up our buffer. */
while (*rbuflen > 0) {
- cc = read_file(ofork, eid, offset, nlmask, nlchar, rbuf,
- rbuflen, xlate);
+ cc = read_file(ofork, eid, offset, nlmask, nlchar, rbuf,rbuflen, xlate);
if (cc < 0)
goto afp_read_exit;
/* find out what we have already and write it out. */
cc = dsi_writeinit(dsi, rbuf, *rbuflen);
- if (!cc ||
- (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
+ if (!cc || (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
dsi_writeflush(dsi);
*rbuflen = 0;
ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum);
/*
- * $Id: volume.c,v 1.51.2.7.2.6 2003-09-30 12:24:49 didg Exp $
+ * $Id: volume.c,v 1.51.2.7.2.7 2003-10-17 00:01:11 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
volname[vlen] = 0;
return;
}
-
+#if 0
LOG(log_debug, logtype_afpd, "Parsing volset %s", val);
-
+#endif
if (optionok(tmp, "allow:", val)) {
setoption(options, save, VOLOPT_ALLOW, val);
/*
- * $Id: adouble.h,v 1.21.6.1 2003-09-09 16:42:20 didg Exp $
+ * $Id: adouble.h,v 1.21.6.2 2003-10-17 00:01:12 didg Exp $
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
*
#include <sys/mman.h>
#include <netatalk/endian.h>
-/* XXX: this is the wrong place to put this.
- * NOTE: as of 2.2.1, linux can't do a sendfile from a socket.
- * and it doesn't have 64 bits sendfile
- */
-#ifdef SENDFILE_FLAVOR_LINUX
-
-#if _FILE_OFFSET_BITS == 64
-
-#undef SENDFILE_FLAVOR_LINUX
-
-#else /* _FILE_OFFSET_BITS != 64 */
-
-#define HAVE_SENDFILE_READ
-#define HAVE_SENDFILE_WRITE
-#include <asm/unistd.h>
-
-#ifdef __NR_sendfile
-#ifdef ATACC
-extern int sendfile __P((int , int , off_t *, size_t ));
-#else /* !ATACC */
-static __inline__ int sendfile(int fdout, int fdin, off_t *off, size_t count)
-{
- return syscall(__NR_sendfile, fdout, fdin, off, count);
-}
-#endif /* ATACC */
-
-#else /* !__NR_sendfile */
-#include <sys/sendfile.h>
-#endif /* __NR_sendfile */
-#endif /* _FILE_OFFSET_BITS */
-#endif /* SENDFILE_FLAVOR_LINUX */
-
-#ifdef SENDFILE_FLAVOR_BSD
-#define HAVE_SENDFILE_READ
-#endif
-
/* version info */
#define AD_VERSION1 0x00010000
#define AD_VERSION2 0x00020000
#define ad_setid(a, b, c)
#endif
-#ifdef HAVE_SENDFILE_READ
+#ifdef WITH_SENDFILE
extern ssize_t ad_readfile __P((const struct adouble *, const int,
const int, off_t, const size_t));
#endif
dsi_proto protocol;
struct dsi_block header;
struct sockaddr_in server, client;
- sigset_t sigblockset;
+
+ sigset_t sigblockset, oldset;
+ int sigblocked;
struct itimerval timer, savetimer;
+
u_int32_t attn_quantum, datasize, server_quantum;
u_int16_t serverID, clientID;
u_int8_t *status, commands[DSI_CMDSIZ], data[DSI_DATASIZ];
extern void dsi_sleep __P((DSI *, const int ));
/* low-level stream commands -- in dsi_stream.c */
-extern size_t dsi_stream_write __P((DSI *, void *, const size_t));
+extern size_t dsi_stream_write __P((DSI *, void *, const size_t, const int mode));
extern size_t dsi_stream_read __P((DSI *, void *, const size_t));
extern int dsi_stream_send __P((DSI *, void *, size_t));
extern int dsi_stream_receive __P((DSI *, void *, const size_t, size_t *));
/*
- * $Id: util.h,v 1.7.10.1 2003-09-09 16:42:20 didg Exp $
+ * $Id: util.h,v 1.7.10.2 2003-10-17 00:01:12 didg Exp $
*/
#ifndef _ATALK_UTIL_H
#endif /* HAVE_UNISTD_H */
#include <netatalk/at.h>
+extern int sys_ftruncate __P((int fd, off_t length));
+
+#ifdef WITH_SENDFILE
+extern ssize_t sys_sendfile __P((int __out_fd, int __in_fd, off_t *__offset,size_t __count));
+#endif
+
extern const int _diacasemap[], _dialowermap[];
extern char **getifacelist(void);
/*
- * $Id: ad_open.c,v 1.30.6.1 2003-09-09 16:42:21 didg Exp $
+ * $Id: ad_open.c,v 1.30.6.2 2003-10-17 00:01:12 didg Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
* Copyright (c) 1990,1991 Regents of The University of Michigan.
#include <netatalk/endian.h>
#include <atalk/adouble.h>
+#include <atalk/util.h>
#include "ad_private.h"
goto bail_lock;
if (fstat(fd, &st) ||
- ftruncate(fd, st.st_size + SHIFTDATA) < 0) {
+ sys_ftruncate(fd, st.st_size + SHIFTDATA) < 0) {
goto bail_open;
}
if (st.st_size > 0x7fffffff) {
return 0;
bail_truncate:
- ftruncate(fd, st.st_size);
+ sys_ftruncate(fd, st.st_size);
bail_open:
close(fd);
bail_lock:
/*
- * $Id: ad_sendfile.c,v 1.6 2003-02-17 01:51:07 srittau Exp $
+ * $Id: ad_sendfile.c,v 1.6.6.1 2003-10-17 00:01:13 didg Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
* NOTE: the following uses the fact that sendfile() only exists on
* machines with SA_RESTART behaviour. this is all very machine specific.
*
- *
+ * sendfile chainsaw from samba.
+ Unix SMB/Netbios implementation.
+ Version 2.2.x / 3.0.x
+ sendfile implementations.
+ Copyright (C) Jeremy Allison 2002.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
+#ifdef WITH_SENDFILE
+
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#include <sys/socket.h>
#include <sys/uio.h>
+#include <errno.h>
#include <atalk/adouble.h>
#include <atalk/logger.h>
#include "ad_private.h"
-#ifdef ATACC
+#if defined(LINUX_BROKEN_SENDFILE_API)
+
+extern int32_t sendfile (int fdout, int fdin, int32_t *offset, u_int32_t count);
-#if defined(HAVE_SENDFILE_READ)
-#ifdef __NR_sendfile
-int sendfile(int fdout, int fdin, off_t *off, size_t count)
+ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
{
-#if _FILE_OFFSET_BITS == 64
-#error sendfile
- return syscall(__NR_sendfile64, fdout, fdin, off, count);
+u_int32_t small_total = 0;
+int32_t small_offset;
+
+ /*
+ * Fix for broken Linux 2.4 systems with no working sendfile64().
+ * If the offset+count > 2 GB then pretend we don't have the
+ * system call sendfile at all. The upper layer catches this
+ * and uses a normal read. JRA.
+ */
+
+ if ((sizeof(off_t) >= 8) && (*offset + count > (off_t)0x7FFFFFFF)) {
+ errno = ENOSYS;
+ return -1;
+ }
+ small_total = (u_int32_t)count;
+ small_offset = (int32_t)*offset;
+
+ while (small_total) {
+ int32_t nwritten;
+ do {
+ nwritten = sendfile(tofd, fromfd, &small_offset, small_total);
+ } while (nwritten == -1 && errno == EINTR);
+ if (nwritten == -1)
+ return -1;
+ if (nwritten == 0)
+ return -1; /* I think we're at EOF here... */
+ small_total -= nwritten;
+ }
+ *offset += count;
+ return count;
+}
+
+#elif defined(SENDFILE_FLAVOR_LINUX)
+#include <sys/sendfile.h>
+
+ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
+{
+size_t total=0;
+
+ total = count;
+ while (total) {
+ ssize_t nwritten;
+ do {
+ nwritten = sendfile(tofd, fromfd, offset, total);
+ } while (nwritten == -1 && errno == EINTR);
+ if (nwritten == -1)
+ return -1;
+ if (nwritten == 0)
+ return -1; /* I think we're at EOF here... */
+ total -= nwritten;
+ }
+ return count;
+}
+
+
+#elif defined(SENDFILE_FLAVOR_BSD )
+/* FIXME untested */
+#include <sys/sendfile.h>
+ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
+{
+size_t total=0;
+int ret;
+
+ total = count;
+ while (total) {
+ ssize_t nwritten;
+ do {
+ ret = sendfile(fromfd, tofd, offset, count, NULL, &nwritten, 0);
+ while (ret == -1 && errno == EINTR);
+ if (ret == -1)
+ return -1;
+ total -= nwritten;
+ offset += nwritten;
+ }
+ return count;
+}
+
#else
- return syscall(__NR_sendfile, fdout, fdin, off, count);
-#endif
+
+ssize_t sys_sendfile(int out_fd, int in_fd, off_t *_offset, size_t count)
+{
+ /* No sendfile syscall. */
+ errno = ENOSYS;
+ return -1;
}
#endif
-#endif
-#endif
-#if defined(HAVE_SENDFILE_READ) || defined(HAVE_SENDFILE_WRITE)
+/* ------------------------------- */
static __inline__ int ad_sendfile_init(const struct adouble *ad,
const int eid, off_t *off,
const int end)
return fd;
}
-#endif
-/* read from adouble file and write to socket. sendfile doesn't change
+/* --------------------------------
+ * read from adouble file and write to socket. sendfile doesn't change
* the file pointer position. */
-#ifdef HAVE_SENDFILE_READ
ssize_t ad_readfile(const struct adouble *ad, const int eid,
const int sock, off_t off, const size_t len)
{
int fd;
fd = ad_sendfile_init(ad, eid, &off, 0);
-#ifdef __linux__
- cc = sendfile(sock, fd, &off, len);
-#endif /* __linux__ */
-
-#ifdef BSD4_4
- if (sendfile(fd, sock, off, len, NULL, &cc, 0) < 0)
- return -1;
-#endif /* BSD4_4 */
-
+ cc = sys_sendfile(sock, fd, &off, len);
return cc;
}
-#endif /* HAVE_SENDFILE_READ */
+/* ------------------------ */
#if 0
#ifdef HAVE_SENDFILE_WRITE
/* read from a socket and write to an adouble file */
int fd;
fd = ad_sendfile_init(ad, eid, &off, end);
- if ((cc = sendfile(fd, sock, &off, len)) < 0)
+ if ((cc = sys_sendfile(fd, sock, &off, len)) < 0)
return -1;
if ((eid != ADEID_DFORK) && (off > ad_getentrylen(ad, eid)))
}
#endif /* HAVE_SENDFILE_WRITE */
#endif /* 0 */
+#endif
/*
- * $Id: ad_write.c,v 1.7.6.2 2003-10-13 22:05:17 didg Exp $
+ * $Id: ad_write.c,v 1.7.6.3 2003-10-17 00:01:13 didg Exp $
*
* Copyright (c) 1990,1995 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
* the caller set the locks
* ftruncate is undefined when the file length is smaller than 'size'
*/
-static int sys_ftruncate(int fd, off_t length)
+int sys_ftruncate(int fd, off_t length)
{
#ifndef HAVE_PWRITE
/*
- * $Id: cnid_dbd.c,v 1.1.4.3 2003-09-22 07:21:34 bfernhomberg Exp $
+ * $Id: cnid_dbd.c,v 1.1.4.4 2003-10-17 00:01:13 didg Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
return 0;
transmit_fail:
+{
+ struct timeval tv;
+ tv.tv_usec = 0;
+ tv.tv_sec = 5;
+ select(0, NULL, NULL, NULL, &tv);
+}
+
if (db->fd != -1) {
close(db->fd);
}
}
/* ---------------------- */
-int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, u_int32_t len)
+int cnid_dbd_getstamp(struct _cnid_db *cdb, void *buffer, const int len)
{
CNID_private *db;
struct cnid_dbd_rqst rqst;
/*
- * $Id: cnid_dbd.h,v 1.1.4.1 2003-09-09 16:42:21 didg Exp $
+ * $Id: cnid_dbd.h,v 1.1.4.2 2003-10-17 00:01:14 didg Exp $
*
* Copyright (C) Joerg Lenneis 2003
* All Rights Reserved. See COPYRIGHT.
const char *, const int, cnid_t));
extern cnid_t cnid_dbd_get __P((struct _cnid_db *, const cnid_t, const char *, const int));
extern char *cnid_dbd_resolve __P((struct _cnid_db *, cnid_t *, void *, u_int32_t ));
-extern int cnid_dbd_getstamp __P((struct _cnid_db *, void *, u_int32_t ));
+extern int cnid_dbd_getstamp __P((struct _cnid_db *, void *, const int ));
extern cnid_t cnid_dbd_lookup __P((struct _cnid_db *, const struct stat *, const cnid_t,
const char *, const int));
extern int cnid_dbd_update __P((struct _cnid_db *, const cnid_t, const struct stat *,
/*
- * $Id: dsi_attn.c,v 1.5 2003-03-12 15:07:05 didg Exp $
+ * $Id: dsi_attn.c,v 1.5.6.1 2003-10-17 00:01:14 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
/* send an attention */
sigprocmask(SIG_BLOCK, &dsi->sigblockset, &oldset);
- len = dsi_stream_write(dsi, block, DSI_BLOCKSIZ + len);
+ len = dsi_stream_write(dsi, block, DSI_BLOCKSIZ + len, 0);
sigprocmask(SIG_SETMASK, &oldset, NULL);
return len;
/*
- * $Id: dsi_read.c,v 1.3 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: dsi_read.c,v 1.3.14.1 2003-10-17 00:01:14 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
dsi->header.dsi_len = htonl(size);
dsi->header.dsi_code = htonl(err);
- sigprocmask(SIG_BLOCK, &dsi->sigblockset, NULL);
+ sigprocmask(SIG_BLOCK, &dsi->sigblockset, &dsi->oldset);
+ dsi->sigblocked = 1;
setitimer(ITIMER_REAL, &none, &dsi->savetimer);
+
if (dsi_stream_send(dsi, buf, buflen)) {
dsi->datasize = size - buflen;
return min(dsi->datasize, buflen);
void dsi_readdone(DSI *dsi)
{
setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
- sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
+ sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
+ dsi->sigblocked = 0;
}
/* send off the data */
ssize_t dsi_read(DSI *dsi, void *buf, const size_t buflen)
{
- size_t len = dsi_stream_write(dsi, buf, buflen);
+ size_t len;
+ int delay = (dsi->datasize != buflen)?1:0;
+
+ len = dsi_stream_write(dsi, buf, buflen, delay);
if (len == buflen) {
dsi->datasize -= len;
/*
- * $Id: dsi_stream.c,v 1.11 2003-03-12 15:07:06 didg Exp $
+ * $Id: dsi_stream.c,v 1.11.6.1 2003-10-17 00:01:14 didg Exp $
*
* Copyright (c) 1998 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
#include <stdio.h>
#include <stdlib.h>
+
#ifdef HAVE_UNISTD_H
#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
+#endif
+
#include <string.h>
#include <errno.h>
#include <sys/types.h>
+#include <sys/socket.h>
+
#ifdef USE_WRITEV
#include <sys/uio.h>
-#endif /* USE_WRITEV */
+#endif
+
#include <atalk/logger.h>
#include <atalk/dsi.h>
#define min(a,b) ((a) < (b) ? (a) : (b))
+#ifndef MSG_MORE
+#define MSG_MORE 0x8000
+#endif
/* write raw data. return actual bytes read. checks against EINTR
* aren't necessary if all of the signals have SA_RESTART
* specified. */
-size_t dsi_stream_write(DSI *dsi, void *data, const size_t length)
+size_t dsi_stream_write(DSI *dsi, void *data, const size_t length, int mode)
{
size_t written;
ssize_t len;
+ unsigned int flags = (mode)?MSG_MORE:0;
written = 0;
while (written < length) {
- if ((-1 == (len = write(dsi->socket, (u_int8_t *) data + written,
- length - written)) && errno == EINTR) ||
+ if ((-1 == (len = send(dsi->socket, (u_int8_t *) data + written,
+ length - written, flags)) && errno == EINTR) ||
!len)
continue;
return written;
}
-/* read raw data. return actual bytes read. this will wait until
- * it gets length bytes */
+/* ---------------------------------------
+ * read raw data. return actual bytes read. this will wait until
+ * it gets length bytes
+ */
size_t dsi_stream_read(DSI *dsi, void *data, const size_t length)
{
size_t stored;
return stored;
}
+/* ---------------------------------------
+*/
void dsi_sleep(DSI *dsi, const int state)
{
dsi->asleep = state;
}
-/* write data. 0 on failure. this assumes that dsi_len will never
- * cause an overflow in the data buffer. */
+/* ---------------------------------------
+*/
+static void block_sig(DSI *dsi)
+{
+ if (!dsi->sigblocked) sigprocmask(SIG_BLOCK, &dsi->sigblockset, &dsi->oldset);
+}
+
+/* ---------------------------------------
+*/
+static void unblock_sig(DSI *dsi)
+{
+ if (!dsi->sigblocked) sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
+}
+
+/* ---------------------------------------
+ * write data. 0 on failure. this assumes that dsi_len will never
+ * cause an overflow in the data buffer.
+ */
int dsi_stream_send(DSI *dsi, void *buf, size_t length)
{
char block[DSI_BLOCKSIZ];
- sigset_t oldset;
#ifdef USE_WRITEV
struct iovec iov[2];
size_t towrite;
sizeof(dsi->header.dsi_reserved));
/* block signals */
- sigprocmask(SIG_BLOCK, &dsi->sigblockset, &oldset);
+ block_sig(dsi);
if (!length) { /* just write the header */
- length = (dsi_stream_write(dsi, block, sizeof(block)) == sizeof(block));
- sigprocmask(SIG_SETMASK, &oldset, NULL);
+ length = (dsi_stream_write(dsi, block, sizeof(block), 0) == sizeof(block));
+ unblock_sig(dsi);
return length; /* really 0 on failure, 1 on success */
}
break;
else if (len < 0) { /* error */
LOG(log_error, logtype_default, "dsi_stream_send: %s", strerror(errno));
- sigprocmask(SIG_SETMASK, &oldset, NULL);
+ unblock_sig(dsi);
return 0;
}
#else /* USE_WRITEV */
/* write the header then data */
- if ((dsi_stream_write(dsi, block, sizeof(block)) != sizeof(block)) ||
- (dsi_stream_write(dsi, buf, length) != length)) {
- sigprocmask(SIG_SETMASK, &oldset, NULL);
- return 0;
+ if ((dsi_stream_write(dsi, block, sizeof(block), 1) != sizeof(block)) ||
+ (dsi_stream_write(dsi, buf, length, 0) != length)) {
+ unblock_sig(dsi);
+ return 0;
}
#endif /* USE_WRITEV */
- sigprocmask(SIG_SETMASK, &oldset, NULL);
+ unblock_sig(dsi);
return 1;
}
-/* read data. function on success. 0 on failure. data length gets
+/* ---------------------------------------
+ * read data. function on success. 0 on failure. data length gets
* stored in length variable. this should really use size_t's, but
* that would require changes elsewhere. */
int dsi_stream_receive(DSI *dsi, void *buf, const size_t ilength,
/*
- * $Id: dsi_tickle.c,v 1.5 2003-03-12 15:07:07 didg Exp $
+ * $Id: dsi_tickle.c,v 1.5.6.1 2003-10-17 00:01:14 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
/* code = len = reserved = 0 */
sigprocmask(SIG_BLOCK, &dsi->sigblockset, &oldset);
- ret = dsi_stream_write(dsi, block, DSI_BLOCKSIZ) == DSI_BLOCKSIZ;
+ ret = dsi_stream_write(dsi, block, DSI_BLOCKSIZ, 0) == DSI_BLOCKSIZ;
sigprocmask(SIG_SETMASK, &oldset, NULL);
return ret;
}
/*
- * $Id: dsi_write.c,v 1.3 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: dsi_write.c,v 1.3.14.1 2003-10-17 00:01:14 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
/* deal with signals. i'm doing it this way to ensure that we don't
* get confused if a writeflush on zero remaining data is, for some
* reason, needed. */
- sigprocmask(SIG_BLOCK, &dsi->sigblockset, NULL);
+ sigprocmask(SIG_BLOCK, &dsi->sigblockset, &dsi->oldset);
setitimer(ITIMER_REAL, &none, &dsi->savetimer);
return len;
}
}
setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
- sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
+ sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
return 0;
}
}
setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
- sigprocmask(SIG_UNBLOCK, &dsi->sigblockset, NULL);
+ sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
}