Exemple #1
0
/*
 * The buf is already using BUF for an output buffer, and probably
 * contains some buffered output now.  Write this out to F, and reset
 * the buffer cursor.
 */
rs_result rs_outfilebuf_drain(rs_job_t *job, rs_buffers_t *buf, void *opaque)
{
    rs_filebuf_t *fb = (rs_filebuf_t *) opaque;
    FILE *fp = fb->fp;
    gzFile zp = fb->zp;
    int fd = fb->fd;
    size_t wlen;

//logp("in rs_outfilebuf_drain\n");

    /* This is only allowed if either the buf has no output buffer
     * yet, or that buffer could possibly be BUF. */
    if(!buf->next_out)
    {
        assert(buf->avail_out == 0);
        buf->next_out = fb->buf;
        buf->avail_out = fb->buf_len;
        return RS_DONE;
    }
        
    assert(buf->avail_out <= fb->buf_len);
    assert(buf->next_out >= fb->buf);
    assert(buf->next_out <= fb->buf + fb->buf_len);

    if((wlen=buf->next_out-fb->buf)>0)
    {
	//logp("wlen: %d\n", wlen);
	if(fd>0)
	{
		size_t w=wlen;
		if(async_append_all_to_write_buffer(CMD_APPEND, fb->buf, &wlen))
		{
			// stop the rsync stuff from reading more.
	//		buf->next_out = fb->buf;
	//		buf->avail_out = 0;
	//		logp("out return BLOCKED\n");
			return RS_BLOCKED;
		}
		fb->bytes+=w;
	}
	else
	{
		size_t result=0;
		if(fp) result=fwrite(fb->buf, 1, wlen, fp);
		else if(zp) result=gzwrite(zp, fb->buf, wlen);
		if(wlen!=result)
		{
		    logp("error draining buf to file: %s",
			     strerror(errno));
		    return RS_IO_ERROR;
		}
	}
    }

    buf->next_out = fb->buf;
    buf->avail_out = fb->buf_len;
        
    return RS_DONE;
}
Exemple #2
0
int async_rw(char *rcmd, char **rdst, size_t *rlen, char wcmd, const char *wsrc, size_t *wlen)
{
        int mfd=-1;
        fd_set fsr;
        fd_set fsw;
        fd_set fse;
	int doread=0;
	int dowrite=0;
        struct timeval tval;
	static int read_blocked_on_write=0;
	static int write_blocked_on_read=0;

//printf("in async_rw\n");
	if(doing_estimate) return 0;

	if(fd<0)
	{
		logp("fd not ready in async rw: %d\n", fd);
		return -1;
	}

	if(rdst) doread++; // Given a pointer to allocate and read into.

	if(*wlen)
	{
		// More stuff to append to the write buffer.
		async_append_all_to_write_buffer(wcmd, wsrc, wlen);
	}

	if(writebuflen && !write_blocked_on_read)
		dowrite++; // The write buffer is not yet empty.

	if(doread)
	{
		if(parse_readbuf(rcmd, rdst, rlen))
		{
			logp("error in parse_readbuf\n");
			return -1;
		}
		if(*rcmd && *rdst) return 0;

		if(read_blocked_on_write) doread=0;
	}

        if(doread || dowrite)
        {
//printf("async_rw loop read %d write %d wbuflen: %d\n", doread, dowrite, writebuflen);
                mfd=-1;

                if(doread) FD_ZERO(&fsr);
                if(dowrite) FD_ZERO(&fsw);
                FD_ZERO(&fse);

                add_fd_to_sets(fd,
			doread?&fsr:NULL, dowrite?&fsw:NULL, &fse, &mfd);

                tval.tv_sec=setsec;
                tval.tv_usec=setusec;

                if(select(mfd+1,
			doread?&fsr:NULL, dowrite?&fsw:NULL, &fse, &tval)<0)
                {
                        if(errno!=EAGAIN && errno!=EINTR)
                        {
                                logp("select error: %s\n", strerror(errno));
                                return -1;
                        }
                }

		if(!FD_ISSET(fd, &fse)
		  && (!doread || !FD_ISSET(fd, &fsr))
		  && (!dowrite || !FD_ISSET(fd, &fsw)))
		{
			//logp("SELECT HIT TIMEOUT - doread: %d, dowrite: %d\n",
			//	doread, dowrite);
			// Be careful to avoid 'read quick' mode.
			if((setsec || setusec)
			  && max_network_timeout>0 && network_timeout--<=0)
			{
				logp("No activity on network for %d seconds.\n",
					max_network_timeout);
				return -1;
			}
			return 0;
		}
		network_timeout=max_network_timeout;

                if(FD_ISSET(fd, &fse))
                {
                        logp("error on socket\n");
                        return -1;
                }

                if(doread && FD_ISSET(fd, &fsr)) // able to read
                {
			int r;
			read_blocked_on_write=0;
			if(do_read(&read_blocked_on_write)) return -1;
			if((r=parse_readbuf(rcmd, rdst, rlen)))
				logp("error in second parse_readbuf\n");
			return r;
                }

                if(dowrite && FD_ISSET(fd, &fsw)) // able to write
		{
			int r=0;
			write_blocked_on_read=0;

			if((r=do_write(&write_blocked_on_read)))
				logp("error in do_write\n");
			return r;
		}
        }

        return 0;
}
Exemple #3
0
// Return 1 if there is still stuff needing to be sent.
static int do_stuff_to_send(struct sbuf *p1b, char **last_requested)
{
	//size_t junk=0;
	if(p1b->senddatapth)
	{
		size_t l=strlen(p1b->datapth);
		if(async_append_all_to_write_buffer(CMD_DATAPTH, p1b->datapth, &l))
			return 1;
		p1b->senddatapth=0;
		//if(async_rw(NULL, NULL, NULL, NULL, NULL, &junk)) return -1;
	}
	if(p1b->sendstat)
	{
		size_t l=p1b->slen;
		if(async_append_all_to_write_buffer(CMD_STAT, p1b->statbuf, &l))
			return 1;
		p1b->sendstat=0;
		//if(async_rw(NULL, NULL, NULL, NULL, NULL, &junk)) return -1;
	}
	if(p1b->sendpath)
	{
		size_t l=p1b->plen;
		if(async_append_all_to_write_buffer(p1b->cmd,
			p1b->path, &l)) return 1;
		p1b->sendpath=0;
		if(*last_requested) free(*last_requested);
		*last_requested=strdup(p1b->path);
		//if(async_rw(NULL, NULL, NULL, NULL, NULL, &junk)) return -1;
	}
	if(p1b->sigjob && !p1b->sendendofsig)
	{
		rs_result sigresult;

		sigresult=rs_async(p1b->sigjob,
			&(p1b->rsbuf), p1b->infb, p1b->outfb);
//logp("after rs_async: %d %c %s\n", sigresult, p1b->cmd, p1b->path);

		if(sigresult==RS_DONE)
		{
			p1b->sendendofsig++;
			//if(async_rw(NULL, NULL, NULL, NULL, NULL, &junk))
			//	return -1;
		}
		else if(sigresult==RS_BLOCKED || sigresult==RS_RUNNING)
		{
			// keep going round the loop.
			//if(async_rw(NULL, NULL, NULL, NULL, NULL, &junk))
			//	return -1;
			return 1;
		}
		else
		{
			logp("error in rs_async: %d\n", sigresult);
			return -1;
		}
	}
	if(p1b->sendendofsig)
	{
		size_t l;
		const char *endfile="endfile";
		l=strlen(endfile);
		if(async_append_all_to_write_buffer(CMD_END_FILE, endfile, &l))
			return 1;
		//if(async_rw(NULL, NULL, NULL, NULL, NULL, &junk)) return -1;
		p1b->sendendofsig=0;
	}
	return 0;
}