void tls_prng_exch_update(TLS_PRNG_SRC *eh) { const char *myname = "tls_prng_exch_update"; unsigned char buffer[TLS_PRNG_EXCH_SIZE]; ssize_t count; /* * Update the PRNG exchange file. Since other processes may have added * entropy, we use a read-stir-write cycle. */ if (acl_myflock(eh->fd.file, ACL_INTERNAL_LOCK, ACL_MYFLOCK_OP_EXCLUSIVE) != 0) acl_msg_fatal("%s: cannot lock PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if (acl_lseek(eh->fd.file, 0, SEEK_SET) < 0) acl_msg_fatal("%s: cannot seek PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if ((count = acl_file_read(eh->fd.file, buffer, sizeof(buffer), 0, NULL)) < 0) acl_msg_fatal("%s: cannot read PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if (count > 0) RAND_seed(buffer, count); RAND_bytes(buffer, sizeof(buffer)); if (acl_lseek(eh->fd.file, 0, SEEK_SET) < 0) acl_msg_fatal("%s: cannot seek PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if (acl_file_write(eh->fd.file, buffer, sizeof(buffer), 0, NULL) != sizeof(buffer)) acl_msg_fatal("%s: cannot write PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); if (acl_myflock(eh->fd.file, ACL_INTERNAL_LOCK, ACL_MYFLOCK_OP_NONE) != 0) acl_msg_fatal("%s: cannot unlock PRNG exchange file %s: %s", myname, eh->name, acl_last_serror()); }
ssize_t tls_prng_file_read(TLS_PRNG_SRC *fh, size_t len) { const char *myname = "tls_prng_file_read"; char buffer[8192]; ssize_t to_read; ssize_t count; if (acl_msg_verbose) acl_msg_info("%s: seed internal pool from file %s", myname, fh->name); if (acl_lseek(fh->fd.file, 0, SEEK_SET) < 0) { if (acl_msg_verbose) acl_msg_info("%s: cannot seek entropy file %s: %s", myname, fh->name, acl_last_serror()); return (-1); } errno = 0; for (to_read = (ssize_t) len; to_read > 0; to_read -= count) { #ifdef ACL_UNIX count = acl_timed_read(fh->fd.file, buffer, to_read > (ssize_t) sizeof(buffer) ? (ssize_t) sizeof(buffer) : to_read, fh->timeout, NULL); #elif defined(WIN32) count = acl_file_read(fh->fd.file, buffer, to_read > (ssize_t) sizeof(buffer) ? (ssize_t) sizeof(buffer) : to_read, fh->timeout, NULL); #endif if (count < 0) { if (acl_msg_verbose) acl_msg_info("%s: cannot read entropy file %s: %s", myname, fh->name, acl_last_serror()); return (-1); } if (count == 0) break; RAND_seed(buffer, count); } if (acl_msg_verbose) acl_msg_info("%s: read %ld bytes from entropy file %s: %s", myname, (long) (len - to_read), fh->name, acl_last_serror()); return ((ssize_t) (len - to_read)); }
static int vstring_extend(ACL_VBUF *bp, ssize_t incr) { const char *myname = "vstring_extend"; ssize_t used = (ssize_t) (bp->ptr - bp->data), new_len; ACL_VSTRING *vp = (ACL_VSTRING *) bp; if (vp->maxlen > 0 && (ssize_t) ACL_VSTRING_LEN(vp) >= vp->maxlen) { ACL_VSTRING_AT_OFFSET(vp, vp->maxlen - 1); ACL_VSTRING_TERMINATE(vp); acl_msg_warn("%s(%d), %s: overflow maxlen: %ld, %ld", __FILE__, __LINE__, myname, (long) vp->maxlen, (long) ACL_VSTRING_LEN(vp)); bp->flags |= ACL_VBUF_FLAG_EOF; return ACL_VBUF_EOF; } #ifdef ACL_WINDOWS if (bp->fd == ACL_FILE_INVALID && (bp->flags & ACL_VBUF_FLAG_FIXED)) #else if (bp->fd < 0 && (bp->flags & ACL_VBUF_FLAG_FIXED)) #endif { acl_msg_warn("%s(%d), %s: can't extend fixed buffer", __FILE__, __LINE__, myname); return ACL_VBUF_EOF; } /* * Note: vp->vbuf.len is the current buffer size (both on entry and on * exit of this routine). We round up the increment size to the buffer * size to avoid silly little buffer increments. With really large * strings we might want to abandon the length doubling strategy, and * go to fixed increments. */ #ifdef INCR_NO_DOUBLE /* below come from redis-server/sds.c/sdsMakeRoomFor, which can * avoid memory double growing too large --- 2015.2.2, zsx */ new_len = bp->len + incr; if (new_len < MAX_PREALLOC) new_len *= 2; else new_len += MAX_PREALLOC; #else new_len = bp->len + (bp->len > incr ? bp->len : incr); #endif if (vp->maxlen > 0 && new_len > vp->maxlen) new_len = vp->maxlen; if (vp->slice) bp->data = (unsigned char *) acl_slice_pool_realloc( __FILE__, __LINE__, vp->slice, bp->data, new_len); else if (vp->dbuf) { const unsigned char *data = bp->data; bp->data = (unsigned char *) acl_dbuf_pool_alloc( vp->dbuf, new_len); memcpy(bp->data, data, used); acl_dbuf_pool_free(vp->dbuf, data); } else if (bp->fd != ACL_FILE_INVALID) { #ifdef ACL_UNIX acl_off_t off = new_len - 1; if (acl_lseek(bp->fd, off, SEEK_SET) != (acl_off_t) off) acl_msg_fatal("lseek failed: %s, off: %lld", acl_last_serror(), off); if (acl_file_write(bp->fd, "\0", 1, 0, NULL, NULL) == ACL_VSTREAM_EOF) { acl_msg_fatal("write error: %s", acl_last_serror()); } #endif } else bp->data = (unsigned char *) acl_myrealloc(bp->data, new_len); bp->len = new_len; bp->ptr = bp->data + used; bp->cnt = bp->len - used; return 0; }
static int __vstream_sys_write(ACL_VSTREAM *stream, const void *vptr, int dlen) { int n, neintr = 0; acl_assert(stream && vptr && dlen > 0); if (stream->type == ACL_VSTREAM_TYPE_FILE) { if (ACL_VSTREAM_FILE(stream) == ACL_FILE_INVALID) return (ACL_VSTREAM_EOF); } else if (ACL_VSTREAM_SOCK(stream) == ACL_SOCKET_INVALID) return (ACL_VSTREAM_EOF); TAG_AGAIN: if (stream->type == ACL_VSTREAM_TYPE_FILE) { if ((stream->oflags & O_APPEND)) { #ifdef ACL_WINDOWS stream->sys_offset = acl_lseek( ACL_VSTREAM_FILE(stream), 0, SEEK_END); if (stream->sys_offset < 0) return (ACL_VSTREAM_EOF); #endif } else if ((stream->flag & ACL_VSTREAM_FLAG_CACHE_SEEK) && stream->offset != stream->sys_offset) { stream->sys_offset = acl_lseek(ACL_VSTREAM_FILE(stream), stream->offset, SEEK_SET); if (stream->sys_offset == -1) return (ACL_VSTREAM_EOF); stream->offset = stream->sys_offset; } n = stream->fwrite_fn(ACL_VSTREAM_FILE(stream), vptr, dlen, stream->rw_timeout, stream, stream->context); if (n > 0) { stream->sys_offset += n; stream->offset = stream->sys_offset; /* 防止缓冲区内的数据与实际不一致, 仅对文件IO有效 */ stream->read_cnt = 0; } } else n = stream->write_fn(ACL_VSTREAM_SOCK(stream), vptr, dlen, stream->rw_timeout, stream, stream->context); if (n < 0) { if (acl_last_error() == ACL_EINTR) { if (++neintr >= 5) return (ACL_VSTREAM_EOF); goto TAG_AGAIN; } if (acl_last_error() == ACL_EAGAIN || acl_last_error() == ACL_EWOULDBLOCK) { acl_set_error(ACL_EAGAIN); } return (ACL_VSTREAM_EOF); } stream->total_write_cnt += n; return (n); }