Example #1
0
void *handle_client(void *arg) {
  int i, fd = *(int*)arg;
  if (nwrite(fd, &i, sizeof(int)) == -1) {
    perror("write");
    goto ERROR;
  }
  for (i = 0; i < NUM_CACL; i++) {
    int a, b, c;
    if (nread(fd, &a, sizeof(int)) == -1 || nread(fd, &b, sizeof(int)) == -1) {
      perror("read");
      LOCK_INC(calc_fail_count);
      goto ERROR;
    }
    a = ntohl(a);
    b = ntohl(b);
    c = htonl(a + b);
    if (nwrite(fd, &c, sizeof(int)) == -1) {
      perror("write");
      LOCK_INC(calc_fail_count);
      goto ERROR;
    }
    LOCK_INC(calc_success_count);
  }

ERROR:
  close(fd);
  free(arg);
  return NULL;
}
Example #2
0
void run(int fd)
{
  u_int16_t len;
  unsigned char *buffer;
  int loggedin;

  while(1) {
    nread(fd, &len, sizeof(len));
    len = ntohs(len);
    buffer = malloc(len);

    if(! buffer) errx(1, "malloc failure for %d bytes", len);

    nread(fd, buffer, len);

    switch(buffer[0]) {
      case 23: 
        loggedin = login(buffer + 1, len - 1);
        send_string(fd, 33, loggedin ? "successful" : "failed");
        break;
      
      default:
        send_string(fd, 58, "what you talkin about willis?");
        break;
    }
  }
}
Example #3
0
static void exchange_packet(int fd)
{
	char response[SIZE_RESPONSE];

	send_packet(fd);
	nread(fd, response, SIZE_RESPONSE);
}
Example #4
0
long sockbuf::howmanyc ()
// return how many chars are available for reading in the input buffer
// and the recvbuf of the socket.
{
    std::streamsize theShowMany = showmanyc();
    assert (theShowMany < INT_MAX);
    return (long)theShowMany + nread ();
}
Example #5
0
int md_read(char *buf, int bytes, int *source, int *type, int *flag)

{
  int i;

  i = nread(buf, bytes, source, type, flag);
  return i;

} /* md_read */
Example #6
0
int readreq()
{
    int r;
    if (skipsp()) goto readend;
    c = suck();
    if (c == EOF) goto readend;
    if (c == '\n') goto readend;
    if (c == '.') {
        while (1) {
            c = suck();
            if (c == EOF) break;
            if (c == '\n') break;
        }
        goto readend;
    }
    r = c << 9;
    c = suck();
    if (c != EOF) {
        if (c != '\n') {
            r = r | c;
        }
    }

    if (r==0157150) c = tread(ohead);	/* oh */
    if (r==0163160) {			/* sp */
        o_sp=nread();
        writebreak();
    }
    if (r==0164141) do_ta();		/* ta */
    if (r==0165154) o_ul=nread();		/* ul */

    while (1) {
        if (c == EOF) break;
        if (c == '\n') break;
        c= suck();
    }
readend:
    if (c != EOF)
        return(1);
    else
        return(0);
}
Example #7
0
static ber_slen_t
sb_stream_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
	assert( sbiod != NULL);
	assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

#if defined(MACOS)
/*
 * MacTCP/OpenTransport
 */
	return tcpread( sbiod->sbiod_sb->sb_fd, 0, (unsigned char *)buf,
		   len, NULL );

#elif defined( HAVE_PCNFS ) || \
   defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
/*
 * PCNFS (under DOS)
 */
/*
 * Windows Socket API (under DOS/Windows 3.x)
 */
/*
 * 32-bit Windows Socket API (under Windows NT or Windows 95)
 */
	{
		int rc;

		rc = recv( sbiod->sbiod_sb->sb_fd, buf, len, 0 );

#ifdef HAVE_WINSOCK
		if ( rc < 0 ) {
			int err;

			err = WSAGetLastError();
			errno = err;
		}
#endif

		return rc;
	}

#elif defined( HAVE_NCSA )
/*
 * NCSA Telnet TCP/IP stack (under DOS)
 */
	return nread( sbiod->sbiod_sb->sb_fd, buf, len );

#else
	return read( sbiod->sbiod_sb->sb_fd, buf, len );
#endif
}
Example #8
0
void do_ta()
{
    int v;
    n_ta = 0;
    while(1) {
        v=nread(v);
        if (v == 1)
            return;
        else {
            o_ta[n_ta] = v;
            n_ta++;
        }
        if (c == '\n') break;
        if (c == EOF) break;
    }
}
Example #9
0
int main(void)
{
    int sock_fd;
    if( (sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        ERR_EXIT("socket");
    struct sockaddr_in srv_addr;
    memset(&srv_addr, 0, sizeof(srv_addr));
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_port = htons(5566);
    srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(sock_fd,(struct sockaddr *)&srv_addr, sizeof(srv_addr)) < 0)
	ERR_EXIT("bind");
    if(listen(sock_fd, SOMAXCONN) < 0)
	ERR_EXIT("listen");
    int conn;
    int len = sizeof(srv_addr);
    if( (conn = accept(sock_fd, (struct sockaddr *)&srv_addr, &len)) < 0)  
        ERR_EXIT("accept");
    char recvbuf[1024] = {0};
    char sendbuf[1024] = {0};
    while(1)
    {
        memset(recvbuf, 0, sizeof(recvbuf));
        int ret = nread(conn, recvbuf, sizeof(recvbuf));
        if(ret < 0)
        {
            close(sock_fd);
            close(conn);
            ERR_EXIT("nread");
        }else if(ret == 0)
        {
            printf("Client is closed");
            break;
        }
        fputs(recvbuf, stdout);
        ret = nwrite(conn, recvbuf, sizeof(recvbuf));
        if(ret < 0)
        {
            close(conn);
            close(sock_fd);
            ERR_EXIT("nwrite");
        }
    }
    close(sock_fd);
    close(conn);	        
}
Example #10
0
void cos_init(void) {
	int i = 0;
	int ret;
	int data;
	void *buf_read, *buf_write;
	cbuf_t read_buffer, write_buffer;
	
	printc("pong init\n");
	if (replica_confirm(cos_spd_id())) BUG();

	/* Get our buffers*/
	write_buffer = get_write_buf(cos_spd_id());
	read_buffer = get_read_buf(cos_spd_id());
	buf_read = cbuf2buf(read_buffer, 1024);
	buf_write = cbuf2buf(write_buffer, 1024);
	printc("pong confirmed with buffers read (%d) and write(%d)\n", read_buffer, write_buffer);
	
	confirm_fork(cos_spd_id());
	
	while (i < N_ROUNDS) {	
		printc("\ni = %d, pong calling read from spdid %d\n", i, cos_spd_id());
		ret = nread(cos_spd_id(), 0, 1);
		assert(ret);
		data = *((int *) buf_read);
		printc("Thread %d: read returned %d and now we have data [%d]\n\n", cos_get_thd_id(), ret, data++);

		printc("\ni = %d, pong calling write\n", i);
		memcpy(buf_write, (void*)&data, 1);
		ret = nwrite(cos_spd_id(), 1, 1);
		assert(ret);
		printc("Thread %d: write returned %d\n\n", cos_get_thd_id(), ret);

		i++;
	}

	/* 
	 * This will actually never execute because this thread was put to sleep and once the last spd returns and exits, nothing is there to wake it up
	 * (minor edge case, voter_monitor would be the ideal place to fix 
	 */	
	printc("Spdid %d finished.\n", cos_spd_id());
}
Example #11
0
int
load_gesture_entry(int fd, PGconn* conn, int store_id) {
	struct gesture_entry entry;

	GET(fd, entry.name_len);
	deflip16(entry.name_len);

	entry.name = calloc(entry.name_len+1, 1);
	nread(fd, entry.name, entry.name_len);
	entry.name[entry.name_len] = '\0';

	GET(fd, entry.num_gestures);
	deflip32(entry.num_gestures);

	int entry_id = PG_EXEC_PARAMS(conn,
		"INSERT INTO gesture_entries (name, library_id) VALUES($1::text, $2::integer) RETURNING id",
		entry.name, itoa(store_id));

	for (ssize_t i = 0; i < entry.num_gestures; i++)
		if (load_gesture(fd, conn, entry_id) != 0) return 1;
	return 0;
}
Example #12
0
int md_wrap_wait(void *buf, int bytes, int *source, int *type, int *flag,
                 MPI_Request *request)

/*******************************************************************************

  Machine dependent wrapped message-wait communication routine for the Intel.
  This routine is identical to md_read but is put here in order to be compatible
  with the order required to do MPI communication.

  Author:          Scott A. Hutchinson, SNL, 9221
  =======

  Return code:     int
  ============

  Parameter list:
  ===============

  buf:             Beginning address of data to be sent.

  bytes:           Length of message in bytes.
  dest:            Destination processor number.

  type:            Message type

  flag:

*******************************************************************************/

{
  int i;

  i = nread(buf, bytes, source, type, flag);
  return i;

} /* md_wrap_wait */
Example #13
0
static ber_slen_t
sb_stream_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len )
{
    assert( sbiod != NULL);
    assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );

#if defined(MACOS)
    /*
     * MacTCP/OpenTransport
     */
    return tcpread( sbiod->sbiod_sb->sb_fd, 0, (unsigned char *)buf,
                    len, NULL );

#elif defined( HAVE_PCNFS ) || \
   defined( HAVE_WINSOCK ) || defined ( __BEOS__ )
    /*
     * PCNFS (under DOS)
     */
    /*
     * Windows Socket API (under DOS/Windows 3.x)
     */
    /*
     * 32-bit Windows Socket API (under Windows NT or Windows 95)
     */
    return recv( sbiod->sbiod_sb->sb_fd, (char*)buf, (int)len, 0 ); // This should be safe, as ret will not exceed 2G.

#elif defined( HAVE_NCSA )
    /*
     * NCSA Telnet TCP/IP stack (under DOS)
     */
    return nread( sbiod->sbiod_sb->sb_fd, buf, len );

#else
    return read( sbiod->sbiod_sb->sb_fd, buf, len );
#endif
}
Example #14
0
static void *_thread_working(void *arg)
{
	int fd = _fd;
	while (1) {
_failed:
		usleep(1000);
		struct serial_request *req = queue_pop(_Q, NULL);

		if (_check_command(req->buf, req->sz) == 0) {
			log_err("cmd error\n");
			free(req);
			goto _failed;
		}

		int num = 0;
		if (req->buf[1] == 0x30) {
			// DATA size + STX(1 byte) + ETX(1 byte) + SUM(2 byte)
			num = ((req->buf[6]-'0')*10 + (req->buf[7]-'0'))*2+4;
		} else {
			num = 1;
		}

		if (num > 64*2+4) {
			log_err("cmd error\n");
			free(req);
			goto _failed;
		}

		// write command
		int ret = nwrite(fd, req->buf, req->sz);
		if (ret < 0) {
			log_err("serial error\n");
			free(req);
			goto _failed;
		}

		_S->n_send++;
		
		char resp[4096];
		memset(resp, 0, sizeof(resp));

		for (;;) {
			struct timeval tv;
			memset(&tv, 0, sizeof(struct timeval));
			tv.tv_sec = 5;
			tv.tv_usec = 0;	

			fd_set rfds;
			FD_ZERO(&rfds);
			FD_SET(fd, &rfds);
	
			ret = select(fd+1, &rfds, NULL, NULL, &tv);
			if (ret == -1) {
				log_err("select error\n");
				free(req);
				goto _failed;
			} else if (ret == 0) {
				log_err("time expired\n");
				free(req);
				goto _failed;
			} else {
				int cnt = nread(fd, resp, num);
				if (cnt == -1) {
					log_err("serial error\n");
					free(req);
					goto _failed;
				}

				// call cb
				_S->n_recv++;
				req->cb(req->ud, resp, num);
				break;
			}
		}
	
		// free something
		free(req);
	}

	return (void *)NULL;
}
Example #15
0
int main(int argc,char *argv[]){
	int i,fd,nmaxconn,nfiles,maxfd,nconn,flags;
	char buf[MAXLINE];
	fd_set rs,ws;

	if(argc < 4)
		err_quit("usage : web <#conn> hostname homepage file1 ...");
	nmaxconn = atoi(argv[1]);

	nfiles = min(argc-4,MAXFILES);

	for(i=0;i<nfiles;i++){
		file[i].f_name = argv[4+i];
		file[i].f_host = argv[2];
		file[i].flags = 0;
	}
	home_page(argv[2],argv[3]);

	FD_ZERO(&rs);
	FD_ZERO(&ws);
	maxfd = -1;
	nconn = 0;
	nleftconn = nlefttoread = nfiles;

	while(nlefttoread > 0){
		while(nconn < nmaxconn && nleftconn > 0){
			for(i=0;i<nfiles;i++)
				if(file[i].flags != 0)
					break;
			if(i == nfiles)
				err_quit("nleftconn = %d but nothing found\n",nleftconn);
			start_connect(&file[i]);
			nconn++;
			nleftconn--;
		}
		rs = rset;
		ws = wset;
		Select(maxfd+1,&rset,&wset,NULL,NULL);
		
		for(i=0;i<nfiles;i++){
			flags = file[i].flags;
			if(flags == 0 || flags == F_DONE)
				continue;
			fd = file[i].f_fd;
			if(flags &  F_CONNECTING && (FD_ISSET(fd,&rset) || FD_ISSET(fd,&wset))){
				n=sizeof(error);
				if(getsockopt(fd,SOL_SOCKET,SO_ERROR,&error,&n) < 0 || error != 0)
					err_ret("nonblocking connect failed for %s\n",file[i].f_name);
				printf("connection established for %s\n",file[i].f_name);
				FD_CLR(fd,&wset);
				write_get_cmd(&file[i]);
			}else if(flags & F_READING && FD_ISSET(fd,&rset)){
				if((n = nread(fd,buf,sizeof(buf))) == 0){
					printf("end-of-file on %s\n",file[i].f_name);
					Close(fd);
					file[i].flags = F_DONE;
					FD_CLR(fd,&rset);
					nconn--;
					nlefconn--;
					nlefttoread--;
				}else {
					printf("read %d bytes from %s\n",n,file[i].f_name);
				}
			}
		}
	}
	exit(0);
}
Example #16
0
int ploop_copy_receiver(struct ploop_copy_receive_param *arg)
{
	int ofd, ret;
	__u64 cluster = 0;
	void *iobuf = NULL;
	int n;
	struct pcopy_pkt_desc desc;

	if (!arg)
		return SYSEXIT_PARAM;

	if (is_fd_socket(arg->ifd) != 1) {
		ploop_err(errno, "Invalid input fd %d: must be "
				"a pipe or a socket", arg->ifd);
		return SYSEXIT_PARAM;
	}

	ofd = open(arg->file, O_WRONLY|O_CREAT|O_TRUNC, 0600);
	if (ofd < 0) {
		ploop_err(errno, "Can't open %s", arg->file);
		return SYSEXIT_CREAT;
	}

	ploop_dbg(3, "RCV start %s", arg->file);
	for (;;) {
		if (nread(arg->ifd, &desc, sizeof(desc)) < 0) {
			ploop_err(errno, "Error in nread(desc)");
			ret = SYSEXIT_READ;
			goto out;
		}

		if (desc.marker != PCOPY_MARKER) {
			ploop_err(0, "Stream corrupted");
			ret = SYSEXIT_PROTOCOL;
			goto out;
		}

		if (desc.size > cluster) {
			free(iobuf);
			iobuf = NULL;
			cluster = desc.size;
			if (p_memalign(&iobuf, 4096, cluster)) {
				ret = SYSEXIT_MALLOC;
				goto out;
			}
		}

		if (desc.size == 0)
			break;

		if (nread(arg->ifd, iobuf, desc.size)) {
			ploop_err(errno, "Error in nread data");
			ret = SYSEXIT_READ;
			goto out;
		}

		ploop_log(3, "RCV type=%d len=%d pos=%" PRIu64,
				desc.type, desc.size, (uint64_t)desc.pos);
		ret = 0;
		switch (desc.type) {
		case PCOPY_PKT_DATA:
		case PCOPY_PKT_DATA_ASYNC: {
			n = TEMP_FAILURE_RETRY(pwrite(ofd, iobuf, desc.size, desc.pos));
			if (n != desc.size) {
				if (n < 0)
					ploop_err(errno, "Error in pwrite");
				else
					ploop_err(0, "Error: short pwrite");
				ret = SYSEXIT_WRITE;
				goto out;
			}
			break;
		}
		case PCOPY_PKT_CMD: {
			unsigned int cmd = ((unsigned int *) iobuf)[0];
			switch(cmd) {
			case PCOPY_CMD_SYNC:
				ret = data_sync(ofd);
				if (ret)
					goto out;
				break;
			default:
				ploop_err(0, "ploop_copy_receiver: unsupported command %d",
						cmd);
				ret = SYSEXIT_PARAM;
			}
			break;
		}
		default:
			ploop_err(0, "ploop_copy_receiver: unsupported command type%d",
						desc.type);
			ret = SYSEXIT_PARAM;
			break;
		}

		/* send reply */
		if (desc.type != PCOPY_PKT_DATA_ASYNC &&
				nwrite(arg->ifd, &ret, sizeof(int))) {
			ret = SYSEXIT_WRITE;
			ploop_err(errno, "failed to send reply");
			goto out;
		}
	}

	ret = data_sync(ofd);
	if (ret)
		goto out;

	ploop_dbg(3, "RCV exited");
	/* send final reply */
	ret = 0;
	if (nwrite(arg->ifd, &ret, sizeof(int))) {
		ret = SYSEXIT_WRITE;
		ploop_err(errno, "failed to send reply");
		goto out;
	}

out:
	if (close(ofd)) {
		ploop_err(errno, "Error in close");
		if (!ret)
			ret = SYSEXIT_WRITE;
	}
	if (ret)
		unlink(arg->file);
	free(iobuf);

	return ret;
}
Example #17
0
int main(void)
{
    int sock_fd;
    if( (sock_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        ERR_EXIT("socket");
    struct sockaddr_in srv_addr;
    memset(&srv_addr, 0, sizeof(srv_addr));
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_port = htons(5566);
    srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(sock_fd,(struct sockaddr *)&srv_addr, sizeof(srv_addr)) < 0)
	ERR_EXIT("bind");
    if(listen(sock_fd, SOMAXCONN) < 0)
	ERR_EXIT("listen");
    int conn;
    int len = sizeof(srv_addr);
    int client[FD_SETSIZE];
    int i;
    memset(client, -1, sizeof(client));
    fd_set allset;
    fd_set set;
    FD_ZERO(&set);
    FD_ZERO(&allset);
    FD_SET(sock_fd, &allset);
    set = allset;
    int maxfd = sock_fd + 1;
    while(1){
        set = allset;       
        int nready = select(maxfd, &set, NULL, NULL, NULL);
        if( nready < 0 )
        {
            if(errno == EINTR)
                continue;
            ERR_EXIT("select");
        }else if(nready == 0)
            continue;
        if(nready > 0)
        {
            if(FD_ISSET(sock_fd, &set))
            {
                if((conn = accept(sock_fd, (struct sockaddr *)&srv_addr, &len)) < 0)
                    ERR_EXIT("accept");
                if(conn >= maxfd)
                    maxfd = conn + 1;
                for(i=0; i<FD_SETSIZE; i++)
                {
                    if(client[i] == -1)
                    {
                        client[i] = conn;
                        FD_SET(conn, &allset);
                        break;
                    }
                }
                if(i >= FD_SETSIZE)
                {
                    printf("Too many conn\n");
                    continue;
                }
                if(nready == 0)
		    continue;
                    
            }
            char recvbuf[1024] = {0};
            for(i=0; i<FD_SETSIZE; i++)
            {
                if(FD_ISSET(client[i], &set))
                {
                   int ret = nread(client[i], recvbuf, sizeof(recvbuf));
                   if(ret < 0)
                   {
           	       if(errno == EINTR)
                           continue;
                       ERR_EXIT("nread"); 
                   }else if(ret == 0)
                   {
                       printf("client is closed\n");
                       FD_CLR(client[i], &allset);
                       close(client[i]);
                       client[i] = -1;
                       continue;
                   }
                   fputs(recvbuf, stdout);
                   ret = nwrite(client[i], recvbuf, sizeof(recvbuf));
                   if(ret < 0)
                   {
                       if(errno == EINTR)
                           continue;
                       ERR_EXIT("nwrite");
                   }
                   
                }
            }
        }
    }
    close(sock_fd);
    return 0;	        
}
Example #18
0
eaio::size_type eaio::readLine(IStream* pIS, char16_t* pLine, size_type nMaxCount, Endian endianSource)
{
    char16_t  cCurrent;
    size_type nCount(0); // Number of chars in the line, not including the line end characters(s).
    size_type nread(0);  // Number of chars successfully read from stream. Will be >= nCount (due to presence of newlines).
    size_type nResult;
    off_type  ninitialPosition(0);
    char16_t  cr, lf;

    if(!pLine)
        ninitialPosition = pIS->getPosition();

    if(endianSource == kEndianLocal)
    {
        cr = '\r';
        lf = '\n';
    }
    else
    {
        cr = SwizzleUint16('\r');
        lf = SwizzleUint16('\n');
    }

    for(;;)
    {
        // We are reading one character at a time, which can be slow if the stream is 
        // not buffered. We read one character at a time because we don't want to read
        // past the end of the line and thus trigger seeks, which may not even be possible
        // for some streams.
        nResult = pIS->read(&cCurrent, sizeof(cCurrent));

        if(nResult == sizeof(cCurrent))
        {
            ++nread;

            if((cCurrent == cr) || (cCurrent == lf))
            {
                // It's possible that we have a "\n" or "\r\n" sequence, and we want 
                // to read past the sequence, but not past anything else. This code here takes
                // care not to read past the first "\n" in a "\n\n" sequence, but is smart 
                // enough to read past the just first "\r\n" in a "\r\n\r\n" sequence.
                char16_t cNext = cCurrent;

                if(cCurrent == cr) // If we have a "\r", then we read again, expecting a "\n".
                    nResult = (size_type)pIS->read(&cNext, sizeof(cNext));

                if(cNext != lf)
                {
                    // We have encountered an unexpected sequence: We have a "\rx" instead of "\n" or "\r\n".
                    // This call requires a stream that can back up.
                    pIS->setPosition(-(off_type)sizeof(cNext), kPositionTypeCurrent);
                }

                break;
            }
            else
            {
                if(pLine && (nCount < (nMaxCount - 1))) // '- 1' because we want to leave room for terminating null.
                {
                    if(endianSource != kEndianLocal)
                        cCurrent = SwizzleUint16(cCurrent);

                    *pLine++ = cCurrent;
                }

                ++nCount;
            }
        }
        else
        {
            // In this case, there was nothing left to read in the file.
            // We need to differentiate between an empty line vs. nothing 
            // left to read in the file. To deal with that we return kSizeTypeDone.
            if(nread == 0)
                nCount = kSizeTypeDone;

            break;
        }
    }

    if(pLine)
        *pLine = 0;
    else
        pIS->setPosition(ninitialPosition);

    return nCount;
}
Example #19
0
File: pcopy.c Project: avagin/ploop
int ploop_copy_receive(struct ploop_copy_receive_param *arg)
{
	int ofd, ret;
	__u64 cluster = 0;
	void *iobuf = NULL;

	if (!arg)
		return SYSEXIT_PARAM;

	if (is_fd_pipe(arg->ifd) != 1) {
		ploop_err(errno, "Invalid input fd %d: must be "
				"a pipe or a socket", arg->ifd);
		return SYSEXIT_PARAM;
	}

	if (arg->feedback_fd >= 0 && is_fd_pipe(arg->feedback_fd) != 1) {
		ploop_err(errno, "Invalid feedback fd %d: must be "
				"a pipe or a socket", arg->feedback_fd);
		return SYSEXIT_PARAM;
	}

	/* If feedback is to be send to stdout or stderr,
	 * we have to disable logging to appropriate fd.
	 *
	 * As currently there's no way to disable just stderr,
	 * so in this case we have to disable stdout as well.
	 */
	if (arg->feedback_fd == STDOUT_FILENO)
		ploop_set_verbose_level(PLOOP_LOG_NOSTDOUT);
	else if (arg->feedback_fd == STDERR_FILENO)
		ploop_set_verbose_level(PLOOP_LOG_NOCONSOLE);

	ofd = open(arg->file, O_WRONLY|O_CREAT|O_EXCL, 0600);
	if (ofd < 0) {
		ploop_err(errno, "Can't open %s", arg->file);
		return SYSEXIT_CREAT;
	}

	/* Read data */
	for (;;) {
		int n;
		struct xfer_desc desc;

		if (nread(arg->ifd, &desc, sizeof(desc)) < 0) {
			ploop_err(errno, "Error in nread(desc)");
			ret = SYSEXIT_READ;
			goto out;
		}
		if (desc.marker != PLOOPCOPY_MARKER) {
			ploop_err(0, "Stream corrupted");
			ret = SYSEXIT_PROTOCOL;
			goto out;
		}
		if (desc.size > cluster) {
			free(iobuf);
			iobuf = NULL;
			cluster = desc.size;
			if (p_memalign(&iobuf, 4096, cluster)) {
				ret = SYSEXIT_MALLOC;
				goto out;
			}
		}
		if (desc.size == 0)
			break;

		if (nread(arg->ifd, iobuf, desc.size)) {
			ploop_err(errno, "Error in nread data");
			ret = SYSEXIT_READ;
			goto out;
		}
		if (desc.size == SYNC_MARK) {
			int st;
			/* ignore received data, instead do sync */
			st = fdatasync(ofd);
			if (arg->feedback_fd >= 0) {
				/* Tell the sending side how it went */
				int w;

				w = write(arg->feedback_fd,
					st ? STATUS_FAIL : STATUS_OK,
					LEN_STATUS);
				/* check write error only if no error yet */
				if (!st && w != LEN_STATUS) {
					ploop_err(errno, "Error in write(%d)",
							arg->feedback_fd);
					ret = SYSEXIT_WRITE;
					goto out;
				}
			}
			if (st) {
				ploop_err(errno, "Error in fdatasync()");
				ret = SYSEXIT_WRITE;
				goto out;
			}
			continue;
		}
		n = pwrite(ofd, iobuf, desc.size, desc.pos);
		if (n != desc.size) {
			if (n < 0)
				ploop_err(errno, "Error in pwrite");
			else
				ploop_err(0, "Error: short pwrite");
			ret = SYSEXIT_WRITE;
			goto out;
		}
	}

	if (fdatasync(ofd)) {
		ploop_err(errno, "Error in fdatasync");
		ret = SYSEXIT_WRITE;
		goto out;
	}

	ret = 0;

out:
	if (close(ofd)) {
		ploop_err(errno, "Error in close");
		if (!ret)
			ret = SYSEXIT_WRITE;
	}
	if (ret)
		unlink(arg->file);
	free(iobuf);

	return ret;
}