/*
- * $Id: fork.c,v 1.20 2002-02-02 19:11:34 jmarcus Exp $
+ * $Id: fork.c,v 1.21 2002-02-03 04:57:38 jmarcus Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
{
struct ofork *ofork;
off_t size;
- int32_t offset, saveoff, reqcount;
- int cc, err, eid, xlate = 0;
+ int32_t offset, saveoff, reqcount, savereqcount;
+ int cc, err, saveerr, eid, xlate = 0;
u_int16_t ofrefnum;
u_char nlmask, nlchar;
}
/* zero request count */
+ err = AFP_OK;
if (!reqcount) {
- err = AFP_OK;
goto afp_read_err;
}
/* reqcount isn't always truthful. we need to deal with that. */
- if ((size = ad_size(ofork->of_ad, eid)) == 0) {
+ size = ad_size(ofork->of_ad, eid);
+
+ if (offset >= size) {
err = AFPERR_EOF;
goto afp_read_err;
}
+ /* subtract off the offset */
+ size -= offset;
+ savereqcount = reqcount;
+ if (reqcount > size) {
+ reqcount = size;
+ err = AFPERR_EOF;
+ }
+
saveoff = offset;
- if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, reqcount) < 0) {
+ /* if EOF lock on the old reqcount, some prg may need it */
+ if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount) < 0) {
err = AFPERR_LOCK;
goto afp_read_err;
}
#define min(a,b) ((a)<(b)?(a):(b))
*rbuflen = min( reqcount, *rbuflen );
+ saveerr = err;
err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen,
xlate);
if (err < 0)
goto afp_read_done;
-
+ if (saveerr < 0) {
+ err = saveerr;
+ goto afp_read_done;
+ }
/* 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;
- /* subtract off the offset */
- size -= offset;
- if (reqcount > size) {
- reqcount = size;
- err = AFPERR_EOF;
- }
-
if (obj->options.flags & OPTION_DEBUG) {
printf( "(read) reply: %d/%d, %d\n", *rbuflen,
reqcount, dsi->clientID);
afp_read_exit:
LOG(log_error, logtype_default, "afp_read: %s", strerror(errno));
dsi_readdone(dsi);
- ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount);
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount);
obj->exit(1);
}
afp_read_done:
- ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount);
+ ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount);
return err;
afp_read_err: