/*
- * $Id: fork.c,v 1.51.2.2.2.8 2004-03-11 16:16:41 didg Exp $
+ * $Id: fork.c,v 1.51.2.2.2.9 2004-05-04 14:26:13 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
int is64;
{
struct ofork *ofork;
- off_t size;
off_t offset, saveoff, reqcount, savereqcount;
int cc, err, eid, xlate = 0;
u_int16_t ofrefnum;
u_char nlmask, nlchar;
- int non_blocking = 0;
ibuf += 2;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
goto afp_read_err;
}
- /* reqcount isn't always truthful. we need to deal with that. */
- size = ad_size(ofork->of_ad, eid);
-
- if (offset >= size) {
- err = AFPERR_EOF;
- goto afp_read_err;
- }
-
savereqcount = reqcount;
saveoff = offset;
if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount,ofork->of_refnum) < 0) {
/* dsi can stream requests. we can only do this if we're not checking
* for an end-of-line character. oh well. */
if ((obj->proto == AFPPROTO_DSI) && (*rbuflen < reqcount) && !nlmask) {
- DSI *dsi = obj->handle;
+ DSI *dsi = obj->handle;
+ off_t size;
+ int non_blocking = 0;
#ifdef DEBUG1
if (obj->options.flags & OPTION_DEBUG) {
bprint(rbuf, *rbuflen);
}
#endif
+ /* reqcount isn't always truthful. we need to deal with that. */
+ size = ad_size(ofork->of_ad, eid);
+
/* subtract off the offset */
size -= offset;
if (reqcount > size) {
/* due to the nature of afp packets, we have to exit if we get
an error. we can't do this with translation on. */
-#if 0 /* idef WITH_SENDFILE */
+#if 0 /* ifdef WITH_SENDFILE */
/* FIXME with OS X deadlock partial workaround we can't use sendfile */
if (!(xlate || Debug(obj) )) {
if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset, dsi->datasize) < 0) {
goto afp_read_exit;
*rbuflen = cc;
}
+ if (non_blocking) {
+ /* set back to blocking mode */
+ dsi_block(dsi, 0);
+ }
dsi_readdone(dsi);
goto afp_read_done;
}
afp_read_done:
- if (non_blocking) {
- DSI *dsi = obj->handle;
- /* set back to blocking mode */
- dsi_block(dsi, 0);
- }
ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount,ofork->of_refnum);
return err;
/*
- * $Id: ad_open.c,v 1.30.6.10 2004-05-03 14:04:35 didg Exp $
+ * $Id: ad_open.c,v 1.30.6.11 2004-05-04 14:26:14 didg Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* if ((oflags & O_CREAT) ==> (oflags & O_RDWR)
*/
admode = mode;
+ errno = 0;
st_invalid = ad_mode_st(ad_p, &admode, &st);
admode = ad_hf_mode(admode);
- errno = 0;
- ad->ad_hf.adf_fd = open( ad_p, oflags,admode );
- if ( ad->ad_hf.adf_fd < 0 && ad->ad_flags != AD_VERSION2_OSX) {
+ if ( errno == ENOENT && !(adflags & ADFLAGS_NOADOUBLE) && ad->ad_flags != AD_VERSION2_OSX) {
/*
* Probably .AppleDouble doesn't exist, try to
* mkdir it.
*/
- if (errno == ENOENT && (adflags & ADFLAGS_NOADOUBLE) == 0) {
- if (NULL == ( slash = strrchr( ad_p, '/' )) ) {
- return ad_error(ad, adflags);
- }
- *slash = '\0';
- errno = 0;
- if ( ad_mkdir( ad_p, 0777 ) < 0 ) {
- return ad_error(ad, adflags);
- }
- *slash = '/';
- admode = mode;
- st_invalid = ad_mode_st(ad_p, &admode, &st);
- admode = ad_hf_mode(admode);
- ad->ad_hf.adf_fd = open( ad_p, oflags, admode);
+ if (NULL == ( slash = strrchr( ad_p, '/' )) ) {
+ return ad_error(ad, adflags);
}
+ *slash = '\0';
+ errno = 0;
+ if ( ad_mkdir( ad_p, 0777 ) < 0 ) {
+ return ad_error(ad, adflags);
+ }
+ *slash = '/';
+ admode = mode;
+ st_invalid = ad_mode_st(ad_p, &admode, &st);
+ admode = ad_hf_mode(admode);
}
+ /* retry with O_CREAT */
+ ad->ad_hf.adf_fd = open( ad_p, oflags,admode );
if ( ad->ad_hf.adf_fd < 0 ) {
return ad_error(ad, adflags);
}
/*
- * $Id: dsi_cmdreply.c,v 1.3 2001-06-29 14:14:46 rufustfirefly Exp $
+ * $Id: dsi_cmdreply.c,v 1.3.14.1 2004-05-04 14:26:14 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
* reserved field are assumed to already be set. */
int dsi_cmdreply(DSI *dsi, const int err)
{
+int ret;
dsi->header.dsi_flags = DSIFL_REPLY;
/*dsi->header.dsi_command = DSIFUNC_CMD;*/
dsi->header.dsi_len = htonl(dsi->datalen);
dsi->header.dsi_code = htonl(err);
- return dsi_stream_send(dsi, dsi->data, dsi->datalen);
+ ret = dsi_stream_send(dsi, dsi->data, dsi->datalen);
+ if (dsi->sigblocked) {
+ sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
+ dsi->sigblocked = 0;
+ }
+ return ret;
}
/*
- * $Id: dsi_read.c,v 1.3.14.3 2004-02-20 20:53:15 bfernhomberg Exp $
+ * $Id: dsi_read.c,v 1.3.14.4 2004-05-04 14:26:14 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
sigprocmask(SIG_BLOCK, &dsi->sigblockset, &dsi->oldset);
dsi->sigblocked = 1;
+#ifdef TIMER_ON_WRITE
setitimer(ITIMER_REAL, &none, &dsi->savetimer);
-
+#endif
if (dsi_stream_send(dsi, buf, buflen)) {
dsi->datasize = size - buflen;
return min(dsi->datasize, buflen);
void dsi_readdone(DSI *dsi)
{
+#ifdef TIMER_ON_WRITE
setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
+#endif
sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
dsi->sigblocked = 0;
}
/*
- * $Id: dsi_stream.c,v 1.11.6.4 2004-02-10 10:21:50 didg Exp $
+ * $Id: dsi_stream.c,v 1.11.6.5 2004-05-04 14:26:14 didg Exp $
*
* Copyright (c) 1998 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
FD_SET( dsi->socket, &readfds);
FD_SET( dsi->socket, &writefds);
maxfd = dsi->socket +1;
- if (select( maxfd, &readfds, &writefds, NULL, NULL) <= 0)
- return;
+ while (1) {
+ FD_SET( dsi->socket, &readfds);
+ FD_SET( dsi->socket, &writefds);
+ if (select( maxfd, &readfds, &writefds, NULL, NULL) <= 0)
+ return;
- if ( !FD_ISSET(dsi->socket, &readfds)) {
- /* nothing waiting in the queue */
- return;
- }
- if (!dsi->buffer) {
- /* XXX config options */
- dsi->maxsize = 6 * dsi->server_quantum;
- if (!dsi->maxsize)
- dsi->maxsize = 6 * DSI_SERVQUANT_DEF;
- dsi->buffer = malloc(dsi->maxsize);
+ if ( !FD_ISSET(dsi->socket, &readfds)) {
+ /* nothing waiting in the read queue */
+ return;
+ }
if (!dsi->buffer) {
- /* fall back to blocking IO */
+ /* XXX config options */
+ dsi->maxsize = 6 * dsi->server_quantum;
+ if (!dsi->maxsize)
+ dsi->maxsize = 6 * DSI_SERVQUANT_DEF;
+ dsi->buffer = malloc(dsi->maxsize);
+ if (!dsi->buffer) {
+ /* fall back to blocking IO */
+ dsi_block(dsi, 0);
+ return;
+ }
+ dsi->start = dsi->buffer;
+ dsi->eof = dsi->buffer;
+ dsi->end = dsi->buffer + dsi->maxsize;
+ }
+ len = dsi->end - dsi->eof;
+
+ if (len <= 0) {
+ /* ouch, our buffer is full !
+ * fall back to blocking IO
+ * could block and disconnect but it's better than a cpu hog
+ */
dsi_block(dsi, 0);
return;
}
- dsi->start = dsi->buffer;
- dsi->eof = dsi->buffer;
- dsi->end = dsi->buffer + dsi->maxsize;
- }
- len = dsi->end - dsi->eof;
-
- if (len <= 0) {
- /* ouch, our buffer is full !
- * fall back to blocking IO
- * could block and disconnect but it's better than a cpu hog
- */
- dsi_block(dsi, 0);
- return;
- }
- len = read(dsi->socket, dsi->eof, len);
- if (len <= 0)
- return;
- dsi->eof += len;
+ len = read(dsi->socket, dsi->eof, len);
+ if (len <= 0)
+ return;
+ dsi->eof += len;
+ if ( FD_ISSET(dsi->socket, &writefds)) {
+ return;
+ }
+ }
}
/* ------------------------------
memcpy(block + 12, &dsi->header.dsi_reserved,
sizeof(dsi->header.dsi_reserved));
- /* block signals */
- block_sig(dsi);
-
if (!length) { /* just write the header */
length = (dsi_stream_write(dsi, block, sizeof(block), 0) == sizeof(block));
- unblock_sig(dsi);
return length; /* really 0 on failure, 1 on success */
}
+ /* block signals */
+ block_sig(dsi);
#ifdef USE_WRITEV
iov[0].iov_base = block;
iov[0].iov_len = sizeof(block);
/*
- * $Id: dsi_write.c,v 1.3.14.1 2003-10-17 00:01:14 didg Exp $
+ * $Id: dsi_write.c,v 1.3.14.2 2004-05-04 14:26:14 didg Exp $
*
* Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
* All rights reserved. See COPYRIGHT.
* for arbitrary buffers. */
size_t dsi_writeinit(DSI *dsi, void *buf, const size_t buflen)
{
+#ifdef TIMER_ON_READ
const struct itimerval none = {{0, 0}, {0, 0}};
+#endif
size_t len, header;
/* figure out how much data we have. do a couple checks for 0
} else
len = 0;
+#ifdef TIMER_ON_READ
/* 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, &dsi->oldset);
+ dsi->sigblocked = 1;
setitimer(ITIMER_REAL, &none, &dsi->savetimer);
+#endif
return len;
}
dsi->datasize -= length;
return length;
}
-
+#ifdef TIMER_ON_READ
setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
+#endif
return 0;
}
else
break;
}
-
+#ifdef TIMER_ON_READ
setitimer(ITIMER_REAL, &dsi->savetimer, NULL);
sigprocmask(SIG_SETMASK, &dsi->oldset, NULL);
+#endif
}