/* * Given a key_type and buffer, read key from buffer. * Return: 1 on success * -1 read failure * 0 on key length mismatch */ int read_key (struct key *key, const struct key_type *kt, struct buffer *buf) { uint8_t cipher_length; uint8_t hmac_length; CLEAR (*key); if (!buf_read (buf, &cipher_length, 1)) goto read_err; if (!buf_read (buf, &hmac_length, 1)) goto read_err; if (!buf_read (buf, key->cipher, cipher_length)) goto read_err; if (!buf_read (buf, key->hmac, hmac_length)) goto read_err; if (cipher_length != kt->cipher_length || hmac_length != kt->hmac_length) goto key_len_err; return 1; read_err: msg (D_TLS_ERRORS, "TLS Error: error reading key from remote"); return -1; key_len_err: msg (D_TLS_ERRORS, "TLS Error: key length mismatch, local cipher/hmac %d/%d, remote cipher/hmac %d/%d", kt->cipher_length, kt->hmac_length, cipher_length, hmac_length); return 0; }
// Helper function for buffers static int cmn_recv_helper( unsigned id, timer_data_type timeout ) { #ifdef BUF_ENABLE_UART t_buf_data data; #endif #ifdef BUF_ENABLE_UART if( buf_is_enabled( BUF_ID_UART, id ) ) { if( timeout == 0 ) { if ( ( buf_read( BUF_ID_UART, id, &data ) ) == PLATFORM_UNDERFLOW ) return -1; } else { while( ( buf_read( BUF_ID_UART, id, &data ) ) == PLATFORM_UNDERFLOW ); } return ( int )data; } else #endif // #ifdef BUF_ENABLE_UART if( id < NUM_UART || id == CDC_UART_ID ) return platform_s_uart_recv( id, timeout ); return -1; }
/* print a reliable ACK record coming off the wire */ const char * reliable_ack_print (struct buffer *buf, bool verbose, struct gc_arena *gc) { int i; uint8_t n_ack; struct session_id sid_ack; packet_id_type pid; struct buffer out = alloc_buf_gc (256, gc); buf_printf (&out, "["); if (!buf_read (buf, &n_ack, sizeof (n_ack))) goto done; for (i = 0; i < n_ack; ++i) { if (!buf_read (buf, &pid, sizeof (pid))) goto done; pid = ntohpid (pid); buf_printf (&out, " " packet_id_format, (packet_id_print_type)pid); } if (n_ack) { if (!session_id_read (&sid_ack, buf)) goto done; if (verbose) buf_printf (&out, " sid=%s", session_id_print (&sid_ack, gc)); } done: buf_printf (&out, " ]"); return BSTR (&out); }
int RDMA_transfer(char* src, char* dst, int buf_size, int count, struct RDMA_communicator *comm) { int i; int fd; int read_size; int tag; int ctl_msg_size; struct file_buffer *fbufs; int fbuf_index = 0; int *flags; char ctl_msg[1536]; double e,s; fbufs = (struct file_buffer *)malloc(sizeof(struct file_buffer) * count); flags = (int *)malloc(sizeof(int) * count); for (i = 0; i < count; i++) { fbufs[i % count].buf = (char *)malloc(buf_size); flags[i % count] = 1; } /*send init*/ tag=get_tag(); sprintf(ctl_msg, "%d\t%s", tag, dst); //printf(ctl_msg); ctl_msg_size = strlen(ctl_msg); RDMA_Sendr(ctl_msg, ctl_msg_size, TRANSFER_INIT, comm); /*---------*/ /*send file*/ fd = open(src, O_RDONLY); // printf("read fbuf_index=%d\n", fbuf_index); read_size = buf_read(fd, fbufs[fbuf_index].buf, buf_size); do { // printf("sent fbuf_index=%d\n", fbuf_index); RDMA_Isendr(fbufs[fbuf_index].buf, read_size, tag, &flags[fbuf_index], comm); //flags[fbuf_index] = 1; // printf("... sent done\n"); // printf("read fbuf_index=%d\n", fbuf_index); s = get_dtime(); read_size = buf_read(fd, fbufs[(fbuf_index + 1) % count].buf, buf_size); e = get_dtime(); // printf("ACT lib: read time = %fsecs, read size = %d MB, throughput = %f MB/s\n", e - s, read_size/1000000, read_size/(e - s)/1000000.0); RDMA_Wait (&flags[fbuf_index]); fbuf_index = (fbuf_index + 1) % count; } while (read_size > 0); /*---------*/ /*send fin*/ sprintf(ctl_msg, "%d\t%s", tag, dst); ctl_msg_size = strlen(ctl_msg); RDMA_Sendr(ctl_msg, ctl_msg_size, TRANSFER_FIN, comm); /*---------*/ return 0; }
/* read a packet ID acknowledgement record from buf into ack */ bool reliable_ack_read(struct reliable_ack *ack, struct buffer *buf, const struct session_id *sid) { struct gc_arena gc = gc_new(); int i; uint8_t count; packet_id_type net_pid; packet_id_type pid; struct session_id session_id_remote; if (!buf_read(buf, &count, sizeof(count))) { goto error; } for (i = 0; i < count; ++i) { if (!buf_read(buf, &net_pid, sizeof(net_pid))) { goto error; } if (ack->len >= RELIABLE_ACK_SIZE) { goto error; } pid = ntohpid(net_pid); ack->packet_id[ack->len++] = pid; } if (count) { if (!session_id_read(&session_id_remote, buf)) { goto error; } if (!session_id_defined(&session_id_remote) || !session_id_equal(&session_id_remote, sid)) { dmsg(D_REL_LOW, "ACK read BAD SESSION-ID FROM REMOTE, local=%s, remote=%s", session_id_print(sid, &gc), session_id_print(&session_id_remote, &gc)); goto error; } } gc_free(&gc); return true; error: gc_free(&gc); return false; }
/* Native C implementation */ static struct RECORD *next_marc(FILE *fp) { static long boff = 0; static struct RECORD rec; char lrecl[6]; char *b; int i; lrecl[5] = '\0'; while((b = buf_read(fp, boff, 5)) != NULL) { memcpy(lrecl, b, 5); for (i = 0; i < 5; i++) { if (!isdigit(lrecl[i])) { rb_raise(rb_eIOError, "FATAL: invalid record length: '%s'\n", lrecl); rec.err = -1; break; } } if (rec.err == -1) break; rec.len = atoi(lrecl); if (rec.len == 0) { rb_raise(rb_eIOError, "FATAL: zero-length record\n"); rec.err = -2; break; } if ((b = buf_read(fp, boff, rec.len)) == NULL) { rb_raise(rb_eIOError, "FATAL: marc read failure (loc %08lx: length %d)", boff, rec.len); rec.err = -3; break; } memcpy(rec.txt, b, rec.len); rec.txt[rec.len] = '\0'; boff += rec.len; return(&rec); } boff=0; if (rec.err) return(&rec); return((struct RECORD *)NULL); }
bool checkreturn pb_read(pb_istream_t *stream, uint8_t *buf, size_t count) { #ifndef PB_BUFFER_ONLY if (buf == NULL && stream->callback != buf_read) { /* Skip input bytes */ uint8_t tmp[16]; while (count > 16) { if (!pb_read(stream, tmp, 16)) return false; count -= 16; } return pb_read(stream, tmp, count); } #endif if (stream->bytes_left < count) PB_RETURN_ERROR(stream, "end-of-stream"); #ifndef PB_BUFFER_ONLY if (!stream->callback(stream, buf, count)) PB_RETURN_ERROR(stream, "io error"); #else if (!buf_read(stream, buf, count)) return false; #endif stream->bytes_left -= count; return true; }
int boss::Socket::gets(char *str, size_t maxlen) { size_t len; int rc; char ch; char *ptr; ptr = str; for (len = 1; len < maxlen; ++len) { if ((rc = buf_read(ch)) == 1) { if (ch == '\n') break; *ptr++ = ch; } else if (rc == 0) { return 0; } else { snprintf(_error_text,sizeof(_error_text)-1, "gets: %s", strerror(errno)); throw SocketException(_error_text); } } *ptr = '\0'; if (ptr > str) *(--ptr) = '\0'; // remove '\n' return len; }
struct Buffer* buf_new(const char *name) { struct Buffer *buf = calloc(1, sizeof(struct Buffer)); if (name) buf->name = strdup(name); buf_read(buf, name); return buf; }
int v2_merge(BUFFER *mid) { char fname[PATHMAX], line[LINELEN]; BUFFER *temp, *msg; FILE *l, *f; int i, numpackets; struct stat sb; long d; int n; int err = -1; temp = buf_new(); msg = buf_new(); pool_packetfile(fname, mid, 0); l = fopen(fname, "a+"); if (l != NULL) lock(l); pool_packetfile(fname, mid, 1); f = fopen(fname, "rb"); if (f == NULL) goto end; fscanf(f, "%32s %ld %d %d\n", line, &d, &i, &numpackets); fclose(f); /* do we have all packets? */ for (i = 1; i <= numpackets; i++) { pool_packetfile(fname, mid, i); if (stat(fname, &sb) != 0) goto end; } errlog(LOG, "Reassembling multipart message.\n"); for (i = 1; i <= numpackets; i++) { pool_packetfile(fname, mid, i); f = fopen(fname, "rb"); if (f == NULL) goto end; fscanf(f, "%32s %ld %d %d\n", line, &d, &n, &n); buf_clear(temp); buf_read(temp, f); v2body_setlen(temp); buf_append(msg, temp->data + 4, temp->length - 4); fclose(f); unlink(fname); } err = v2body(msg); end: if (l != NULL) fclose(l); pool_packetfile(fname, mid, 0); unlink(fname); buf_free(temp); buf_free(msg); return (err); }
void buf_clear(buf_t* buf) { void* entry; while ( !buf_empty(buf) ) { entry = buf_read(buf); if (NULL != entry) mem_release( entry ); } buf->reads = 0; buf->writes = 0; }
// Helper function for buffers static int cmn_recv_helper( unsigned id, s32 timeout ) { #ifdef BUF_ENABLE_UART t_buf_data data; if( buf_is_enabled( BUF_ID_UART, id ) ) { if( timeout == 0 ) { if ( ( buf_read( BUF_ID_UART, id, &data ) ) == PLATFORM_UNDERFLOW ) return -1; } else { while( ( buf_read( BUF_ID_UART, id, &data ) ) == PLATFORM_UNDERFLOW ); } return ( int )data; } else #endif return platform_s_uart_recv( id, timeout ); }
static int pgp_readkeyring(BUFFER *keys, char *filename) { FILE *keyfile; BUFFER *armored, *line, *tmp; int err = -1; if ((keyfile = mix_openfile(filename, "rb")) == NULL) return (err); armored = buf_new(); buf_read(armored, keyfile); fclose(keyfile); if (pgp_ispacket(armored)) { err = 0; buf_move(keys, armored); } else { line = buf_new(); tmp = buf_new(); while (1) { do if (buf_getline(armored, line) == -1) { goto end_greedy_dearmor; } while (!bufleft(line, begin_pgp)) ; buf_clear(tmp); buf_cat(tmp, line); buf_appends(tmp, "\n"); do { if (buf_getline(armored, line) == -1) { goto end_greedy_dearmor; } buf_cat(tmp, line); buf_appends(tmp, "\n"); } while (!bufleft(line, end_pgp)) ; if (pgp_dearmor(tmp, tmp) == 0) { err = ARMORED; buf_cat(keys, tmp); } } end_greedy_dearmor: buf_free(line); buf_free(tmp); } buf_free(armored); return (err); }
void mix_upd_stats(void) { FILE *f; BUFFER *statssrc; statssrc = buf_new(); buf_clear(statssrc); f = mix_openfile(STATSSRC, "r"); if (f != NULL) { buf_read(statssrc, f); fclose(f); } if (statssrc->length > 0) download_stats(statssrc->data); buf_free(statssrc); }
/* get a packet_id from buf */ bool reliable_ack_read_packet_id (struct buffer *buf, packet_id_type *pid) { packet_id_type net_pid; if (buf_read (buf, &net_pid, sizeof (net_pid))) { *pid = ntohpid (net_pid); dmsg (D_REL_DEBUG, "ACK read ID " packet_id_format " (buf->len=%d)", (packet_id_print_type)*pid, buf->len); return true; } dmsg (D_REL_LOW, "ACK read ID FAILED (buf->len=%d)", buf->len); return false; }
/* Flush buffered data to shell output */ static void telnet_flush(void) { struct buf *buf; buf = &telnet_data.writebuf; uint8_t data[2]; data[1] = '\0'; igordev_telnet.write_status = IDEV_STATUS_BUSY; /* Flush as long as it is ok. */ while (!BUF_EMPTY(buf)) { buf_read(buf, data, 1); shell_output((char *)data, ""); } igordev_telnet.write_status = IDEV_STATUS_OK; }
/* * Read num bytes from device and place it into data. * Data assumed to be a buffer large enough for num bytes. * Addr here is ignored. */ uint8_t telnet_recv(uint64_t addr, uint8_t *data, uint8_t num) { struct buf *buf; uint8_t byte; uint8_t i; buf = &telnet_data.readbuf; /* Avoid making larger buffers for now. */ for (i = 0; i < num; i++) { buf_read(buf, &byte, 1); if (BUF_EMPTY(buf)) break; *(data + i) = byte; } return (i); }
static int read_lines(SceUID fd, char *lines, size_t linebuf_size) { char *p; int ret; size_t re; if(linebuf_size == 0) { return -1; } p = lines; re = linebuf_size; while(re -- != 0) { ret = buf_read(fd, p); if(ret < 0) { break; } if(ret == 0) { if(p == lines) { ret = -1; } break; } if(*p == '\r') { continue; } if(*p == '\n') { break; } p++; } if(p < lines + linebuf_size) { *p = '\0'; } return ret >= 0 ? p - lines : ret; }
int main(int argc, char *argv[]) { int i, len = 0; char *buf = NULL, *fn; D_Parser *p; D_ParseNode *pn = NULL; process_args(&arg_state, argv); if (!arg_state.nfile_arguments) help(&arg_state, NULL); p = new_D_Parser(&parser_tables_gram, SIZEOF_MY_PARSE_NODE); p->save_parse_tree = save_parse_tree; p->ambiguity_fn = ambiguity_count_fn; p->partial_parses = partial_parses; p->dont_fixup_internal_productions = !fixup; p->fixup_EBNF_productions = fixup_ebnf; p->dont_compare_stacks = !compare_stacks; p->commit_actions_interval = commit_actions_interval; p->start_state = start_state; p->dont_use_greediness_for_disambiguation = dont_use_greediness_for_disambiguation; p->dont_use_height_for_disambiguation = dont_use_height_for_disambiguation; for (i = 0; i < arg_state.nfile_arguments; i++) { p->loc.pathname = arg_state.file_argument[i]; p->loc.line = 1; p->loc.col = 0; if (buf_read(arg_state.file_argument[i], &buf, &len) > 0) pn = dparse(p, buf, len); else d_fail("unable to read file '%s'", arg_state.file_argument[i]); if (pn) { free_D_ParseNode(p, pn); pn = 0; } else { fn = d_dup_pathname_str(p->loc.pathname); fprintf(stderr, "fatal error, '%s' line %d\n", fn, p->loc.line); FREE(fn); } if (buf) FREE(buf); } free_D_Parser(p); free_args(&arg_state); exit(0); }
/* * Essentially a loop around buf_read() to ensure "length" bytes are read * from dsi->buffer and/or the socket. * * @returns length on success, some value smaller then length indicates an error */ size_t dsi_stream_read(DSI *dsi, void *data, const size_t length) { size_t stored; ssize_t len; if (dsi->flags & DSI_DISCONNECTED) return 0; LOG(log_maxdebug, logtype_dsi, "dsi_stream_read(%u bytes)", length); stored = 0; while (stored < length) { len = buf_read(dsi, (u_int8_t *) data + stored, length - stored); if (len == -1 && (errno == EINTR || errno == EAGAIN)) { LOG(log_maxdebug, logtype_dsi, "dsi_stream_read: select read loop"); continue; } else if (len > 0) { stored += len; } else { /* eof or error */ /* don't log EOF error if it's just after connect (OSX 10.3 probe) */ #if 0 if (errno == ECONNRESET) dsi->flags |= DSI_GOT_ECONNRESET; #endif if (len || stored || dsi->read_count) { if (! (dsi->flags & DSI_DISCONNECTED)) { LOG(log_error, logtype_dsi, "dsi_stream_read: len:%d, %s", len, (len < 0) ? strerror(errno) : "unexpected EOF"); } return 0; } break; } } dsi->read_count += stored; LOG(log_maxdebug, logtype_dsi, "dsi_stream_read(%u bytes): got: %u", length, stored); return stored; }
void tls_crypt_v2_init_client_key(struct key_ctx_bi *key, struct buffer *wkc_buf, const char *key_file, const char *key_inline) { struct buffer client_key = alloc_buf(TLS_CRYPT_V2_CLIENT_KEY_LEN + TLS_CRYPT_V2_MAX_WKC_LEN); if (!read_pem_key_file(&client_key, tls_crypt_v2_cli_pem_name, key_file, key_inline)) { msg(M_FATAL, "ERROR: invalid tls-crypt-v2 client key format"); } struct key2 key2; if (!buf_read(&client_key, &key2.keys, sizeof(key2.keys))) { msg(M_FATAL, "ERROR: not enough data in tls-crypt-v2 client key"); } tls_crypt_v2_load_client_key(key, &key2, false); secure_memzero(&key2, sizeof(key2)); *wkc_buf = client_key; }
static void sub_convert(opt_t *o) { buf_t *b = NULL, *bswap = NULL; FILE *f; bool is_8xp; int i; /* if files provided as arguments, loop through them */ if(o->extra_args != NULL) { i = 0; while(o->extra_args[i] != NULL) { /* read file */ f = fopen(o->extra_args[i], "r"); if(f == NULL) { MAIN_ERR_CONV(errno, "could not open file \"%s\" for reading", o->extra_args[i]); } b = buf_read(f); fclose(f); /* ensure input formats are consistent */ if(i == 0) { is_8xp = b->is_8xp; } else { if(is_8xp != b->is_8xp) MAIN_ERR_CONV(EPERM, "inconsistent input file formats"); } /* convert file and append to bswap */ if(is_8xp) { /* TODO: expand */ if(bswap == NULL) bswap = buf_new(false); bswap = parse_buf_byte(b, bswap, o->list, o->extra_args[i], o->pretty, o->safe); } else { if(bswap == NULL) bswap = buf_new(true); bswap = parse_buf_str(b, bswap, o->list, o->extra_args[i]); } buf_free(b); b = NULL; /* error converting. */ if(bswap == NULL) { opt_free(o); exit(EINVAL); } i++; } /* else read a single file from stdin */ } else { b = buf_read(stdin); is_8xp = b->is_8xp; /* convert stdin */ if(is_8xp) { bswap = buf_new(true); bswap = parse_buf_byte(b, bswap, o->list, "stdin", o->pretty, o->safe); } else { bswap = buf_new(false); bswap = parse_buf_str(b, bswap, o->list, "stdin"); } buf_free(b); b = NULL; /* error converting. */ if(bswap == NULL) { opt_free(o); exit(EINVAL); } } /* end reading */ b = bswap; bswap = NULL; /* pack, if necessary */ if(!is_8xp) { if(o->name != NULL) bswap = header_pack_buf(b, o->name, o->archived); else bswap = header_pack_buf(b, "A", o->archived); buf_free(b); b = bswap; bswap = NULL; /* TODO: compact */ } /* write to file */ if(o->output != NULL) { f = fopen(o->output, "w"); if(f == NULL) { MAIN_ERR_CONV(errno, "could not open file \"%s\" for writing", o->output); } buf_write(b, f); fclose(f); buf_free(b); return; } else { buf_write(b, stdout); buf_free(b); return; } }
void dispatch_imsg(struct interface_info *ifi, int fd) { struct imsg_hdr hdr; char *medium, *reason, *filename, *servername, *prefix; size_t medium_len, reason_len, filename_len, servername_len, prefix_len, totlen; struct client_lease lease; int ret, i, optlen; struct buf *buf; buf_read(fd, &hdr, sizeof(hdr)); switch (hdr.code) { case IMSG_SCRIPT_INIT: if (hdr.len < sizeof(hdr) + sizeof(size_t)) error("corrupted message received"); buf_read(fd, &medium_len, sizeof(medium_len)); if (hdr.len < medium_len + sizeof(size_t) + sizeof(hdr) + sizeof(size_t) || medium_len == SIZE_T_MAX) error("corrupted message received"); if (medium_len > 0) { if ((medium = calloc(1, medium_len + 1)) == NULL) error("%m"); buf_read(fd, medium, medium_len); } else medium = NULL; buf_read(fd, &reason_len, sizeof(reason_len)); if (hdr.len < medium_len + reason_len + sizeof(hdr) || reason_len == SIZE_T_MAX) error("corrupted message received"); if (reason_len > 0) { if ((reason = calloc(1, reason_len + 1)) == NULL) error("%m"); buf_read(fd, reason, reason_len); } else reason = NULL; priv_script_init(reason, medium); free(reason); free(medium); break; case IMSG_SCRIPT_WRITE_PARAMS: bzero(&lease, sizeof lease); totlen = sizeof(hdr) + sizeof(lease) + sizeof(size_t); if (hdr.len < totlen) error("corrupted message received"); buf_read(fd, &lease, sizeof(lease)); buf_read(fd, &filename_len, sizeof(filename_len)); totlen += filename_len + sizeof(size_t); if (hdr.len < totlen || filename_len == SIZE_T_MAX) error("corrupted message received"); if (filename_len > 0) { if ((filename = calloc(1, filename_len + 1)) == NULL) error("%m"); buf_read(fd, filename, filename_len); } else filename = NULL; buf_read(fd, &servername_len, sizeof(servername_len)); totlen += servername_len + sizeof(size_t); if (hdr.len < totlen || servername_len == SIZE_T_MAX) error("corrupted message received"); if (servername_len > 0) { if ((servername = calloc(1, servername_len + 1)) == NULL) error("%m"); buf_read(fd, servername, servername_len); } else servername = NULL; buf_read(fd, &prefix_len, sizeof(prefix_len)); totlen += prefix_len; if (hdr.len < totlen || prefix_len == SIZE_T_MAX) error("corrupted message received"); if (prefix_len > 0) { if ((prefix = calloc(1, prefix_len + 1)) == NULL) error("%m"); buf_read(fd, prefix, prefix_len); } else prefix = NULL; for (i = 0; i < 256; i++) { totlen += sizeof(optlen); if (hdr.len < totlen) error("corrupted message received"); buf_read(fd, &optlen, sizeof(optlen)); lease.options[i].data = NULL; lease.options[i].len = optlen; if (optlen > 0) { totlen += optlen; if (hdr.len < totlen || optlen == SIZE_T_MAX) error("corrupted message received"); lease.options[i].data = calloc(1, optlen + 1); if (lease.options[i].data == NULL) error("%m"); buf_read(fd, lease.options[i].data, optlen); } } lease.server_name = servername; lease.filename = filename; priv_script_write_params(prefix, &lease); free(servername); free(filename); free(prefix); for (i = 0; i < 256; i++) if (lease.options[i].len > 0) free(lease.options[i].data); break; case IMSG_SCRIPT_GO: if (hdr.len != sizeof(hdr)) error("corrupted message received"); ret = priv_script_go(); hdr.code = IMSG_SCRIPT_GO_RET; hdr.len = sizeof(struct imsg_hdr) + sizeof(int); if ((buf = buf_open(hdr.len)) == NULL) error("buf_open: %m"); if (buf_add(buf, &hdr, sizeof(hdr))) error("buf_add: %m"); if (buf_add(buf, &ret, sizeof(ret))) error("buf_add: %m"); if (buf_close(fd, buf) == -1) error("buf_close: %m"); break; case IMSG_SEND_PACKET: send_packet_priv(ifi, &hdr, fd); break; default: error("received unknown message, code %d", hdr.code); } }
chunk_ptr chunk_read(int fd, bool* eofp) { if (fd > maxfd) { // on first call, we zero the buffer set if (maxfd == 0) { FD_ZERO(&buf_set); FD_ZERO(&in_set); } maxfd = fd; } buf_node* curr_node = NULL; buf_node* temp_node = NULL; //create new head if (buf_list_head == NULL) { buf_list_head = calloc_or_fail(sizeof(buf_node), 1, "chunk_read create head"); buf_list_head->fd = fd; #if RPT >= 5 report(5, "created a node for fd %d as head\n", fd); #endif buf_list_head->length = 0; buf_list_head->location = 0; buf_list_head->buf = calloc_or_fail(CHUNK_MAX_SIZE, 2, "chunk_read create head buf"); curr_node = buf_list_head; } // search for the fd in the buffer list, if it exists else { temp_node = buf_list_head; while (temp_node != NULL && curr_node == NULL) { if (fd == temp_node->fd) { curr_node = temp_node; #if RPT >= 5 report(5, "found node for fd %d\n", fd); #endif } temp_node = temp_node->next; } } // if it doesn't exist, create the new fd buffer at the head of the list if (curr_node == NULL) { curr_node = calloc_or_fail(sizeof(buf_node), 1, "chunk_read create node"); curr_node->fd = fd; curr_node->length = 0; curr_node->location = 0; curr_node->next = buf_list_head; curr_node->buf = calloc_or_fail(CHUNK_MAX_SIZE, 2, "chunk_read create head buf"); #if RPT >= 5 report(5, "created a node for fd %d at head\n", fd); #endif buf_list_head = curr_node; } // if we can copy to the beginning, then we copy to the beginning // (if the read point is past the beginning, and if the end of // the buffered data is past the midway point of the buffer) if (curr_node->length + curr_node->location >= CHUNK_MAX_SIZE && curr_node->location > 0) { memmove(curr_node->buf, (char *)(curr_node->buf + curr_node->location), curr_node->length); curr_node->location = 0; } // read if possible - if there is space, if the inset contains it, and if we // want to use buffering (otherwise we don't want random buffer refills) if (((curr_node->length + curr_node->location) < CHUNK_MAX_SIZE) && bufferReadBool && !(!(FD_ISSET(fd, &in_set))) ) { #if RPT >= 5 report(5, "reading for %d\n", curr_node->fd); #endif ssize_t n = read(curr_node->fd, curr_node->buf + curr_node->location + curr_node->length, CHUNK_MAX_SIZE); curr_node->length += n; } #if RPT >= 5 report(5, "about to get header for %d\n", fd); #endif // get header of chunk size_t need_cnt = sizeof(chunk_t); unsigned char buf[CHUNK_MAX_SIZE]; unsigned char* buf_ptr = (unsigned char*)buf; ssize_t n = buf_read(curr_node, eofp, buf_ptr, need_cnt); //ssize_t n = read(curr_node->fd, buf, need_cnt); if (n <= 0) { return NULL; } #if RPT >= 5 report(5, "about to get rest of chunk for fd %d\n", fd); #endif // get rest of chunk chunk_ptr creadp = (chunk_ptr) buf_ptr; size_t len = creadp->length; #if RPT >= 5 report(5, "len needed: %d", len); #endif if (len > 1) { need_cnt = WORD_BYTES * (len - 1); #if RPT >= 5 report(5, "head buf pointer at %p", buf_ptr); #endif buf_ptr = (unsigned char *)(buf_ptr + n); #if RPT >= 5 report(5, "moved pointer to %p for rest", buf_ptr); #endif ssize_t n = buf_read(curr_node, eofp, buf_ptr, need_cnt); //ssize_t n = read(curr_node->fd, buf_ptr, need_cnt); if (n < 0) { chunk_error("Failed read", NULL); if (eofp) *eofp = false; return NULL; } } #if RPT >= 5 report(5, "exiting chunk_read_buffered_builtin!\n"); #endif if (eofp) *eofp = false; return chunk_clone(creadp); }
int RDMA_file_transfer(char* src, char* dst, int buf_size, int count) { int i; int fd; int read_size; int tag; int ctl_msg_size; struct file_buffer *fbufs; int fbuf_index = 0; int *flags; int flag_init=0; char ctl_msg[1536]; double e,s; int send_buf = 0; s = get_dtime(); fbufs = (struct file_buffer *)malloc(sizeof(struct file_buffer) * count); flags = (int *)malloc(sizeof(int) * count); for (i = 0; i < count; i++) { fbufs[i % count].buf = (char *)malloc(buf_size); flags[i % count] = 1; } // fprintf(stderr, "ACT lib: SEND: %d: src=%s dst=%s \n", file_send_count, src, dst); /*send init*/ tag=get_tag(); sprintf(ctl_msg, "%d\t%s\t", tag, dst); // fprintf(stderr, "ACT lib: SEND: %d: ctlmsg=%s\n", file_send_count, ctl_msg); file_send_count++; //printf(ctl_msg); ctl_msg_size = strlen(ctl_msg); flag_init = 0; RDMA_Isendr(ctl_msg, ctl_msg_size, TRANSFER_INIT, &flag_init, &rdma_comm); // fprintf(stderr, "ACT lib: SEND: %d: DONE ctlmsg=%s\n", file_send_count, ctl_msg); /*---------*/ /*send file*/ fd = open(src, O_RDONLY); read_size = buf_read(fd, fbufs[fbuf_index].buf, buf_size); RDMA_Wait (&flag_init); do { // printf("sent fbuf_index=%d\n", fbuf_index); // fprintf(stderr, "ACT lib: SEND: Befor RDNA Isendr call: ctlmsg=%s\n", ctl_msg); flags[fbuf_index] = 0; RDMA_Isendr(fbufs[fbuf_index].buf, read_size, tag, &flags[fbuf_index], &rdma_comm); send_buf += read_size; // fprintf(stderr, "ACT lib: SEND: After RDNA Isendr call: ctlmsg=%s\n", ctl_msg); //flags[fbuf_index] = 1; // printf("... sent done\n"); read_size = buf_read(fd, fbufs[(fbuf_index + 1) % count].buf, buf_size); // fprintf(stderr, "ACT lib: SEND: read time = %f secs, read size = %f MB, throughput = %f MB/s: ctlmsg=%s\n", e - s, read_size/1000000.0, read_size/(e - s)/1000000.0, ctl_msg); //fprintf(stderr, "ACT lib: SEND: Before wait: ctlmsg=%s\n", ctl_msg); RDMA_Wait (&flags[fbuf_index]); // fprintf(stderr, "ACT lib: SEND: After wait: ctlmsg=%s\n", ctl_msg); fbuf_index = (fbuf_index + 1) % count; } while (read_size > 0); /*---------*/ /*send fin*/ sprintf(ctl_msg, "%d\t%s", tag, dst); ctl_msg_size = strlen(ctl_msg); RDMA_Sendr(ctl_msg, ctl_msg_size, TRANSFER_FIN, &rdma_comm); /*---------*/ close(fd); for (i = 0; i < count; i++) { free(fbufs[i % count].buf); } free(flags); free(fbufs); e = get_dtime(); // fprintf(stderr, "ACT lib: SEND: file send: Time= %f , size= %d \n", e - s, send_buf); return 0; }
/** * Grabs the next available character, and also stores modifier key data at the * time of the key press. * * @param pid The process that made the request * @returns 1 if a proper IO-request was created, otherwise 0 */ int char_read( char *buf, Pcb* pc ){ return buf_read( buf, 0, pc ); }
void handle_client_read(void *arg) { client_t *cli = (client_t*) arg; buf_t *buf = cli->buf_recv; apr_socket_t *sock = cli->pjob->pfd.desc.s; apr_status_t status = buf_from_sock(buf, sock); // invoke msg handling. size_t sz_c = 0; while ((sz_c = buf_sz_content(buf)) > SZ_SZMSG) { uint32_t sz_msg = 0; buf_peek(buf, (uint8_t*)&sz_msg, sizeof(sz_msg)); if (sz_c >= sz_msg + SZ_SZMSG + SZ_MSGID) { buf_read(buf, (uint8_t*)&sz_msg, SZ_SZMSG); msgid_t msgid = 0; buf_read(buf, (uint8_t*)&msgid, SZ_MSGID); rpc_state *state = (rpc_state*)malloc(sizeof(rpc_state)); state->sz_input = sz_msg; state->raw_input = (uint8_t *)malloc(sz_msg); // state->ctx = ctx; buf_read(buf, state->raw_input, sz_msg); // state->ctx = ctx; /* apr_thread_pool_push(tp_on_read_, (*(ctx->on_recv)), (void*)state, 0, NULL); // mpr_thread_pool_push(tp_read_, (void*)state); */ // apr_atomic_inc32(&n_data_recv_); //(*(ctx->on_recv))(NULL, state); // FIXME call rpc_state* (**fun)(void*) = NULL; size_t sz; mpr_hash_get(cli->comm->ht, &msgid, SZ_MSGID, (void**)&fun, &sz); SAFE_ASSERT(fun != NULL); LOG_TRACE("going to call function %x", *fun); // ctx->n_rpc++; // ctx->sz_recv += n; (**fun)(state); free(state->raw_input); free(state); } else { break; } } if (status == APR_SUCCESS) { } else if (status == APR_EOF) { LOG_DEBUG("cli poll on read, received eof, close socket"); poll_mgr_remove_job(cli->pjob->mgr, cli->pjob); } else if (status == APR_ECONNRESET) { LOG_ERROR("cli poll on read. connection reset."); poll_mgr_remove_job(cli->pjob->mgr, cli->pjob); // TODO [improve] you may retry connect } else if (status == APR_EAGAIN) { LOG_DEBUG("cli poll on read. read socket busy, resource temporarily unavailable."); // do nothing. } else { LOG_ERROR("unkown error on poll reading. %s\n", apr_strerror(status, (char*)malloc(100), 100)); SAFE_ASSERT(0); } }
void handle_sconn_read(void* arg) { LOG_TRACE("sconn read handle read."); sconn_t *sconn = (sconn_t *) arg; buf_t *buf = sconn->buf_recv; apr_socket_t *sock = sconn->pjob->pfd.desc.s; apr_status_t status = APR_SUCCESS; //status = apr_socket_recv(pfd->desc.s, (char *)buf, &n); status = buf_from_sock(buf, sock); // invoke msg handling. size_t sz_c = 0; while ((sz_c = buf_sz_content(buf)) > SZ_SZMSG) { uint32_t sz_msg = 0; SAFE_ASSERT(buf_peek(buf, (uint8_t*)&sz_msg, SZ_SZMSG) == SZ_SZMSG); SAFE_ASSERT(sz_msg > 0); if (sz_c >= sz_msg + SZ_SZMSG + SZ_MSGID) { SAFE_ASSERT(buf_read(buf, (uint8_t*)&sz_msg, SZ_SZMSG) == SZ_SZMSG); msgid_t msgid = 0; SAFE_ASSERT(buf_read(buf, (uint8_t*)&msgid, SZ_MSGID) == SZ_MSGID); LOG_TRACE("next message size: %d, type: %x", (int32_t)sz_msg, (int32_t)msgid); rpc_state *state = malloc(sizeof(rpc_state)); state->sz_input = sz_msg; state->raw_input = malloc(sz_msg); state->raw_output = NULL; state->sz_output = 0; state->sconn = sconn; state->msgid = msgid; SAFE_ASSERT(buf_read(buf, (uint8_t*)state->raw_input, sz_msg) == sz_msg); // apr_thread_pool_push(tp_on_read_, (*(ctx->on_recv)), (void*)state, 0, NULL); // mpr_thread_pool_push(tp_read_, (void*)state); // apr_atomic_inc32(&n_data_recv_); //(*(ctx->on_recv))(NULL, state); // FIXME call if (msgid & NEW_THREAD_CALL) { apr_thread_pool_t *tp = sconn->tp; SAFE_ASSERT(tp != NULL); apr_thread_pool_push(tp, msg_call, state, 0, NULL); } else { msg_call(NULL, state); } } else { break; } } if (status == APR_SUCCESS) { } else if (status == APR_EOF) { LOG_INFO("sconn poll on read, received eof, close socket"); poll_mgr_remove_job(sconn->pjob->mgr, sconn->pjob); } else if (status == APR_ECONNRESET) { LOG_INFO("on read. connection reset, close socket"); poll_mgr_remove_job(sconn->pjob->mgr, sconn->pjob); // TODO [improve] you may retry connect } else if (status == APR_EAGAIN) { LOG_TRACE("sconn poll on read, socket busy, resource temporarily unavailable."); // do nothing. } else { LOG_ERROR("unkown error on poll reading. %s\n", apr_strerror(status, malloc(100), 100)); SAFE_ASSERT(0); } }
int begin(char* base_file_name, unsigned char *png_buf, long long png_length) { MY_PNG_READ_OFFSET = 0; PNG_LENGTH = png_length; ENTIRE_PNG_BUF = png_buf; if (png_sig_cmp(ENTIRE_PNG_BUF, 0, 8) != 0) { error(-1, "png_sig_cmp", E_INVALID); return -1; } DEBUG_PRINT(("Initial png size is %lld bytes\n", PNG_LENGTH)); my_png_meta *pm = calloc(1, sizeof(my_png_meta)); my_init_libpng(pm); //If libpng errors, we end up here if (setjmp(png_jmpbuf(pm->read_ptr))) { DEBUG_PRINT(("libpng called setjmp!\n")); my_deinit_libpng(pm); free(ENTIRE_PNG_BUF); error(-1, "libpng", "libpng encountered an error\n"); return -1; } //Normally a file, but instead make it our buffer void *read_io_ptr = png_get_io_ptr(pm->read_ptr); png_set_read_fn(pm->read_ptr, read_io_ptr, my_png_read_fn); //Transform all PNG image types to RGB int transforms = PNG_TRANSFORM_GRAY_TO_RGB | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_EXPAND; png_read_png(pm->read_ptr, pm->info_ptr, transforms, NULL); //Now that it was read and transformed, its size will differ PNG_LENGTH = 0; //Lets collect our metadata struct ihdr_infos_s ihdr_infos; ihdr_infos.bit_depth = png_get_bit_depth(pm->read_ptr, pm->info_ptr); ihdr_infos.color_type = png_get_color_type(pm->read_ptr, pm->info_ptr); ihdr_infos.filter_method = png_get_filter_type(pm->read_ptr, pm->info_ptr); ihdr_infos.compression_type = png_get_compression_type(pm->read_ptr, pm->info_ptr); ihdr_infos.interlace_type = png_get_interlace_type(pm->read_ptr, pm->info_ptr); ihdr_infos.height = png_get_image_height(pm->read_ptr, pm->info_ptr); ihdr_infos.width = png_get_image_width(pm->read_ptr, pm->info_ptr); if (ihdr_infos.color_type != 2) { DEBUG_PRINT((E_INVALID)); free(ENTIRE_PNG_BUF); my_deinit_libpng(pm); DEBUG_PRINT(("Looks like libpng could not correctly convert to RGB\n")); return -1; } //Just in case we want to enable alpha, etc switch(ihdr_infos.color_type) { case 0: //greyscale case 3: //indexed ihdr_infos.bytes_per_pixel = 1; break; case 4: ihdr_infos.bytes_per_pixel = 2; break; //greyscale w/ alpha case 2: ihdr_infos.bytes_per_pixel = 3; break; //Truecolour (RGB) case 6: ihdr_infos.bytes_per_pixel = 4; break; //Truecolour w/ alpha default: error_fatal(1, "ihdr_infos", "Unknown image type"); //should never happen } ihdr_infos.scanline_len = (ihdr_infos.bytes_per_pixel * ihdr_infos.width) + 1; DEBUG_PRINT(("HEIGHT: %u\n", ihdr_infos.height)); DEBUG_PRINT(("WIDTH: %u\n", ihdr_infos.width)); DEBUG_PRINT(("BIT_DEPTH: %u\n", ihdr_infos.bit_depth)); // Don't compress, since we are merely copying it to memory, // we will be decompressing it again anyway png_set_compression_level(pm->write_ptr, Z_NO_COMPRESSION); void *write_io_ptr = png_get_io_ptr(pm->write_ptr); png_set_write_fn(pm->write_ptr, write_io_ptr, my_png_write_fn, my_png_dummy_flush); //Make sure we use all filters png_set_filter(pm->write_ptr, 0, PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | PNG_FILTER_UP | PNG_FILTER_VALUE_UP | PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG | PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH); //Set our comment struct png_text_struct comment_struct; comment_struct.compression = -1; comment_struct.key = " Glitched by pnglitch.xyz "; comment_struct.text = NULL; comment_struct.text_length = 0; png_set_text(pm->write_ptr, pm->info_ptr, &comment_struct, 1); //Buffer is Written using callback my_png_write_fn to buffer //ENTIRE_PNG_BUF. PNG_LENGTH will be updated automatically by it png_write_png(pm->write_ptr, pm->info_ptr, PNG_TRANSFORM_IDENTITY, NULL); my_deinit_libpng(pm); DEBUG_PRINT(("libpng output buf is %lld bytes\n", PNG_LENGTH)); //Now that libpng has converted the image //and we have it in a buffer, we process it by hand with zlib struct z_stream_s inflate_stream; my_init_zlib(&inflate_stream); inflateInit(&inflate_stream); //Pointer to keep track of where we are unsigned char *pngp = ENTIRE_PNG_BUF; //Skip PNG Signature pngp += 8; //Get Header unsigned char ihdr_bytes_buf[4+4+13+4]; // size + label + content + crc buf_read(ihdr_bytes_buf, &pngp, 4+4+13+4); //When we run into non-idat chunks, we will want to preserve them. //The spec says there's no chunk that needs to go after IDAT, //so we can simply concatenate all of these chunks into a buffer //then write them all at once after the IHDR //ancillary chunks, eg comments unsigned char *ancil_chunks_buf = calloc(1,1); long long ancil_chunks_len = 0; unsigned char *unzip_idats_buf = calloc(1, 1); long unzip_buf_len = 1; long unzip_buf_offset = 0; long long zipped_idats_len = 0; //Length of all idats as we read them unsigned long accum_png_len = 8 + (4+4+13+4); int chunk_count = 0; printf("Uncompressing image data...\n"); while (1) { unsigned char chunk_label[4]; unsigned char chunk_len_buf[4]; buf_read(chunk_len_buf, &pngp, 4); //first 4 bytes are the length of data section long chunk_len = four_bytes_to_int(chunk_len_buf); accum_png_len += chunk_len + 4 + 4 + 4; // plus len, crc, label DEBUG_PRINT(("at %lu --> %lld\n", accum_png_len, PNG_LENGTH)); //leave at end of buffer if (accum_png_len >= PNG_LENGTH) break; //read the chunk label (name of this header) buf_read(chunk_label, &pngp, 4); DEBUG_PRINT(("Reading chunk %d with label '%c%c%c%c', size %ld\n", chunk_count, chunk_label[0], chunk_label[1], chunk_label[2], chunk_label[3], chunk_len)); chunk_count += 1; if (memcmp(chunk_label, "IDAT", 4) == 0) { zipped_idats_len += chunk_len; //read the chunk's data section unsigned char *raw_chunk_buf = calloc(chunk_len, 1); buf_read(raw_chunk_buf, &pngp, chunk_len); //Tell inflate to uncompress it inflate_stream.next_in = raw_chunk_buf; inflate_stream.avail_in = chunk_len; //Now uncompress it (resizes buffer automatically) unsigned char *check_uncompress = uncompress_buffer(&inflate_stream, unzip_idats_buf, &unzip_buf_len, &unzip_buf_offset); //Stop if error if (check_uncompress == NULL) { DEBUG_PRINT((E_GLITCH)); free(ancil_chunks_buf); free(raw_chunk_buf); free(unzip_idats_buf); free(ENTIRE_PNG_BUF); return -1; } //Moving on unzip_idats_buf = check_uncompress; free(raw_chunk_buf); pngp += 4; // skip CRC } else { //This is not an idat ancil_chunks_buf = realloc(ancil_chunks_buf, ancil_chunks_len + 4 + 4 + chunk_len + 4); //make room for new data //append length and label bytes append_bytes(ancil_chunks_buf, chunk_len_buf, &ancil_chunks_len, 4); append_bytes(ancil_chunks_buf, chunk_label, &ancil_chunks_len, 4); //append chunk data unsigned char *raw_chunk_buf = calloc(chunk_len, 1); buf_read(raw_chunk_buf, &pngp, chunk_len); append_bytes(ancil_chunks_buf, raw_chunk_buf, &ancil_chunks_len, chunk_len ); //append chunk crc unsigned char chunk_crc_buf[4]; buf_read(chunk_crc_buf, &pngp, 4); append_bytes(ancil_chunks_buf, chunk_crc_buf, &ancil_chunks_len, 4); free(raw_chunk_buf); DEBUG_PRINT(("ancillary chunks length: %lld\n", ancil_chunks_len)); } } //buf contains all idats uncompressed, concatenated unsigned long unzipped_idats_len = inflate_stream.total_out; unzip_idats_buf = realloc(unzip_idats_buf, unzipped_idats_len); //we already have ancillary chunks and idats, don't need the original free(ENTIRE_PNG_BUF); inflateEnd(&inflate_stream); printf("Uncompressed %lld bytes to %ld bytes\n", zipped_idats_len, unzipped_idats_len); printf("Glitching image data...\n"); for (int g=0;g<NUM_OUTPUT_FILES;g++) { //do glitches switch(g) { case 5: glitch_random(unzip_idats_buf, unzipped_idats_len, ihdr_infos.scanline_len, 0.0005); break; case 6: glitch_random_filter(unzip_idats_buf, unzipped_idats_len, ihdr_infos.scanline_len); break; default: glitch_filter(unzip_idats_buf, unzipped_idats_len, ihdr_infos.scanline_len, g); } //recompress so we can write them to file long long glitched_idats_len = 0; unsigned char *glitched_idats = zip_idats(unzip_idats_buf, unzipped_idats_len, &glitched_idats_len); if (glitched_idats == NULL) { DEBUG_PRINT((E_GLITCH)); free (unzip_idats_buf); free (ancil_chunks_buf); return -1; } char path[MAX_PATH_LENGTH]; bzero(path, MAX_PATH_LENGTH); snprintf(path, MAX_PATH_LENGTH, "%s%s%s-%d.png", OUTPUT_DIRECTORY, DIR_SEP, base_file_name, g); DEBUG_PRINT(("Output file name is %s\n", path)); FILE *outfp = fopen(path, "wb"); write_glitched_image(glitched_idats, glitched_idats_len, ihdr_bytes_buf, ancil_chunks_buf, ancil_chunks_len, outfp); printf("%s\n", path); fflush(stdout); fclose(outfp); free(glitched_idats); } free(ancil_chunks_buf); free(unzip_idats_buf); return 0; }
/* Read a single sexp from the reader. */ object_t *read_sexp (reader_t * r) { /* Check for a shebang line. */ if (r->shebang == -1) { char str[2]; str[0] = reader_getc (r); str[1] = reader_getc (r); if (str[0] == '#' && str[1] == '!') { /* Looks like a she-bang line. */ r->shebang = 1; consume_line (r); } else { r->shebang = 0; reader_putc (r, str[1]); reader_putc (r, str[0]); } } r->done = 0; r->error = 0; push (r); print_prompt (r); while (!r->eof && !r->error && (list_empty (r) || stack_height (r) > 1)) { int nc, c = reader_getc (r); switch (c) { case EOF: r->eof = 1; break; /* Comments */ case ';': consume_line (r); break; /* Dotted pair */ case '.': nc = reader_getc (r); if (strchr (" \t\r\n()", nc) != NULL) { if (r->state->dotpair_mode > 0) read_error (r, "invalid dotted pair syntax"); else if (r->state->vector_mode > 0) read_error (r, "dotted pair not allowed in vector"); else { r->state->dotpair_mode = 1; reader_putc (r, nc); } } else { /* Turn it into a decimal point. */ reader_putc (r, nc); reader_putc (r, '.'); reader_putc (r, '0'); } break; /* Whitespace */ case '\n': r->linecnt++; print_prompt (r); case ' ': case '\t': case '\r': break; /* Parenthesis */ case '(': push (r); break; case ')': if (r->state->quote_mode) read_error (r, "unbalanced parenthesis"); else if (r->state->vector_mode) read_error (r, "unbalanced brackets"); else addpop (r); break; /* Vectors */ case '[': push (r); r->state->vector_mode = 1; break; case ']': if (r->state->quote_mode) read_error (r, "unbalanced parenthesis"); else if (!r->state->vector_mode) read_error (r, "unbalanced brackets"); else addpop (r); break; /* Quoting */ case '\'': push (r); add (r, quote); if (!r->error) r->state->quote_mode = 1; break; /* strings */ case '"': buf_read (r, "\""); add (r, parse_str (r)); reader_getc (r); /* Throw away other quote. */ break; /* numbers and symbols */ default: buf_append (r, c); buf_read (r, " \t\r\n()[];"); object_t *o = parse_atom (r); if (!r->error) add (r, o); break; } } if (!r->eof && !r->error) consume_whitespace (r); if (r->error) return err_symbol; /* Check state */ r->done = 1; if (stack_height (r) > 1 || r->state->quote_mode || r->state->dotpair_mode == 1) { read_error (r, "premature end of file"); return err_symbol; } if (list_empty (r)) { obj_destroy (pop (r)); return NIL; } object_t *wrap = pop (r); object_t *sexp = UPREF (CAR (wrap)); obj_destroy (wrap); return sexp; }