static int readv_test(uint repeat, uint msgsz, bool var) { uint i; ssize_t rc; size_t msg_len; int echo_fd = -1; char tx_buf [msgsz]; char rx0_buf[msgsz]; char rx1_buf[msgsz]; struct iovec iovs[2]= {{rx0_buf, 0}, {rx1_buf, 0}}; if (!opt_silent) { printf("%s: repeat %u: msgsz %u: variable %s\n", __func__, repeat, msgsz, var ? "true" : "false"); } echo_fd = tipc_connect(dev_name, echo_name); if (echo_fd < 0) { fprintf(stderr, "Failed to connect to service\n"); return echo_fd; } for (i = 0; i < repeat; i++) { msg_len = msgsz; if (opt_variable && msgsz) { msg_len = rand() % msgsz; } iovs[0].iov_len = msg_len / 3; iovs[1].iov_len = msg_len - iovs[0].iov_len; memset(tx_buf, i + 1, sizeof(tx_buf)); memset(rx0_buf, i + 2, iovs[0].iov_len); memset(rx1_buf, i + 3, iovs[1].iov_len); rc = write(echo_fd, tx_buf, msg_len); if (rc < 0) { perror("readv_test: write"); break; } if ((size_t)rc != msg_len) { fprintf(stderr, "%s: %s: data size mismatch (%zd vs. %zd)\n", __func__, "write", (size_t)rc, msg_len); break; } rc = readv(echo_fd, iovs, 2); if (rc < 0) { perror("readv_test: readv"); break; } if ((size_t)rc != msg_len) { fprintf(stderr, "%s: %s: data size mismatch (%zd vs. %zd)\n", __func__, "write", (size_t)rc, msg_len); break; } if (memcmp(rx0_buf, tx_buf, iovs[0].iov_len)) { fprintf(stderr, "%s: data mismatch: buf 0\n", __func__); break; } if (memcmp(rx1_buf, tx_buf + iovs[0].iov_len, iovs[1].iov_len)) { fprintf(stderr, "%s: data mismatch, buf 1\n", __func__); break; } } tipc_close(echo_fd); if (!opt_silent) { printf("%s: done\n",__func__); } return 0; }
int citp_pipe_splice_write(citp_fdinfo* fdi, int alien_fd, loff_t* alien_off, size_t olen, int flags, citp_lib_context_t* lib_context) { citp_pipe_fdi* epi = fdi_to_pipe_fdi(fdi); int len_in_bufs = OO_PIPE_SIZE_TO_BUFS(olen); struct iovec iov_on_stack[CITP_PIPE_SPLICE_WRITE_STACK_IOV_LEN]; struct iovec* iov = iov_on_stack; int want_buf_count; int rc; int bytes_to_read; int len = olen; int no_more = 1; /* for now we only run single loop */ int written_total = 0; int non_block = (flags & SPLICE_F_NONBLOCK) || (epi->pipe->aflags & (CI_PFD_AFLAG_NONBLOCK << CI_PFD_AFLAG_WRITER_SHIFT)); if( fdi_is_reader(fdi) ) { errno = EINVAL; return -1; } if( alien_off ) { /* TODO support this */ errno = ENOTSUP; return -1; } do { int count; int iov_num; int bytes_to_write; struct ci_pipe_pkt_list pkts = {}; struct ci_pipe_pkt_list pkts2; want_buf_count = len_in_bufs; /* We might need to wait for buffers here on the first iteration */ rc = ci_pipe_zc_alloc_buffers(epi->ni, epi->pipe, want_buf_count, MSG_NOSIGNAL | (non_block || written_total ? MSG_DONTWAIT : 0), &pkts); if( rc < 0 && written_total ) { /* whatever the error we need to report already written_bytes */ rc = written_total; break; } else if( rc < 0 ) break; else if( pkts.count == 0 && non_block ) { errno = EAGAIN; rc = -1; break; } else ci_assert_gt(pkts.count, 0); count = pkts.count; if( count > CITP_PIPE_SPLICE_WRITE_STACK_IOV_LEN ) { void* niov = realloc(iov == iov_on_stack ? NULL : iov, sizeof(*iov) * len_in_bufs); if( niov == NULL ) /* we can still move quite a few pkts */ count = CITP_PIPE_SPLICE_WRITE_STACK_IOV_LEN; else niov = iov; } ci_assert_ge(count, 1); iov_num = count; pkts2 = pkts; bytes_to_read = ci_pipe_list_to_iovec(epi->ni, epi->pipe, iov, &iov_num, &pkts2, len); citp_exit_lib_if(lib_context, TRUE); /* Note: the following call might be non-blocking as well as blocking */ rc = readv(alien_fd, iov, count); citp_reenter_lib(lib_context); if( rc > 0 ) { bytes_to_write = rc; written_total += bytes_to_write; len -= bytes_to_write; no_more |= bytes_to_write < bytes_to_read; } else { bytes_to_write = 0; no_more = 1; } { /* pipe zc_write will write non_empty buffers and release the empty * ones */ int rc2 = ci_pipe_zc_write(epi->ni, epi->pipe, &pkts, bytes_to_write, CI_PIPE_ZC_WRITE_FLAG_FORCE | MSG_DONTWAIT | MSG_NOSIGNAL); (void) rc2; ci_assert_equal(rc2, bytes_to_write); } /* for now we will not be doing second iteration, to allow for that * we'd need to have guarantee that read will not block * e.g. insight into type of fd and a nonblokcing operation * (to name a valid case: socket, recvmsg) */ } while( ! no_more ); if( iov != iov_on_stack ) free(iov); if( rc > 0 ) return written_total; if( rc < 0 && errno == EPIPE && ! (flags & MSG_NOSIGNAL) ) { ci_sys_ioctl(ci_netif_get_driver_handle(epi->ni), OO_IOC_KILL_SELF_SIGPIPE, NULL); } return rc; }
static void dotest(int testers, int me, int fd) { char *bits, *hold_bits; char val; int count, collide, chunk, whenmisc, xfr, i; /* Stuff for the readv call */ struct iovec r_iovec[MAXIOVCNT]; int r_ioveclen; /* Stuff for the writev call */ struct iovec val_iovec[MAXIOVCNT]; struct iovec zero_iovec[MAXIOVCNT]; int w_ioveclen; nchunks = max_size / csize; whenmisc = 0; if ((bits = malloc((nchunks+7) / 8)) == NULL) { tst_resm(TBROK, "\tmalloc failed(bits)"); tst_exit(); } if ((hold_bits = malloc((nchunks+7) / 8)) == NULL) { tst_resm(TBROK, "\tmalloc failed(hlod_bits)"); tst_exit(); } /*Allocate memory for the iovec buffers and init the iovec arrays */ r_ioveclen = w_ioveclen = csize / MAXIOVCNT; /* Please note that the above statement implies that csize * be evenly divisible by MAXIOVCNT. */ for (i = 0; i < MAXIOVCNT; i++) { if ((r_iovec[i].iov_base = calloc(r_ioveclen, 1)) == NULL) { tst_resm(TFAIL, "\tmalloc failed(r_iovec[i].iov_base)"); tst_exit(); } r_iovec[i].iov_len = r_ioveclen; /* Allocate unused memory areas between all the buffers to * make things more diffult for the OS. */ if (malloc((i+1)*8) == NULL) { tst_resm(TBROK, "\tmalloc failed((i+1)*8)"); tst_exit(); } if ((val_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) { tst_resm(TBROK, "\tmalloc failed(val_iovec[i]"); exit(1); } val_iovec[i].iov_len = w_ioveclen; if (malloc((i+1)*8) == NULL) { tst_resm(TBROK, "\tmalloc failed((i+1)*8)"); tst_exit(); } if ((zero_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) { tst_resm(TBROK, "\tmalloc failed(zero_iover)"); tst_exit(); } zero_iovec[i].iov_len = w_ioveclen; if (malloc((i+1)*8) == NULL) { tst_resm(TBROK, "\tmalloc failed((i+1)*8)"); tst_exit(); } } /* * No init sectors; allow file to be sparse. */ val = (64/testers) * me + 1; /* * For each iteration: * zap bits array * loop * pick random chunk, read it. * if corresponding bit off { * verify = 0. (sparse file) * ++count; * } else * verify = val. * write "val" on it. * repeat unitl count = nchunks. * ++val. */ srand(getpid()); if (misc_intvl) whenmisc = NEXTMISC; while (iterations-- > 0) { for (i = 0; i < NMISC; i++) misc_cnt[i] = 0; ftruncate(fd,0); file_max = 0; memset(bits, 0, (nchunks+7) / 8); memset(hold_bits, 0, (nchunks+7) / 8); /* Have to fill the val and zero iov buffers in a different manner */ for (i = 0; i < MAXIOVCNT; i++) { memset(val_iovec[i].iov_base,val,val_iovec[i].iov_len); memset(zero_iovec[i].iov_base,0,zero_iovec[i].iov_len); } count = 0; collide = 0; while (count < nchunks) { chunk = rand() % nchunks; /* * Read it. */ if (lseek64(fd, CHUNK(chunk), 0) < 0) { tst_resm(TFAIL, "\tTest[%d]: lseek64(0) fail at %Lx, errno = %d.", me, CHUNK(chunk), errno); tst_exit(); } if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) { tst_resm(TFAIL, "\tTest[%d]: readv fail at %Lx, errno = %d.", me, CHUNK(chunk), errno); tst_exit(); } /* * If chunk beyond EOF just write on it. * Else if bit off, haven't seen it yet. * Else, have. Verify values. */ if (CHUNK(chunk) >= file_max) { bits[chunk/8] |= (1<<(chunk%8)); ++count; } else if ((bits[chunk/8] & (1<<(chunk%8))) == 0) { if (xfr != csize) { tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, zero read.", me, xfr, csize); tst_exit(); } for (i = 0; i < MAXIOVCNT; i++) { if (memcmp(r_iovec[i].iov_base, zero_iovec[i].iov_base, r_iovec[i].iov_len)) { tst_resm(TFAIL, "\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x, should be 0.", me, CHUNK(chunk), val, count, xfr, file_max); tst_resm(TINFO, "\tTest[%d]: last_trunc = 0x%x.", me, last_trunc); sync(); ft_dumpiov(&r_iovec[i]); ft_dumpbits(bits, (nchunks+7)/8); ft_orbits(hold_bits, bits, (nchunks+7)/8); tst_resm(TINFO, "\tHold "); ft_dumpbits(hold_bits, (nchunks+7)/8); tst_exit(); } } bits[chunk/8] |= (1<<(chunk%8)); ++count; } else { if (xfr != csize) { tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, val read.", me, xfr, csize); tst_exit(); } ++collide; for (i = 0; i < MAXIOVCNT; i++) { if (memcmp(r_iovec[i].iov_base, val_iovec[i].iov_base, r_iovec[i].iov_len)) { tst_resm(TFAIL, "\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x.", me, CHUNK(chunk), val, count, xfr, file_max); tst_resm(TINFO, "\tTest[%d]: last_trunc = 0x%x.", me, last_trunc); sync(); ft_dumpiov(&r_iovec[i]); ft_dumpbits(bits, (nchunks+7)/8); ft_orbits(hold_bits, bits, (nchunks+7)/8); tst_resm(TINFO, "\tHold "); ft_dumpbits(hold_bits, (nchunks+7)/8); tst_exit(); } } } /* * Writev it. */ if (lseek64(fd, -((off64_t)xfr), 1) < 0) { tst_resm(TFAIL, "\tTest[%d]: lseek64(1) fail at %Lx, errno = %d.", me, CHUNK(chunk), errno); tst_exit(); } if ((xfr = writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) { if (errno == ENOSPC) { tst_resm(TFAIL, "\tTest[%d]: no space, exiting.", me); fsync(fd); tst_exit(); } tst_resm(TFAIL, "\tTest[%d]: writev fail at %Lx xfr %d, errno = %d.", me, CHUNK(chunk), xfr, errno); tst_exit(); } if (CHUNK(chunk) + csize > file_max) file_max = CHUNK(chunk) + csize; /* * If hit "misc" interval, do it. */ if (misc_intvl && --whenmisc <= 0) { ft_orbits(hold_bits, bits, (nchunks+7)/8); domisc(me, fd, bits); whenmisc = NEXTMISC; } if (count + collide > 2 * nchunks) break; } /* * End of iteration, maybe before doing all chunks. */ fsync(fd); ++misc_cnt[m_fsync]; //tst_resm(TINFO, "\tTest{%d} val %d done, count = %d, collide = {%d}", // me, val, count, collide); //for (i = 0; i < NMISC; i++) // tst_resm(TINFO, "\t\tTest{%d}: {%d} %s's.", me, misc_cnt[i], m_str[i]); ++val; } }
int main(void) { int nbytes; /* Fill the buf_list[0] and buf_list[1] with 0 zeros */ buf_list[0] = buf1; buf_list[1] = buf2; memset(buf_list[0], 0, K_1); memset(buf_list[1], 0, K_1); if ((fd = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) { fprintf(stderr, "open(2) failed: fname = %s, errno = %d\n", f_name, errno); return 1; } else if ((nbytes = write(fd, buf_list[1], K_1)) != K_1) { fprintf(stderr, "write(2) failed: nbytes = %d, errno = %d\n", nbytes, errno); return 1; } if (close(fd) < 0) { fprintf(stderr, "close failed: errno = %d\n", errno); return 1; } fprintf(stderr, "Test file created.\n"); if ((fd = open(f_name, O_RDWR, 0666)) < 0) { fprintf(stderr, "open failed: fname = %s, errno = %d\n", f_name, errno); return 1; } lseek(fd, 0, 0); if (writev(fd, wr_iovec, 2) < 0) { if (errno == EFAULT) fprintf(stderr, "Received EFAULT as expected\n"); else fprintf(stderr, "Expected EFAULT, got %d\n", errno); lseek(fd, K_1, 0); if ((nbytes = read(fd, buf_list[0], CHUNK)) != 0) fprintf(stderr, "Expected nbytes = 0, got %d\n", nbytes); } else fprintf(stderr, "Error writev returned a positive value\n"); // Now check invalid vector count if (writev(fd, wr_iovec, -1) < 0) { if (errno == EINVAL) fprintf(stderr, "Received EINVAL as expected\n"); else fprintf(stderr, "expected errno = EINVAL, got %d\n", errno); } else fprintf(stderr, "Error writev returned a positive value\n"); if (readv(fd, wr_iovec, -1) < 0) { if (errno == EINVAL) fprintf(stderr, "Received EINVAL as expected\n"); else fprintf(stderr, "expected errno = EINVAL, got %d\n", errno); } else fprintf(stderr, "Error writev returned a positive value\n"); unlink(f_name); return 0; }
static ssize_t pcap_sg_read_pcap_pkt(int fd, struct pcap_pkthdr *hdr, uint8_t *packet, size_t len) { /* In contrast to writing, reading gets really ugly ... */ spinlock_lock(&lock); if (likely(avail - used >= sizeof(*hdr) && iov[c].iov_len - iov_used >= sizeof(*hdr))) { __memcpy_small(hdr, iov[c].iov_base + iov_used, sizeof(*hdr)); iov_used += sizeof(*hdr); used += sizeof(*hdr); } else { size_t remainder, offset = 0; if (avail - used < sizeof(*hdr)) return -ENOMEM; offset = iov[c].iov_len - iov_used; remainder = sizeof(*hdr) - offset; assert(offset + remainder == sizeof(*hdr)); __memcpy_small(hdr, iov[c].iov_base + iov_used, offset); used += offset; iov_used = 0; c++; if (c == IOVSIZ) { /* We need to refetch! */ c = 0; avail = readv(fd, iov, IOVSIZ); if (avail < 0) return -EIO; used = 0; } /* Now we copy the remainder and go on with business ... */ __memcpy_small(hdr, iov[c].iov_base + iov_used, remainder); iov_used += remainder; used += remainder; } if (likely(avail - used >= hdr->len && iov[c].iov_len - iov_used >= hdr->len)) { __memcpy(packet, iov[c].iov_base + iov_used, hdr->len); iov_used += hdr->len; used += hdr->len; } else { size_t remainder, offset = 0; if (avail - used < hdr->len) return -ENOMEM; offset = iov[c].iov_len - iov_used; remainder = hdr->len - offset; assert(offset + remainder == hdr->len); __memcpy(packet, iov[c].iov_base + iov_used, offset); used += offset; iov_used = 0; c++; if (c == IOVSIZ) { /* We need to refetch! */ c = 0; avail = readv(fd, iov, IOVSIZ); if (avail < 0) return -EIO; used = 0; } /* Now we copy the remainder and go on with business ... */ __memcpy(packet, iov[c].iov_base + iov_used, remainder); iov_used += remainder; used += remainder; } spinlock_unlock(&lock); if (unlikely(hdr->len == 0)) return -EINVAL; /* Bogus packet */ return sizeof(*hdr) + hdr->len; }
static void dotest(int testers, int me, int fd) { char *bits; char val, val0; int count, collide, chunk, whenmisc, xfr, i; /* Stuff for the readv call */ struct iovec r_iovec[MAXIOVCNT]; int r_ioveclen; /* Stuff for the writev call */ struct iovec val0_iovec[MAXIOVCNT]; struct iovec val_iovec[MAXIOVCNT]; int w_ioveclen; nchunks = max_size / (testers * csize); whenmisc = 0; if ((bits = malloc((nchunks + 7) / 8)) == NULL) { tst_resm(TBROK, "\tmalloc failed(bits)"); tst_exit(); } /* Allocate memory for the iovec buffers and init the iovec arrays */ r_ioveclen = w_ioveclen = csize / MAXIOVCNT; /* Please note that the above statement implies that csize * be evenly divisible by MAXIOVCNT. */ for (i = 0; i < MAXIOVCNT; i++) { if ((r_iovec[i].iov_base = malloc(r_ioveclen)) == NULL) { tst_resm(TBROK, "\tmalloc failed(iov_base)"); tst_exit(); } r_iovec[i].iov_len = r_ioveclen; /* Allocate unused memory areas between all the buffers to * make things more diffult for the OS. */ if (malloc((i + 1) * 8) == NULL) { tst_resm(TBROK, "\tmalloc failed((i+1)*8)"); tst_exit(); } if ((val0_iovec[i].iov_base = malloc(w_ioveclen)) == NULL) { tst_resm(TBROK, "\tmalloc failed(val0_iovec)"); tst_exit(); } val0_iovec[i].iov_len = w_ioveclen; if (malloc((i + 1) * 8) == NULL) { tst_resm(TBROK, "\tmalloc failed((i+1)*8)"); tst_exit(); } if ((val_iovec[i].iov_base = malloc(w_ioveclen)) == NULL) { tst_resm(TBROK, "\tmalloc failed(iov_base)"); tst_exit(); } val_iovec[i].iov_len = w_ioveclen; if (malloc((i + 1) * 8) == NULL) { tst_resm(TBROK, "\tmalloc failed(((i+1)*8)"); tst_exit(); } } /* * No init sectors; file-sys makes 0 to start. */ val = (64 / testers) * me + 1; val0 = 0; /* * For each iteration: * zap bits array * loop: * pick random chunk, read it. * if corresponding bit off { * verify == 0. (sparse file) * ++count; * } else * verify == val. * write "val" on it. * repeat until count = nchunks. * ++val. */ srand(getpid()); if (misc_intvl) whenmisc = NEXTMISC; while (iterations-- > 0) { for (i = 0; i < NMISC; i++) misc_cnt[i] = 0; memset(bits, 0, (nchunks + 7) / 8); /* Have to fill the val0 and val iov buffers in a different manner */ for (i = 0; i < MAXIOVCNT; i++) { memset(val0_iovec[i].iov_base, val0, val0_iovec[i].iov_len); memset(val_iovec[i].iov_base, val, val_iovec[i].iov_len); } count = 0; collide = 0; while (count < nchunks) { chunk = rand() % nchunks; /* * Read it. */ if (lseek64(fd, CHUNK(chunk), 0) < 0) { tst_resm(TFAIL, "\tTest[%d]: lseek64(0) fail at %" PRIx64 "x, errno = %d.", me, CHUNK(chunk), errno); tst_exit(); } if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) { tst_resm(TFAIL, "\tTest[%d]: readv fail at %" PRIx64 "x, errno = %d.", me, CHUNK(chunk), errno); tst_exit(); } /* * If chunk beyond EOF just write on it. * Else if bit off, haven't seen it yet. * Else, have. Verify values. */ if (xfr == 0) { bits[chunk / 8] |= (1 << (chunk % 8)); } else if ((bits[chunk / 8] & (1 << (chunk % 8))) == 0) { if (xfr != csize) { tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, zero read.", me, xfr, csize); tst_exit(); } for (i = 0; i < MAXIOVCNT; i++) { if (memcmp (r_iovec[i].iov_base, val0_iovec[i].iov_base, r_iovec[i].iov_len)) { tst_resm(TFAIL, "\tTest[%d] bad verify @ 0x%" PRIx64 " for val %d count %d xfr %d.", me, CHUNK(chunk), val0, count, xfr); ft_dumpiov(&r_iovec[i]); ft_dumpbits(bits, (nchunks + 7) / 8); tst_exit(); } } bits[chunk / 8] |= (1 << (chunk % 8)); ++count; } else { if (xfr != csize) { tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, val read.", me, xfr, csize); tst_exit(); } ++collide; for (i = 0; i < MAXIOVCNT; i++) { if (memcmp (r_iovec[i].iov_base, val_iovec[i].iov_base, r_iovec[i].iov_len)) { tst_resm(TFAIL, "\tTest[%d] bad verify @ 0x%" PRIx64 " for val %d count %d xfr %d.", me, CHUNK(chunk), val, count, xfr); ft_dumpiov(&r_iovec[i]); ft_dumpbits(bits, (nchunks + 7) / 8); tst_exit(); } } } /* * Write it. */ if (lseek64(fd, -xfr, 1) < 0) { tst_resm(TFAIL, "\tTest[%d]: lseek64(1) fail at %" PRIx64 ", errno = %d.", me, CHUNK(chunk), errno); tst_exit(); } if ((xfr = writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) { if (errno == ENOSPC) { tst_resm(TFAIL, "\tTest[%d]: no space, exiting.", me); fsync(fd); tst_exit(); } tst_resm(TFAIL, "\tTest[%d]: writev fail at %" PRIx64 "x xfr %d, errno = %d.", me, CHUNK(chunk), xfr, errno); tst_exit(); } /* * If hit "misc" interval, do it. */ if (misc_intvl && --whenmisc <= 0) { domisc(me, fd); whenmisc = NEXTMISC; } if (count + collide > 2 * nchunks) break; } /* * End of iteration, maybe before doing all chunks. */ if (count < nchunks) { //tst_resm(TINFO, "\tTest{%d} val %d stopping @ %d, collide = {%d}.", // me, val, count, collide); for (i = 0; i < nchunks; i++) { if ((bits[i / 8] & (1 << (i % 8))) == 0) { if (lseek64(fd, CHUNK(i), 0) < (off64_t) 0) { tst_resm(TFAIL, "\tTest[%d]: lseek64 fail at %" PRIx64 "x, errno = %d.", me, CHUNK(i), errno); tst_exit(); } if (writev(fd, &val_iovec[0], MAXIOVCNT) != csize) { tst_resm(TFAIL, "\tTest[%d]: writev fail at %" PRIx64 "x, errno = %d.", me, CHUNK(i), errno); tst_exit(); } } } } fsync(fd); ++misc_cnt[m_fsync]; //tst_resm(TINFO, "\tTest[%d] val %d done, count = %d, collide = %d.", // me, val, count, collide); //for (i = 0; i < NMISC; i++) // tst_resm(TINFO, "\t\tTest[%d]: %d %s's.", me, misc_cnt[i], m_str[i]); val0 = val++; } }
int doErrorTest(void) { FILE *fp; int fd; struct iovec vec[4]; int rc; /* * Open and close the file to get a bad file descriptor */ fp = fopen(TESTFILE, "wt"); if ( fp == NULL ) { printf( "fopen for error 1: %d=%s\n", errno, strerror(errno)); return FALSE; } fd = fileno(fp); fclose(fp); /* writev -- bad file descriptor */ puts("writev bad file descriptor -- EBADF"); rc = writev(fd, vec, 4); if ( (rc != -1) || (errno != EBADF) ) { printf( "writev error 1: %d=%s\n", errno, strerror(errno) ); return FALSE; } /* readv -- bad file descriptor */ puts("readv bad file descriptor -- EBADF"); rc = read(fd, vec, 4); if ( (rc != -1) || (errno != EBADF) ) { printf( "readv error 1: %d=%s\n", errno, strerror(errno) ); return FALSE; } /* * Open the file for the rest of the tests */ fp = fopen(TESTFILE, "w+"); if ( fp == NULL ) { printf( "fopen for error 2: %d=%s\n", errno, strerror(errno)); return FALSE; } fd = fileno(fp); /* writev -- bad iovec pointer */ puts("writev bad iovec pointer -- EINVAL"); rc = writev(fd, NULL, 4); if ( (rc != -1) || (errno != EINVAL) ) { printf( "writev error 2: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* readv -- bad iovec pointer */ puts("readv bad iovec pointer -- EINVAL"); rc = readv(fd, NULL, 4); if ( (rc != -1) || (errno != EINVAL) ) { printf( "readv error 2: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* writev -- bad iovcnt 0 */ puts("readv bad iovcnt of 0 -- EINVAL"); rc = writev(fd, vec, 0); if ( (rc != -1) || (errno != EINVAL) ) { printf( "writev error 3: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* readv -- bad iovcnt 0 */ puts("readv bad iovcnt of 0 -- EINVAL"); rc = readv(fd, vec, 0); if ( (rc != -1) || (errno != EINVAL) ) { printf( "readv error 3: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* writev -- bad iovcnt negative */ puts("writev bad iovcnt negative -- EINVAL"); rc = writev(fd, vec, -2); if ( (rc != -1) || (errno != EINVAL) ) { printf( "writev error 4: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* readv -- bad iovcnt negative */ puts("readv bad iovcnt negative -- EINVAL"); rc = readv(fd, vec, -100); if ( (rc != -1) || (errno != EINVAL) ) { printf( "readv error 4: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* writev -- bad iov[i].iov_base */ vec[0].iov_base = vec; vec[0].iov_len = 100; vec[1].iov_base = NULL; vec[1].iov_len = 100; puts("writev bad iov[i].iov_base -- EINVAL"); rc = writev(fd, vec, 2); if ( (rc != -1) || (errno != EINVAL) ) { printf( "writev error 5: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* readv -- bad iov[i].iov_base */ vec[0].iov_base = vec; vec[0].iov_len = 100; vec[1].iov_base = NULL; vec[1].iov_len = 100; puts("readv bad iov[i].iov_base -- EINVAL"); rc = readv(fd, vec, 2); if ( (rc != -1) || (errno != EINVAL) ) { printf( "readv error 5: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* writev -- bad iov[i].iov_len < 0 */ vec[0].iov_base = vec; vec[0].iov_len = 100; vec[1].iov_base = vec; vec[1].iov_len = -10; puts("writev bad iov[i].iov_len < 0 -- EINVAL"); rc = writev(fd, vec, 2); if ( (rc != -1) || (errno != EINVAL) ) { printf( "writev error 6: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* readv -- bad iov[i].iov_len = 0 */ vec[0].iov_base = vec; vec[0].iov_len = 100; vec[1].iov_base = vec; vec[1].iov_len = -1024; puts("readv bad iov[i].iov_len = 0 -- EINVAL"); rc = readv(fd, vec, 2); if ( (rc != -1) || (errno != EINVAL) ) { printf( "readv error 6: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* writev -- iov_len total overflows */ vec[0].iov_base = vec; vec[0].iov_len = SIZE_MAX; vec[1].iov_base = vec; vec[1].iov_len = SIZE_MAX; vec[2].iov_base = vec; vec[2].iov_len = SIZE_MAX; puts("writev iov_len total overflows -- EINVAL"); rc = writev(fd, vec, 3); if ( (rc != -1) || (errno != EINVAL) ) { printf( "writev error 7: rc=%d %d=%s\n", rc, errno, strerror(errno) ); fclose(fp); return FALSE; } /* readv -- iov_len total overflows */ vec[0].iov_base = vec; vec[0].iov_len = SIZE_MAX; vec[1].iov_base = vec; vec[1].iov_len = SIZE_MAX; puts("readv iov_len total overflows -- EINVAL"); rc = readv(fd, vec, 2); if ( (rc != -1) || (errno != EINVAL) ) { printf( "read error 7: rc=%d %d=%s\n", rc, errno, strerror(errno) ); fclose(fp); return FALSE; } /* writev -- all zero length buffers */ vec[0].iov_base = vec; vec[0].iov_len = 0; vec[1].iov_base = vec; vec[1].iov_len = 0; puts("writev iov_len works with no effect -- OK"); rc = writev(fd, vec, 2); if ( (rc != 0) ) { printf( "writev error 8: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } /* readv -- all zero length buffers */ vec[0].iov_base = vec; vec[0].iov_len = 0; vec[1].iov_base = vec; vec[1].iov_len = 0; puts("readv iov_len works with no effect -- OK"); rc = readv(fd, vec, 2); if ( (rc != 0) ) { printf( "readv error 8: %d=%s\n", errno, strerror(errno) ); fclose(fp); return FALSE; } fclose(fp); return TRUE; }
void do_with_fd( int fd, const char *description ) { struct stat stat_buff; struct iovec vec[4]; off_t res; int status; printf("ftruncate %s\n", description); status = ftruncate(fd, 40); rtems_test_assert( status == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); printf("_fcntl_r %s\n", description); status = _fcntl_r( NULL, fd, F_SETFD, 1 ); rtems_test_assert( status == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); printf("fdatasync %s\n", description); status = fdatasync( fd ); rtems_test_assert( status == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); printf("fstat %s\n", description); status = fstat( fd, &stat_buff ); rtems_test_assert( status == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); printf("fsync %s\n", description); status = fsync( fd ); rtems_test_assert( status == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); printf("ioctl %s\n", description); status = ioctl( fd, 0 ); rtems_test_assert( status == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); printf("_lseek_r %s\n", description); res = _lseek_r (NULL, fd, 0, SEEK_SET); rtems_test_assert( res == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); printf("readv %s\n", description); status = readv(fd, vec, 4); rtems_test_assert( status == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); printf("writev %s\n", description); status = writev(fd, vec, 4); rtems_test_assert( status == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); printf("write %s\n", description); status = write(fd, "1234", 4); rtems_test_assert( status == -1 ); printf( "%d: %s\n", errno, strerror( errno ) ); rtems_test_assert( errno == EBADF ); }
tempfd = fd = mkstemp (fname); if (fd == -1) FAIL_EXIT1 ("mkstemp failed: %m"); unlink (fname); xpthread_barrier_wait (&b2); } xpthread_barrier_wait (&b2); ssize_t s; pthread_cleanup_push (cl, NULL); char buf[100]; struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } }; s = readv (fd, iov, 1); pthread_cleanup_pop (0); FAIL_EXIT1 ("readv returns with %zd", s); } static void * tf_write (void *arg) { int fd; if (arg == NULL) fd = fds[1]; else
void primorial_gaps(const char *store, uint64_t num) { uint64_t reprimes[REPRIMES + 1]; uint64_t primes[SMALLPRIMES]; printf("1 = 3 - 2\n"); printf("2 = 5 - 3\n"); printf("4 = 11 - 7\n"); uint64_t pcount = reprime_generate(reprimes, primes, SMALLPRIMES); uint64_t last_prime = 13; uint64_t greatest_gap = 4; int i; for (i = 0; i < pcount; i++) { if (primes[i] - last_prime > greatest_gap) { greatest_gap = primes[i] - last_prime; printf("%llu = %llu - %llu\n", (unsigned long long)greatest_gap, (unsigned long long)primes[i], (unsigned long long)last_prime); } last_prime = primes[i]; } struct iovec vectors[2]; unsigned char junk[8192 - REPRIMES / 8]; vectors[0].iov_base = junk; vectors[0].iov_len = 8192 - REPRIMES / 8; unsigned char reprime_bits[REPRIMES / 8]; vectors[1].iov_base = reprime_bits; vectors[1].iov_len = REPRIMES / 8; int fd = open(store, O_RDONLY); if (fd == -1) { fprintf(stderr, "could not open file: %s\n", store); exit(IO_ERR); } struct stat st; if (fstat(fd, &st) == -1) { fprintf(stderr, "could not stat file: %s\n", store); close(fd); exit(IO_ERR); } off_t pages = st.st_size / 8192; off_t page; for (page = 1; page <= pages; page++) { if (readv(fd, vectors, 2) != 8192) { fprintf(stderr, "could not read full page\n"); close(fd); exit(IO_ERR); } uint64_t base = (uint64_t)MODULUS * page; int reprime_offset; for (reprime_offset = 0; reprime_offset < REPRIMES; reprime_offset++) { if (reprime_bits[reprime_offset / 8] & (1U << reprime_offset % 8)) { uint64_t current_prime = base + reprimes[reprime_offset]; uint64_t current_gap = current_prime - last_prime; if (current_gap > greatest_gap) { printf("%llu = %llu - %llu\n", (unsigned long long)current_gap, (unsigned long long)current_prime, (unsigned long long)last_prime); greatest_gap = current_gap; } last_prime = current_prime; } } } close(fd); exit(0); }
int MPID_nem_tcp_module_lmt_start_recv (MPIDI_VC_t *vc, MPID_Request *req) { int mpi_errno = MPI_SUCCESS; int ret; MPIDI_msg_sz_t data_sz; int dt_contig; MPI_Aint dt_true_lb; MPID_Datatype * dt_ptr; MPIDI_msg_sz_t last; int nb; int r_len; MPIDI_CH3I_VC *vc_ch = (MPIDI_CH3I_VC *)vc->channel_private; MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_TCP_MODULE_LMT_START_RECV); MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_TCP_MODULE_LMT_START_RECV); free_cookie (vc_ch->net.tcp.lmt_cookie); if (!vc_ch->net.tcp.lmt_connected) { int len; struct sockaddr_in saddr; int connfd; len = sizeof (saddr); connfd = accept (vc_ch->net.tcp.lmt_desc, (struct sockaddr *)&saddr, &len); MPIU_ERR_CHKANDJUMP2 (connfd == -1, mpi_errno, MPI_ERR_OTHER, "**sock|poll|accept", "**sock|poll|accept %d %s", errno, strerror (errno)); /* close listen fd */ do ret = close (vc_ch->net.tcp.lmt_desc); while (ret == -1 && errno == EINTR); MPIU_ERR_CHKANDJUMP2 (ret == -1, mpi_errno, MPI_ERR_OTHER, "**closesocket", "**closesocket %s %d", strerror (errno), errno); /* set lmt_desc to new connected fd */ vc_ch->net.tcp.lmt_desc = connfd; vc_ch->net.tcp.lmt_connected = 1; // ret = fcntl (vc_ch->net.tcp.lmt_desc, F_SETFL, O_NONBLOCK); // MPIU_ERR_CHKANDJUMP2 (ret == -1, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %s %d", strerror (errno), errno); } MPIDI_Datatype_get_info (req->dev.user_count, req->dev.datatype, dt_contig, data_sz, dt_ptr, dt_true_lb); if (data_sz > vc_ch->net.tcp.lmt_s_len) { data_sz = vc_ch->net.tcp.lmt_s_len; } else if (data_sz < vc_ch->net.tcp.lmt_s_len) { /* message will be truncated */ r_len = data_sz; req->status.MPI_ERROR = MPIU_ERR_SET2 (mpi_errno, MPI_ERR_TRUNCATE, "**truncate", "**truncate %d %d", vc_ch->net.tcp.lmt_s_len, r_len); } MPID_Segment_init (req->dev.user_buf, req->dev.user_count, req->dev.datatype, &req->dev.segment, 0); req->dev.segment_first = 0; req->dev.segment_size = data_sz; req->dev.iov_count = MPID_IOV_LIMIT; req->dev.iov_offset = 0; last = data_sz; do { int iov_offset; int left_to_recv; MPID_Segment_unpack_vector (&req->dev.segment, req->dev.segment_first, &last, req->dev.iov, &req->dev.iov_count); left_to_recv = last - req->dev.segment_first; iov_offset = 0; #ifdef TESTING_CHUNKING { char *buf = req->dev.iov[0].MPID_IOV_BUF; int l; while (left_to_recv) { if (left_to_recv > CHUNK) l = CHUNK; else l = left_to_recv; do nb = read (vc_ch->net.tcp.lmt_desc, buf, l); while (nb == -1 && errno == EINTR); MPIU_ERR_CHKANDJUMP (nb == -1, mpi_errno, MPI_ERR_OTHER, "**sock_writev"); left_to_recv -= nb; buf += nb; } MPIDI_CH3U_Request_complete (req); goto fn_exit; } #endif do nb = readv (vc_ch->net.tcp.lmt_desc, &req->dev.iov[iov_offset], req->dev.iov_count - iov_offset); while (nb == -1 && errno == EINTR); MPIU_ERR_CHKANDJUMP2 (nb == -1, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %s %d", strerror (errno), errno); MPIU_ERR_CHKANDJUMP (nb == 0, mpi_errno, MPI_ERR_OTHER, "**fail"); left_to_recv -= nb; while (left_to_recv) { /* recv rest of iov */ while (nb >= req->dev.iov[iov_offset].MPID_IOV_LEN) { /* update iov to reflect sent bytes */ nb -= req->dev.iov[iov_offset].MPID_IOV_LEN; ++iov_offset; } req->dev.iov[iov_offset].MPID_IOV_BUF = (char *)req->dev.iov[iov_offset].MPID_IOV_BUF + nb; req->dev.iov[iov_offset].MPID_IOV_LEN -= nb; do nb = readv (vc_ch->net.tcp.lmt_desc, &req->dev.iov[iov_offset], req->dev.iov_count - iov_offset); while (nb == -1 && errno == EINTR); MPIU_ERR_CHKANDJUMP2 (nb == -1, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %s %d", strerror (errno), errno); MPIU_ERR_CHKANDJUMP (nb == 0, mpi_errno, MPI_ERR_OTHER, "**fail"); left_to_recv -= nb; } } while (last < data_sz); MPIDI_CH3U_Request_complete (req); fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_TCP_MODULE_LMT_START_RECV); return mpi_errno; fn_fail: goto fn_exit; }
/* * Read from so's socket into sb_snd, updating all relevant sbuf fields * NOTE: This will only be called if it is select()ed for reading, so * a read() of 0 (or less) means it's disconnected */ int soread(struct socket *so) { int n, nn; struct sbuf *sb = &so->so_snd; struct iovec iov[2]; DEBUG_CALL("soread"); DEBUG_ARG("so = %p", so); /* * No need to check if there's enough room to read. * soread wouldn't have been called if there weren't */ sopreprbuf(so, iov, &n); #ifdef HAVE_READV nn = readv(so->s, (struct iovec *)iov, n); DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); #else nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0); #endif if (nn <= 0) { if (nn < 0 && (errno == EINTR || errno == EAGAIN)) return 0; else { int err; socklen_t slen = sizeof err; err = errno; if (nn == 0) { getsockopt(so->s, SOL_SOCKET, SO_ERROR, &err, &slen); } DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno))); sofcantrcvmore(so); if (err == ECONNRESET || err == ECONNREFUSED || err == ENOTCONN || err == EPIPE) { tcp_drop(sototcpcb(so), err); } else { tcp_sockclosed(sototcpcb(so)); } return -1; } } #ifndef HAVE_READV /* * If there was no error, try and read the second time round * We read again if n = 2 (ie, there's another part of the buffer) * and we read as much as we could in the first read * We don't test for <= 0 this time, because there legitimately * might not be any more data (since the socket is non-blocking), * a close will be detected on next iteration. * A return of -1 won't (shouldn't) happen, since it didn't happen above */ if (n == 2 && nn == iov[0].iov_len) { int ret; ret = qemu_recv(so->s, iov[1].iov_base, iov[1].iov_len,0); if (ret > 0) nn += ret; } DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn)); #endif /* Update fields */ sb->sb_cc += nn; sb->sb_wptr += nn; if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen)) sb->sb_wptr -= sb->sb_datalen; return nn; }
int32_t TransportUDP::read(uint8_t* buffer, uint32_t size) { { boost::mutex::scoped_lock lock(close_mutex_); if (closed_) { ROSCPP_LOG_DEBUG("Tried to read on a closed socket [%d]", sock_); return -1; } } ROS_ASSERT((int32_t)size > 0); uint32_t bytes_read = 0; while (bytes_read < size) { TransportUDPHeader header; // Get the data either from the reorder buffer or the socket // copy_bytes will contain the read size. // from_previous is true if the data belongs to the previous UDP datagram. uint32_t copy_bytes = 0; bool from_previous = false; if (reorder_bytes_) { if (reorder_start_ != reorder_buffer_) { from_previous = true; } copy_bytes = std::min(size - bytes_read, reorder_bytes_); header = reorder_header_; memcpy(buffer + bytes_read, reorder_start_, copy_bytes); reorder_bytes_ -= copy_bytes; reorder_start_ += copy_bytes; } else { if (data_filled_ == 0) { #if defined(WIN32) SSIZE_T num_bytes = 0; DWORD received_bytes = 0; DWORD flags = 0; WSABUF iov[2]; iov[0].buf = reinterpret_cast<char*>(&header); iov[0].len = sizeof(header); iov[1].buf = reinterpret_cast<char*>(data_buffer_); iov[1].len = max_datagram_size_ - sizeof(header); int rc = WSARecv(sock_, iov, 2, &received_bytes, &flags, NULL, NULL); if ( rc == SOCKET_ERROR) { num_bytes = -1; } else { num_bytes = received_bytes; } #else ssize_t num_bytes; struct iovec iov[2]; iov[0].iov_base = &header; iov[0].iov_len = sizeof(header); iov[1].iov_base = data_buffer_; iov[1].iov_len = max_datagram_size_ - sizeof(header); // Read a datagram with header num_bytes = readv(sock_, iov, 2); #endif if (num_bytes < 0) { if ( last_socket_error_is_would_block() ) { num_bytes = 0; break; } else { ROSCPP_LOG_DEBUG("readv() failed with error [%s]", last_socket_error_string()); close(); break; } } else if (num_bytes == 0) { ROSCPP_LOG_DEBUG("Socket [%d] received 0/%d bytes, closing", sock_, size); close(); return -1; } else if (num_bytes < (unsigned) sizeof(header)) { ROS_ERROR("Socket [%d] received short header (%d bytes): %s", sock_, int(num_bytes), last_socket_error_string()); close(); return -1; } num_bytes -= sizeof(header); data_filled_ = num_bytes; data_start_ = data_buffer_; } else { from_previous = true; } copy_bytes = std::min(size - bytes_read, data_filled_); // Copy from the data buffer, whether it has data left in it from a previous datagram or // was just filled by readv() memcpy(buffer + bytes_read, data_start_, copy_bytes); data_filled_ -= copy_bytes; data_start_ += copy_bytes; } if (from_previous) { // We are simply reading data from the last UDP datagram, nothing to // parse bytes_read += copy_bytes; } else { // This datagram is new, process header switch (header.op_) { case ROS_UDP_DATA0: if (current_message_id_) { ROS_DEBUG("Received new message [%d:%d], while still working on [%d] (block %d of %d)", header.message_id_, header.block_, current_message_id_, last_block_ + 1, total_blocks_); reorder_header_ = header; // Copy the entire data buffer to the reorder buffer, as we will // need to replay this UDP datagram in the next call. reorder_bytes_ = data_filled_ + (data_start_ - data_buffer_); memcpy(reorder_buffer_, data_buffer_, reorder_bytes_); reorder_start_ = reorder_buffer_; current_message_id_ = 0; total_blocks_ = 0; last_block_ = 0; data_filled_ = 0; data_start_ = data_buffer_; return -1; } total_blocks_ = header.block_; last_block_ = 0; current_message_id_ = header.message_id_; break; case ROS_UDP_DATAN: if (header.message_id_ != current_message_id_) { ROS_DEBUG("Message Id mismatch: %d != %d", header.message_id_, current_message_id_); data_filled_ = 0; // discard datagram return 0; } if (header.block_ != last_block_ + 1) { ROS_DEBUG("Expected block %d, received %d", last_block_ + 1, header.block_); data_filled_ = 0; // discard datagram return 0; } last_block_ = header.block_; break; default: ROS_ERROR("Unexpected UDP header OP [%d]", header.op_); return -1; } bytes_read += copy_bytes; if (last_block_ == (total_blocks_ - 1)) { current_message_id_ = 0; break; } } } return bytes_read; }
int run_file_tests(char *testfile) { int ret = -1; struct stat buf; assert(testfile); fprintf(stdout, "Testing creat"); ret = creat(testfile, S_IRWXU); check_err(ret, "creat", 2); fprintf(stdout, "Testing close"); ret = close(ret); check_err(ret, "close", 2); fprintf(stdout, "Testing open"); ret = open(testfile, O_RDONLY); check_err(ret, "open", 2); fprintf(stdout, "Testing read"); ret = read(0, NULL, 0); check_err(ret, "read", 2); fprintf(stdout, "Testing readv"); ret = readv(0, NULL, 0); check_err(ret, "readv", 2); fprintf(stdout, "Testing pread"); ret = pread(0, NULL, 0, 0); check_err(ret, "pread", 2); fprintf(stdout, "Testing write"); ret = write(0, NULL, 0); check_err(ret, "write", 2); fprintf(stdout, "Testing writev"); ret = writev(0, NULL, 0); check_err(ret, "writev", 2); fprintf(stdout, "Testing pwrite"); ret = pwrite(0, NULL, 0, 0); check_err(ret, "pwrite", 2); fprintf(stdout, "Testing lseek"); ret = lseek(0, 0, 0); check_err(ret, "lseek", 2); fprintf(stdout, "Testing dup"); ret = dup(0); check_err(ret, "dup", 2); fprintf(stdout, "Testing dup2"); ret = dup2(0, 0); check_err(ret, "dup2", 2); fprintf(stdout, "Testing fchmod"); ret = fchmod(0, 0); check_err(ret, "fchmod", 2); fprintf(stdout, "Testing fchown"); ret = fchown(0, 0, 0); check_err(ret, "fchown", 2); fprintf(stdout, "Testing fsync"); ret = fsync(0); check_err(ret, "fsync", 2); fprintf(stdout, "Testing ftruncate"); ret = ftruncate(0, 0); check_err(ret, "ftruncate", 1); fprintf(stdout, "Testing fstat"); ret = fstat(0, &buf); check_err(ret, "fstat", 1); fprintf(stdout, "Testing sendfile"); ret = sendfile(0, 0, NULL, 0); check_err(ret, "sendfile", 1); fprintf(stdout, "Testing fcntl"); ret = fcntl(0, 0, NULL); check_err(ret, "fcntl", 2); fprintf(stdout, "Testing close"); ret = close(ret); check_err(ret, "close", 2); fprintf(stdout, "Testing remove"); ret = remove(testfile); check_err(ret, "remove", 2); return ret; }
ssize_t ARSAL_Socket_Readv (int sockfd, const struct iovec *iov, int iovcnt) { return readv (sockfd, iov, iovcnt); }
/***************************************************************************** * Readv commands. *****************************************************************************/ static int libc_readv ( dvdcss_t dvdcss, const struct iovec *p_iovec, int i_blocks ) { #if defined( _WIN32 ) int i_index, i_len, i_total = 0; unsigned char *p_base; int i_bytes; for( i_index = i_blocks; i_index; i_index--, p_iovec++ ) { i_len = p_iovec->iov_len; p_base = p_iovec->iov_base; if( i_len <= 0 ) { continue; } i_bytes = read( dvdcss->i_fd, p_base, i_len ); if( i_bytes < 0 ) { /* One of the reads failed, too bad. * We won't even bother returning the reads that went OK, * and as in the POSIX spec the file position is left * unspecified after a failure */ dvdcss->i_pos = -1; return -1; } i_total += i_bytes; i_total /= DVDCSS_BLOCK_SIZE; if( i_bytes != i_len ) { /* We reached the end of the file or a signal interrupted * the read. Return a partial read. */ int i_seek; dvdcss->i_pos = -1; i_seek = libc_seek( dvdcss, i_total ); if( i_seek < 0 ) { return i_seek; } /* We have to return now so that i_pos isn't clobbered */ return i_total; } } dvdcss->i_pos += i_total; return i_total; #else int i_read = readv( dvdcss->i_fd, p_iovec, i_blocks ); if( i_read < 0 ) { dvdcss->i_pos = -1; return i_read; } i_read /= DVDCSS_BLOCK_SIZE; dvdcss->i_pos += i_read; return i_read; #endif }
void RtpH264_Run(int sfd, RtpH264_OnPicture onPicture) { #define INBUF_SIZE (1024 * 128) uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); AVFrame *picture = avcodec_alloc_frame(); AVPacket avpkt; av_init_packet(&avpkt); int frame_count = 0; unsigned short sequence = 0; unsigned int timestamp = 0; while(1) { //int ready = 0; fd_set rfds; FD_ZERO(&rfds); FD_SET(sfd, &rfds); struct timeval timeout; /*Timer for operation select*/ timeout.tv_sec = 0; timeout.tv_usec = 10000; /*10 ms*/ if(select(sfd+1, &rfds, 0, 0, &timeout) <= 0) { if(bStop) break; else continue; } if(FD_ISSET(sfd, &rfds) <= 0) continue; rtp_hdr_t rtp; unsigned char buf[64]; memset(buf, 0, 64); int r = recv(sfd, buf, sizeof(rtp_hdr_t) + 8, MSG_PEEK); /* Peek data from socket, so that we could determin how to read data from socket*/ if(r <= sizeof(rtp_hdr_t) || r == -1) { recv(sfd, buf, sizeof(rtp_hdr_t) + 8, 0); /*Read invalid packet*/ printf("Warning !!! Invalid packet\n"); continue; /*Invalid packet ???*/ } int ready = 0; /* Handle H.264 RTP Header */ /* +---------------+ * |0|1|2|3|4|5|6|7| * +-+-+-+-+-+-+-+-+ * |F|NRI| Type | * +---------------+ * * F must be 0. */ unsigned char nal_ref_idc, nal_unit_type; unsigned char *header = buf + sizeof(rtp_hdr_t); /* NAL Header */ nal_ref_idc = (header[0] & 0x60) >> 5; /* NRI */ //printf("nal_ref_idc = %d\n", nal_ref_idc); nal_unit_type = header[0] & 0x1f; /* Type */ //printf("nal_unit_type = %d\n", nal_unit_type); switch (nal_unit_type) { case 0: case 30: case 31: /* undefined */ break; case 25: /* STAP-B Single-time aggregation packet 5.7.1 */ /* 2 byte extra header for DON */ /* fallthrough */ case 24: /* STAP-A Single-time aggregation packet 5.7.1 */ break; case 26: /* MTAP16 Multi-time aggregation packet 5.7.2 */ /* fallthrough, not implemented */ case 27: /* MTAP24 Multi-time aggregation packet 5.7.2 */ break; case 28: /* FU-A Fragmentation unit 5.8 */ case 29: { /* FU-B Fragmentation unit 5.8 */ /* +---------------+ * |0|1|2|3|4|5|6|7| * +-+-+-+-+-+-+-+-+ * |S|E|R| Type | * +---------------+ * * R is reserved and always 0 */ /*Really read packet*/ struct iovec data[3]; data[0].iov_base = &rtp; data[0].iov_len = sizeof(rtp_hdr_t); if(nal_unit_type == 28) { /* strip off FU indicator and FU header bytes */ data[1].iov_base = buf; data[1].iov_len = 2; } else if(nal_unit_type == 29) { /* strip off FU indicator and FU header and DON bytes */ data[1].iov_base = buf; data[1].iov_len = 4; } /* NAL unit starts here */ if((header[1] & 0x80) == 0x80) { data[2].iov_base = &inbuf[5]; data[2].iov_len = INBUF_SIZE - 5; r = readv(sfd, data, 3); if(r <= (sizeof(rtp_hdr_t) + 2)) { printf("Socket read fail !!!\n"); goto cleanup; } unsigned char fu_indicator = buf[0]; unsigned char fu_header = buf[1]; timestamp = ntohl(rtp.ts); sequence = ntohs(rtp.seq); inbuf[0] = 0x00; inbuf[1] = 0x00; inbuf[2] = 0x00; inbuf[3] = 0x01; inbuf[4] = (fu_indicator & 0xe0) | (fu_header & 0x1f); if(nal_unit_type == 28) avpkt.size = (r - sizeof(rtp_hdr_t) - 2 + 5); else if(nal_unit_type == 29) avpkt.size = (r - sizeof(rtp_hdr_t) - 4 + 5); avpkt.data = inbuf; //printf("nalu = %d\n", fu_header & 0x1f); if((fu_header & 0x1f) == 7) avpkt.flags |= PKT_FLAG_KEY; // avpkt.pts = frame_count++; //printf("avpkt.pts = %d\n", avpkt.pts); break; } else { data[2].iov_base = inbuf + avpkt.size; data[2].iov_len = INBUF_SIZE - avpkt.size; r = readv(sfd, data, 3); //unsigned char fu_indicator = buf[0]; unsigned char fu_header = buf[1]; if(r <= (sizeof(rtp_hdr_t) + 2) || r == -1) { printf("Socket read fail !!!\n"); goto cleanup; } if(ntohl(rtp.ts) != timestamp) { printf("Miss match timestamp %d ( expect %d )\n", ntohl(rtp.ts), timestamp); } if(ntohs(rtp.seq) != ++sequence) { printf("Wrong sequence number %u ( expect %u )\n", ntohs(rtp.seq), sequence); } if(nal_unit_type == 28) avpkt.size += (r - sizeof(rtp_hdr_t) - 2); else if(nal_unit_type == 29) avpkt.size += (r - sizeof(rtp_hdr_t) - 4); //printf("frame size : %d\n", avpkt.size); } /* NAL unit ends */ if((header[1] & 0x40) == 0x40) { ready = 1; /*We are done, go to decode*/ break; } break; } default: { /* 1-23 NAL unit Single NAL unit packet per H.264 5.6 */ /* the entire payload is the output buffer */ struct iovec data[2]; data[0].iov_base = &rtp; data[0].iov_len = sizeof(rtp_hdr_t); inbuf[0] = 0x00; inbuf[1] = 0x00; inbuf[2] = 0x00; inbuf[3] = 0x01; data[1].iov_base = &inbuf[4]; data[1].iov_len = INBUF_SIZE - 4; r = readv(sfd, data, 2); if(r <= sizeof(rtp_hdr_t) || r == -1) { printf("Socket read fail !!!\n"); goto cleanup; } avpkt.size = (r - sizeof(rtp_hdr_t) + 4); avpkt.data = inbuf; ready = 1; /*We are done, go to decode*/ break; } } int got_picture; while(ready && avpkt.size > 0) { avpkt.pts = ++frame_count; //printf("frame size : %d\n", avpkt.size); //printf("avpkt.dts = %d\n", avpkt.dts); // int len = avcodec_decode_video(context, picture, &got_picture, avpkt.data, avpkt.size); int len = avcodec_decode_video2(context, picture, &got_picture, &avpkt); //printf("context->coded_frame->pts = %d\n", context->coded_frame->pts); /* 0 */ //printf("picture->pts = %d\n", picture->pts); //printf("picture->pict_type = %d\n", picture->pict_type); //printf("picture->key_frame = %d\n", picture->key_frame); //printf("picture->interlaced_frame = %d\n", picture->interlaced_frame); //printf("avpkt.duration = %d\n", avpkt.duration); Mp4Mux_WriteVideo(&avpkt, timestamp); if(len < 0) { fprintf(stderr, "Error while decoding frame\n"); av_init_packet(&avpkt); break; } if(got_picture) { // printf("Decode length : %d\n", len); // fflush(stdout); /* the picture is allocated by the decoder. no need to free it */ if(onPicture) onPicture(picture->data[0], picture->linesize[0], context->width, context->height); av_init_packet(&avpkt); break; } avpkt.size -= len; avpkt.data += len; } } cleanup: av_free(picture); return; }
int main(int argc, char **argv) { int x = 0; char *args[10]; setuid(2); signal(SIGCHLD, sigchld); do_signals(); x += getpid(); x += getppid(); x += getuid(); x += getgid(); x += setsid(); x += seteuid(); x += setegid(); lseek(0, 0, -1); kill(0, 0); signal(99, 0); signal(SIGINT, int_handler); signal(SIGSEGV, segv_handler); // *(int *) 0 = 0; pipe(0); munmap(0, 0); mincore(0, 0); shmget(0); shmat(0); line = __LINE__; poll(-1, 0, 0); signal(SIGSEGV, SIG_IGN); // ppoll(-1, -1, -1, 0); signal(SIGSEGV, SIG_DFL); sched_yield(); readv(-1, 0, 0, 0); writev(-1, 0, 0, 0); msync(0, 0, 0); fsync(-1); fdatasync(-1); semget(0, 0, 0); semctl(0, 0, 0); uselib(NULL); pivot_root(0, 0); personality(-1); setfsuid(-1); flock(-1, 0); shmdt(0, 0, 0); times(0); mremap(0, 0, 0, 0, 0); madvise(0, 0, 0); fchown(-1, 0, 0); lchown(0, 0, 0); setreuid(); setregid(); link("/nonexistant", "/also-nonexistant"); do_slow(); symlink("/nothing", "/"); rename("/", "/"); mkdir("/junk/stuff////0", 0777); geteuid(); getsid(); getpgid(); getresuid(); getresgid(); getpgid(); ptrace(-1, 0, 0, 0); semop(0, 0, 0); capget(0, 0); line = __LINE__; gettimeofday(0, 0); settimeofday(0, 0); dup(-1); dup2(-1, -1); shmctl(0, 0, 0, 0); execve("/bin/nothing", "/bin/nothing", 0); alarm(9999); bind(0, 0, 0); socket(0, 0, 0); accept(0, 0, 0); listen(0); shutdown(0); getsockname(0, 0, 0); getpeername(0, 0, 0); truncate(0, 0); ftruncate(0, 0); line = __LINE__; if (vfork() == 0) exit(0); line = __LINE__; x = opendir("/", 0, 0); line = __LINE__; readdir(x, 0, 0); line = __LINE__; closedir(x); line = __LINE__; chroot("/"); line = __LINE__; sigaction(0, 0, 0); line = __LINE__; sigprocmask(0, 0, 0); x += open("/nothing", 0); x += chdir("/nothing"); x += mknod("/nothing/nothing", 0); x += ioctl(); execve("/nothing", NULL, NULL); line = __LINE__; x += close(-2); line = __LINE__; if (fork() == 0) exit(0); line = __LINE__; clone(clone_func, 0, 0, 0); line = __LINE__; brk(0); sbrk(0); line = __LINE__; mmap(0, 0, 0, 0, 0); line = __LINE__; uname(0); line = __LINE__; getcwd(0, 0); line = __LINE__; iopl(3); ioperm(0, 0, 0); mount(0, 0, 0, 0, 0); umount(0, 0); umount(0, 0, 0); swapon(0, 0); swapoff(0); sethostname(0); line = __LINE__; time(NULL); unlink("/nothing"); line = __LINE__; rmdir("/nothing"); chmod(0, 0); line = __LINE__; # if defined(__i386) || defined(__amd64) modify_ldt(0); # endif stat("/doing-nice", 0); nice(0); args[0] = "/bin/df"; args[1] = "-l"; args[2] = NULL; close(1); open("/dev/null", O_WRONLY); /***********************************************/ /* Some syscalls arent available direct */ /* from libc, so get them here. We mostly */ /* care about the ones which have caused */ /* implementation difficulty and kernel */ /* crashes - eventually we can be complete. */ /***********************************************/ line = __LINE__; open("/system-dependent-syscalls-follow", 0); line = __LINE__; if (fork() == 0) exit(0); {int status; while (wait(&status) >= 0) ; } sigaltstack(0, 0); /*vm86(0, 0);*/ /***********************************************/ /* Some syscalls arent directly accessible, */ /* e.g. legacy. */ /***********************************************/ #if defined(__x86_64__) trace(__LINE__, "x64 syscalls"); syscall(174, 0, 0, 0); // create_module syscall(176, 0, 0, 0); // delete_module syscall(178, 0, 0, 0); // query_module #else trace(__LINE__, "x32 syscalls"); syscall(0, 0, 0, 0); // restart_syscall syscall(34, 0, 0, 0); // nice syscall(59, 0, 0, 0); // oldolduname syscall(109, 0, 0, 0); // olduname if (fork() == 0) syscall(1, 0, 0, 0); // exit #endif line = __LINE__; execve("/bin/df", args, NULL); fprintf(stderr, "Error: should not get here -- %s\n", strerror(errno)); exit(1); }
void cons_receiveq_fn(void *_vq) // host -> guest { struct virtio_vq *vq = _vq; uint32_t head; uint32_t olen, ilen; uint32_t i, j; int num_read; struct iovec *iov; struct virtio_mmio_dev *dev = vq->vqdev->transport_dev; if (!vq) errx(1, "\n %s:%d\n" " Virtio device: (not sure which one): Error, device behavior.\n" " The device must provide a valid virtio_vq as an argument to %s." , __FILE__, __LINE__, __func__); // NOTE: The virtio_next_avail_vq_desc will not write more than // vq->vring.num entries to iov, and the device implementation // (virtio_mmio.c) will not allow the driver to set vq->vring.num to a // value greater than QueueNumMax (vq->qnum_max), so you are safe as // long as your iov is at least vq->qnum_max iovecs in size. iov = malloc(vq->qnum_max * sizeof(struct iovec)); if (vq->qready == 0x0) VIRTIO_DEV_ERRX(vq->vqdev, "The service function for queue '%s' was launched before the driver set QueueReady to 0x1." , vq->name); // NOTE: This will block in 2 places: // - reading from stdin // - reading from eventfd in virtio_next_avail_vq_desc while (1) { head = virtio_next_avail_vq_desc(vq, iov, &olen, &ilen); if (olen) { // virtio-v1.0-cs04 s5.3.6.1 Device Operation (console section) VIRTIO_DRI_ERRX(vq->vqdev, "The driver placed a device-readable buffer in the console device's receiveq.\n" " See virtio-v1.0-cs04 s5.3.6.1 Device Operation"); } // TODO: We may want to add some sort of console abort // (e.g. type q and enter to quit) // readv from stdin as much as we can (to end of bufs or end of input) num_read = readv(0, iov, ilen); if (num_read < 0) VIRTIO_DEV_ERRX(vq->vqdev, "Encountered an error trying to read input from stdin (fd 0)."); // You pass the number of bytes written to virtio_add_used_desc virtio_add_used_desc(vq, head, num_read); // Poke the guest however the mmio transport prefers // NOTE: assuming that the mmio transport was used for now. virtio_mmio_set_vring_irq(dev); if (dev->poke_guest) dev->poke_guest(dev->vec); else VIRTIO_DEV_ERRX(vq->vqdev, "The host MUST provide a way for device interrupts to be sent to the guest. The 'poke_guest' function pointer on the vq->vqdev->transport_dev (assumed to be a struct virtio_mmio_dev) was not set."); } free(iov); }
/* net_receiveq_fn receives packets for the guest through the virtio networking * device and the _vq virtio queue. */ void net_receiveq_fn(void *_vq) { struct virtio_vq *vq = _vq; uint32_t head; uint32_t olen, ilen; int num_read; struct iovec *iov; struct virtio_mmio_dev *dev = vq->vqdev->transport_dev; int fd; struct virtio_net_hdr_v1 *net_header; fd = open(data_path, O_RDWR); if (fd == -1) VIRTIO_DEV_ERRX(vq->vqdev, "Could not open data file for ether1."); if (!vq) VIRTIO_DEV_ERRX(vq->vqdev, "\n %s:%d\n" " Virtio device: (not sure which one): Error, device behavior.\n" " The device must provide a valid virtio_vq as an argument to %s." , __FILE__, __LINE__, __func__); if (vq->qready == 0x0) VIRTIO_DEV_ERRX(vq->vqdev, "The service function for queue '%s' was launched before the driver set QueueReady to 0x1.", vq->name); iov = malloc(vq->qnum_max * sizeof(struct iovec)); assert(iov != NULL); if (!dev->poke_guest) { free(iov); VIRTIO_DEV_ERRX(vq->vqdev, "The 'poke_guest' function pointer was not set."); } for (;;) { head = virtio_next_avail_vq_desc(vq, iov, &olen, &ilen); if (olen) { free(iov); VIRTIO_DRI_ERRX(vq->vqdev, "The driver placed a device-readable buffer in the net device's receiveq.\n" " See virtio-v1.0-cs04 s5.3.6.1 Device Operation"); } /* For receive the virtio header is in iov[0], so we only want * the packet to be read into iov[1] and above. */ num_read = readv(fd, iov + 1, ilen - 1); if (num_read < 0) { free(iov); VIRTIO_DEV_ERRX(vq->vqdev, "Encountered an error trying to read input from the ethernet device."); } /* See virtio spec virtio-v1.0-cs04 s5.1.6.3.2 Device Requirements: * Setting Up Receive Buffers * * VIRTIO_NET_F_MRG_RXBUF is not currently negotiated. * num_buffers will always be 1 if VIRTIO_NET_F_MRG_RXBUF is not * negotiated. */ net_header = iov[0].iov_base; net_header->num_buffers = 1; virtio_add_used_desc(vq, head, num_read + VIRTIO_HEADER_SIZE); virtio_mmio_set_vring_irq(dev); dev->poke_guest(dev->vec); } }
int doFunctionalTest(void) { FILE *fp; int fd; struct iovec rdvec[4]; struct iovec wrvec[4]; int rc; /* * Setup the iovec */ wrvec[0].iov_base = &PatternBuffer[0]; wrvec[0].iov_len = 100; wrvec[1].iov_base = &PatternBuffer[100]; wrvec[1].iov_len = 200; wrvec[2].iov_base = &PatternBuffer[300]; wrvec[2].iov_len = 300; wrvec[3].iov_base = &PatternBuffer[600]; wrvec[3].iov_len = 400; rdvec[0].iov_base = &ReadBuffer[0]; rdvec[0].iov_len = 400; rdvec[1].iov_base = &ReadBuffer[400]; rdvec[1].iov_len = 300; rdvec[2].iov_base = &ReadBuffer[700]; rdvec[2].iov_len = 200; rdvec[3].iov_base = &ReadBuffer[900]; rdvec[3].iov_len = 100; /* * Write the File */ fp = fopen(TESTFILE, "wt"); if ( fp == NULL ) { printf( "fopen for write: %d=%s\n", errno, strerror(errno)); return FALSE; } fd = fileno(fp); rc = writev(fd, wrvec, 4); if ( rc <= 0 ) { printf( "writev: %d=%s\n", errno, strerror(errno) ); return FALSE; } fclose(fp); puts("File written using writev .. OK"); /* * Now read it back and check it */ fp = fopen(TESTFILE, "rt"); if ( fp == NULL ) { printf( "fopen for write: %d=%s\n", errno, strerror(errno)); return FALSE; } fd = fileno(fp); rc = readv(fd, rdvec, 4); if ( rc <= 0 ) { printf( "rd: %d=%s\n", errno, strerror(errno) ); return FALSE; } if ( memcmp( PatternBuffer, ReadBuffer, MAX_BUFFER ) ) { puts("readv .. Buffers do not match"); return FALSE; } puts("File read using readv .. OK"); return TRUE; }
int main() { struct test_info info; int test, part, fd_random, fd_file1, fd_file2; double speeds[PARTS]; int limitsr[] = { 0, 0, 0, 2000, 3000 }; int limitsw[] = { 0, 80, 2000, 5000, 1000 }; int sizes[] = { 100, 100, 700, 500, 200 }; int counts[] = { 10, 5, 100, 200, 500 }; iolimits(0); if ((fd_random = open(fromfile, O_RDONLY)) < 0 ) { fprintf(stderr, "Error in open (%s)!\n", fromfile); return 1; } if ((fd_file1 = open(file1, O_WRONLY | O_CREAT, 0666)) < 0 ) { fprintf(stderr, "Error in open (%s)!\n", file1); return 2; } if ((read(fd_random, buf, BUFLEN*VECLEN)) < 0) { fprintf(stderr, "Error in read (%s)!\n", fromfile); return 3; } if ((write(fd_file1, buf, BUFLEN*VECLEN)) < 0) { fprintf(stderr, "Error in read (%s)!\n", file1); return 4; } close(fd_random); close(fd_file1); iolimits(1); for (test = 0; test < TESTS; ++test) { int r, w, t, i; limit_read(MAJORr,MINORr,limitsr[test]); limit_write(MAJORw,MINORw,limitsw[test]); for (part = 0; part < PARTS; ++part) { int pos; t = 0; w = 0; r = 0; if ((fd_file1 = open(file1, O_CREAT | O_RDONLY, 0666)) < 0) { fprintf(stderr, "Error in open (%s)!\n", file1); break; } if ((fd_file2 = open(file2, O_CREAT | O_WRONLY, 0666)) < 0) { fprintf(stderr, "Error in open (%s)!\n", file2); break; } for (i = 0; i < VECLEN; ++i) { v[i].iov_base = buf + i*counts[test]; v[i].iov_len = counts[test]; } tic(); for (i = 0; i < sizes[test]; ++i) { if ((r += readv(fd_file1, v, VECLEN)) < 0) { fprintf(stderr, "Error in read (%s,%d,%d,%s)!\n", file1, i, errno, strerror(errno)); break; } if ((w += writev(fd_file2, v, VECLEN)) < 0) { fprintf(stderr, "Error in write (%s,%d,%d,%s)!\n", file2,i, errno, strerror(errno)); break; } } t = toc(); if (r != w) fprintf(stderr, "w= %d r= %d ok= %d\n", w, r, sizes[test]*counts[test]*VECLEN); assert(r == w); if (r != sizes[test]*counts[test]*VECLEN) fprintf(stderr, "r= %d ok= %d\n", r, sizes[test]*counts[test]*VECLEN); speeds[part] = (1000.0E0) * ((double) w) / ((double) t); /* (B / usec) = (10000000/1024) * (kB/s) */ fprintf(stderr, "limit(read): %d, limit(write): %d, count: %dB, part: %d time: %d speed1: %f\n", limitsr[test], limitsw[test], counts[test], part, t, speeds[part]); close(fd_file1); close(fd_file2); } info = analyse(speeds, PARTS); fprintf(stdout, "=> TEST %d.1 => limit(read): %dkB, limit(write): %dkB, data: %dB, count: %dB, avg: %fs, dev: %fs, len: %dparts\n", test, limitsr[test], limitsw[test], sizes[test], counts[test], info.avg, info.dev, info.len); fflush(stdout); } iolimits(0); return 0; }
//Lowest level method that we have control before firing a read or write //operation. The return values are typically interpretted by the caller. //IOPending flags are pushed to this method so that IOPending flag is not //set or reset at different places in the code. Int32 SQScratchFile::redriveVectorIO(Int32 index) { ssize_t bytesCompleted = 0; ExBMOStats *bmoStats = scratchSpace_->bmoStats(); //Other book keeping fileHandle_[index].IOPending = TRUE; #ifdef _DEBUG // Regression testing support for simulating IO Pending state. if (envIOPending_ && bmoStats && (type_ == PEND_READ) && (envIOBlockCount_ == bmoStats->getScratchReadCount())) { envIOBlockCount_ = -1; //avoid looping. bytesCompleted = -1; errno = EAGAIN; return -1; } #endif if(scratchSpace_->getScratchOverflowMode() == SCRATCH_MMAP) { struct iovec *temp = (struct iovec *)remainingAddr_; while(remainingVectorSize_ > 0) { if(type_ == PEND_READ) { memcpy(temp->iov_base, (fileHandle_[index].mmap + readmmapCursor_), temp->iov_len); readmmapCursor_ += temp->iov_len; if(bmoStats) bmoStats->incScratchReadCount(); } else { memcpy((fileHandle_[index].mmap + writemmapCursor_), temp->iov_base , temp->iov_len); writemmapCursor_ += temp->iov_len; if(bmoStats) bmoStats->incScratchWriteCount(); } bytesCompleted_ =+ temp->iov_len; remainingVectorSize_ --; temp++; }//while remainingAddr_ = 0; //Typically this address is invalid after reaching here. } else { while(remainingVectorSize_ > 0) { if(type_ == PEND_READ) { bytesCompleted = readv(fileHandle_[index].fileNum, (struct iovec*)remainingAddr_, remainingVectorSize_); if(bmoStats) bmoStats->incScratchReadCount(); } else { bytesCompleted = writev(fileHandle_[index].fileNum, (struct iovec*)remainingAddr_, remainingVectorSize_); if(bmoStats) bmoStats->incScratchWriteCount(); } if(bytesCompleted == -1) { //This can happen at the very first call or subsequent interations. //note that remaningAddr and remainingVectorSize is already adjusted //in previous iterations if they were successful. return -1; } bytesCompleted_ =+ bytesCompleted; //Now readjust the remaining counters by deducting bytesWritten while(bytesCompleted > 0) { struct iovec *temp = (struct iovec *)remainingAddr_; if(bytesCompleted >= temp->iov_len) { //advance to next vector element bytesCompleted -= temp->iov_len; remainingVectorSize_ --; temp++; remainingAddr_ = (void *)temp; } else { //adjust the vector element temp->iov_len -= bytesCompleted; temp->iov_base = (void *) ((char *) temp->iov_base + bytesCompleted); bytesCompleted = 0; } }//while }//while } //not MMAP //If we reach here, then remainingVectorSize_ is zero. write/read operation is //fully complete. fileHandle_[index].IOPending = FALSE; return 0; }
static ssize_t uv__fs_read(uv_fs_t* req) { #if defined(__linux__) static int no_preadv; #endif ssize_t result; #if defined(_AIX) struct stat buf; if(fstat(req->file, &buf)) return -1; if(S_ISDIR(buf.st_mode)) { errno = EISDIR; return -1; } #endif /* defined(_AIX) */ if (req->off < 0) { if (req->nbufs == 1) result = read(req->file, req->bufs[0].base, req->bufs[0].len); else result = readv(req->file, (struct iovec*) req->bufs, req->nbufs); } else { if (req->nbufs == 1) { result = pread(req->file, req->bufs[0].base, req->bufs[0].len, req->off); goto done; } #if HAVE_PREADV result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); #else # if defined(__linux__) if (no_preadv) retry: # endif { off_t nread; size_t index; nread = 0; index = 0; result = 1; do { if (req->bufs[index].len > 0) { result = pread(req->file, req->bufs[index].base, req->bufs[index].len, req->off + nread); if (result > 0) nread += result; } index++; } while (index < req->nbufs && result > 0); if (nread > 0) result = nread; } # if defined(__linux__) else { result = uv__preadv(req->file, (struct iovec*)req->bufs, req->nbufs, req->off); if (result == -1 && errno == ENOSYS) { no_preadv = 1; goto retry; } } # endif #endif } done: return result; }
bool mca_btl_tcp_frag_recv(mca_btl_tcp_frag_t* frag, int sd) { int cnt, dont_copy_data = 0; size_t i, num_vecs; mca_btl_base_endpoint_t* btl_endpoint = frag->endpoint; repeat: num_vecs = frag->iov_cnt; #if MCA_BTL_TCP_ENDPOINT_CACHE if( 0 != btl_endpoint->endpoint_cache_length ) { size_t length; /* It's strange at the first look but cnt have to be set to the full amount of data * available. After going to advance_iov_position we will use cnt to detect if there * is still some data pending. */ cnt = length = btl_endpoint->endpoint_cache_length; for( i = 0; i < frag->iov_cnt; i++ ) { if( length > frag->iov_ptr[i].iov_len ) length = frag->iov_ptr[i].iov_len; if( (0 == dont_copy_data) || (length < frag->iov_ptr[i].iov_len) ) { memcpy( frag->iov_ptr[i].iov_base, btl_endpoint->endpoint_cache_pos, length ); } else { frag->segments[0].seg_addr.pval = btl_endpoint->endpoint_cache_pos; frag->iov_ptr[i].iov_base = btl_endpoint->endpoint_cache_pos; } btl_endpoint->endpoint_cache_pos += length; btl_endpoint->endpoint_cache_length -= length; length = btl_endpoint->endpoint_cache_length; if( 0 == length ) { btl_endpoint->endpoint_cache_pos = btl_endpoint->endpoint_cache; break; } } goto advance_iov_position; } /* What's happens if all iovecs are used by the fragment ? It still work, as we reserve one * iovec for the caching in the fragment structure (the +1). */ frag->iov_ptr[num_vecs].iov_base = btl_endpoint->endpoint_cache_pos; frag->iov_ptr[num_vecs].iov_len = mca_btl_tcp_component.tcp_endpoint_cache - btl_endpoint->endpoint_cache_length; num_vecs++; #endif /* MCA_BTL_TCP_ENDPOINT_CACHE */ /* non-blocking read, but continue if interrupted */ cnt = -1; while( cnt < 0 ) { cnt = readv(sd, frag->iov_ptr, num_vecs); if( 0 < cnt ) goto advance_iov_position; if( cnt == 0 ) { mca_btl_tcp_endpoint_close(btl_endpoint); return false; } switch(opal_socket_errno) { case EINTR: continue; case EWOULDBLOCK: return false; case EFAULT: BTL_ERROR(("mca_btl_tcp_frag_recv: readv error (%p, %d)\n\t%s(%d)\n", frag->iov_ptr[0].iov_base, frag->iov_ptr[0].iov_len, strerror(opal_socket_errno), frag->iov_cnt)); mca_btl_tcp_endpoint_close(btl_endpoint); return false; default: BTL_ERROR(("mca_btl_tcp_frag_recv: readv failed: %s (%d)", strerror(opal_socket_errno), opal_socket_errno)); mca_btl_tcp_endpoint_close(btl_endpoint); return false; } }; advance_iov_position: /* if the read didn't complete - update the iovec state */ num_vecs = frag->iov_cnt; for( i = 0; i < num_vecs; i++ ) { if( cnt < (int)frag->iov_ptr->iov_len ) { frag->iov_ptr->iov_base = (ompi_iov_base_ptr_t) (((unsigned char*)frag->iov_ptr->iov_base) + cnt); frag->iov_ptr->iov_len -= cnt; cnt = 0; break; } cnt -= frag->iov_ptr->iov_len; frag->iov_idx++; frag->iov_ptr++; frag->iov_cnt--; } #if MCA_BTL_TCP_ENDPOINT_CACHE btl_endpoint->endpoint_cache_length = cnt; #endif /* MCA_BTL_TCP_ENDPOINT_CACHE */ /* read header */ if(frag->iov_cnt == 0) { if (btl_endpoint->endpoint_nbo && frag->iov_idx == 1) MCA_BTL_TCP_HDR_NTOH(frag->hdr); switch(frag->hdr.type) { case MCA_BTL_TCP_HDR_TYPE_SEND: if(frag->iov_idx == 1 && frag->hdr.size) { frag->segments[0].seg_addr.pval = frag+1; frag->segments[0].seg_len = frag->hdr.size; frag->iov[1].iov_base = (IOVBASE_TYPE*)(frag->segments[0].seg_addr.pval); frag->iov[1].iov_len = frag->hdr.size; frag->iov_cnt++; #ifndef __sparc /* The following cannot be done for sparc code * because it causes alignment errors when accessing * structures later on in the btl and pml code. */ dont_copy_data = 1; #endif goto repeat; } break; case MCA_BTL_TCP_HDR_TYPE_PUT: if(frag->iov_idx == 1) { frag->iov[1].iov_base = (IOVBASE_TYPE*)frag->segments; frag->iov[1].iov_len = frag->hdr.count * sizeof(mca_btl_base_segment_t); frag->iov_cnt++; goto repeat; } else if (frag->iov_idx == 2) { for( i = 0; i < frag->hdr.count; i++ ) { frag->iov[i+2].iov_base = (IOVBASE_TYPE*)ompi_ptr_ltop(frag->segments[i].seg_addr.lval); frag->iov[i+2].iov_len = frag->segments[i].seg_len; } frag->iov_cnt += frag->hdr.count; goto repeat; } break; case MCA_BTL_TCP_HDR_TYPE_GET: default: break; } return true; } return false; }
void File::mmreadv() { if (mmread()) readv(); }
int NET_ReadV(int s, const struct iovec * vector, int count) { BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); }
int t20(char *name) { char file[MAX_PATH_LENGTH] = ""; int fd; struct iovec iov[2]; char buf[100]; long ret; ENTER("trap app's general bad pointer for file i/o"); snprintf(file, MAX_PATH_LENGTH, "%s/test_t20_file", lustre_path); fd = open(file, O_RDWR|O_CREAT, (mode_t)0666); if (fd < 0) { printf("error open file: %s\n", strerror(errno)); return(-1); } ret = write(fd, NULL, 20); if (ret != -1 || errno != EFAULT) { printf("write 1: ret %lld, errno %d\n", (long long)ret, errno); return(1); } ret = write(fd, (void *)-1, 20); if (ret != -1 || errno != EFAULT) { printf("write 2: ret %lld, errno %d\n", (long long)ret, errno); return(1); } iov[0].iov_base = NULL; iov[0].iov_len = 10; iov[1].iov_base = (void *)-1; iov[1].iov_len = 10; ret = writev(fd, iov, 2); if (ret != -1 || errno != EFAULT) { printf("writev 1: ret %lld, errno %d\n", (long long)ret, errno); return(1); } iov[0].iov_base = NULL; iov[0].iov_len = 0; iov[1].iov_base = buf; iov[1].iov_len = sizeof(buf); ret = writev(fd, iov, 2); if (ret != sizeof(buf)) { printf("writev 2: ret %lld, error %d\n", (long long)ret, errno); return(1); } lseek(fd, 0, SEEK_SET); ret = read(fd, NULL, 20); if (ret != -1 || errno != EFAULT) { printf("read 1: ret %lld, errno %d\n", (long long)ret, errno); return(1); } ret = read(fd, (void *)-1, 20); if (ret != -1 || errno != EFAULT) { printf("read 2: ret %lld, error %d\n", (long long)ret, errno); return(1); } iov[0].iov_base = NULL; iov[0].iov_len = 10; iov[1].iov_base = (void *)-1; iov[1].iov_len = 10; ret = readv(fd, iov, 2); if (ret != -1 || errno != EFAULT) { printf("readv 1: ret %lld, error %d\n", (long long)ret, errno); return(1); } iov[0].iov_base = NULL; iov[0].iov_len = 0; iov[1].iov_base = buf; iov[1].iov_len = sizeof(buf); ret = readv(fd, iov, 2); if (ret != sizeof(buf)) { printf("readv 2: ret %lld, error %d\n", (long long)ret, errno); return(1); } close(fd); t_unlink(file); LEAVE(); }
/* * Implementation of a scattering read. Will use the appropriate * vector based read call (currently readv on Linux). * * This has a limit to the number of buffers that will be read. It * will not make muliple readv calls. This is to ensure that operations * are atomic. Currently it is limited to 16 buffers. This is for * compatibiliy with Sun. */ JNIEXPORT jlong JNICALL Java_gnu_java_nio_VMChannel_readScattering (JNIEnv *env, jobject o __attribute__ ((__unused__)), jint fd, jobjectArray bbufs, jint offset, jint length) { jint i; /* jboolean is_error = JNI_FALSE; */ /* char *error_msg; */ struct iovec buffers[JCL_IOV_MAX]; struct JCL_buffer bi_list[JCL_IOV_MAX]; ssize_t result; jint vec_len = length < JCL_IOV_MAX ? length : JCL_IOV_MAX; jlong bytes_read = 0; /* Build the vector of buffers to read into */ for (i = 0; i < vec_len; i++) { struct JCL_buffer* buf; jobject bbuf; buf = &bi_list[i]; bbuf = (*env)->GetObjectArrayElement(env, bbufs, offset + i); JCL_init_buffer(env, buf, bbuf); buffers[i].iov_base = &(buf->ptr[buf->position + buf->offset]); buffers[i].iov_len = buf->limit - buf->position; (*env)->DeleteLocalRef(env, bbuf); } /* Work the scattering magic */ result = readv(fd, buffers, vec_len); bytes_read = (jlong) result; /* Handle the response */ if (result < 0) { if (errno == EAGAIN) /* Non blocking */ result = 0; else if (errno == EBADF) /* Bad fd */ { JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read); JCL_ThrowException (env, NON_READABLE_CHANNEL_EXCEPTION, strerror(errno)); return -1; } else { JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read); JCL_ThrowException (env, IO_EXCEPTION, strerror(errno)); return -1; } bytes_read = 0; } else if (result == 0) /* EOF */ { result = -1; } JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read); return (jlong) result; }
static void pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) { struct iovec iov[VTNET_MAXSEGS], *riov; struct vqueue_info *vq; void *vrx; int len, n; uint16_t idx; /* * Should never be called without a valid tap fd */ assert(sc->vsc_tapfd != -1); /* * But, will be called when the rx ring hasn't yet * been set up or the guest is resetting the device. */ if (!sc->vsc_rx_ready || sc->resetting) { /* * Drop the packet and try later. */ (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf)); return; } /* * Check for available rx buffers */ vq = &sc->vsc_queues[VTNET_RXQ]; if (!vq_has_descs(vq)) { /* * Drop the packet and try later. Interrupt on * empty, if that's negotiated. */ (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf)); vq_endchains(vq, 1); return; } do { /* * Get descriptor chain. */ n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); assert(n >= 1 && n <= VTNET_MAXSEGS); /* * Get a pointer to the rx header, and use the * data immediately following it for the packet buffer. */ vrx = iov[0].iov_base; riov = rx_iov_trim(iov, &n, sc->rx_vhdrlen); len = readv(sc->vsc_tapfd, riov, n); if (len < 0 && errno == EWOULDBLOCK) { /* * No more packets, but still some avail ring * entries. Interrupt if needed/appropriate. */ vq_retchain(vq); vq_endchains(vq, 0); return; } /* * The only valid field in the rx packet header is the * number of buffers if merged rx bufs were negotiated. */ memset(vrx, 0, sc->rx_vhdrlen); if (sc->rx_merge) { struct virtio_net_rxhdr *vrxh; vrxh = vrx; vrxh->vrh_bufs = 1; } /* * Release this chain and handle more chains. */ vq_relchain(vq, idx, len + sc->rx_vhdrlen); } while (vq_has_descs(vq)); /* Interrupt if needed, including for NOTIFY_ON_EMPTY. */ vq_endchains(vq, 1); }