void dispatcher_send_message(Dispatcher *dispatcher, uint32_t message_type, void *payload) { DispatcherMessage *msg; uint32_t ack; int send_fd = dispatcher->send_fd; assert(dispatcher->max_message_type > message_type); assert(dispatcher->messages[message_type].handler); msg = &dispatcher->messages[message_type]; pthread_mutex_lock(&dispatcher->lock); if (write_safe(send_fd, (uint8_t*)&message_type, sizeof(message_type)) == -1) { spice_printerr("error: failed to send message type for message %d", message_type); goto unlock; } if (write_safe(send_fd, payload, msg->size) == -1) { spice_printerr("error: failed to send message body for message %d", message_type); goto unlock; } if (msg->ack == DISPATCHER_ACK) { if (read_safe(send_fd, (uint8_t*)&ack, sizeof(ack), 1) == -1) { spice_printerr("error: failed to read ack"); } else if (ack != ACK) { spice_printerr("error: got wrong ack value in dispatcher " "for message %d\n", message_type); /* TODO handling error? */ } } unlock: pthread_mutex_unlock(&dispatcher->lock); }
void handle_mapper() { char buffer[DEFAULT_BUFFER]; int i; while(read_safe(mapper_pipes[process_number][READ_END], buffer, DEFAULT_BUFFER) > 0) { for(i = 0; i < strlen(buffer) && buffer[i] != '\n'; i++) { char letter = buffer[i]; if((letter >= (int)'a') && (letter <= (int) 'z')) { int index = (int)letter - (int)'a'; write_safe(reducer_pipes[index][WRITE_END], &letter, 1); } } } for(i = 0; i < NUMBER_MAPPERS; i++) { close_safe(mapper_pipes[i][READ_END]); } for(i = 0; i < NUMBER_REDUCERS; i++) { close_safe(reducer_pipes[i][WRITE_END]); } exit(0); }
void handle_parent(FILE *input) { char buffer[DEFAULT_BUFFER]; int i; for(i = 0; (fgets(buffer, DEFAULT_BUFFER, input) != NULL); i++) { write_safe(mapper_pipes[i % NUMBER_MAPPERS][WRITE_END], buffer, DEFAULT_BUFFER); } // close mapper pipes then wait for mappers to exit for(i = 0; i < NUMBER_MAPPERS; i++) { close_safe(mapper_pipes[i][WRITE_END]); } int status; for(i = 0; i < NUMBER_MAPPERS; i++) { wait_safe(&status); } // close reducer pipes then wait for reducers to exit for(i = 0; i < NUMBER_REDUCERS; i++) { close_safe(reducer_pipes[i][WRITE_END]); } for(i = 0; i < NUMBER_REDUCERS; i++) { wait_safe(&status); } }
bool f$copy (const string &from, const string &to) { struct stat stat_buf; dl::enter_critical_section();//OK int read_fd = open (from.c_str(), O_RDONLY); if (read_fd < 0) { dl::leave_critical_section(); return false; } if (fstat (read_fd, &stat_buf) < 0) { close (read_fd); dl::leave_critical_section(); return false; } if (!S_ISREG (stat_buf.st_mode)) { php_warning ("Regular file expected as first argument in function copy, \"%s\" is given", from.c_str()); close (read_fd); dl::leave_critical_section(); return false; } int write_fd = open (to.c_str(), O_WRONLY | O_CREAT | O_TRUNC, stat_buf.st_mode); if (write_fd < 0) { close (read_fd); dl::leave_critical_section(); return false; } size_t size = stat_buf.st_size; while (size > 0) { size_t len = min (size, (size_t)PHP_BUF_LEN); if (read_safe (read_fd, php_buf, len) < (ssize_t)len) { break; } if (write_safe (write_fd, php_buf, len) < (ssize_t)len) { break; } size -= len; } close (read_fd); close (write_fd); dl::leave_critical_section(); return size == 0; }
static int dispatcher_handle_single_read(Dispatcher *dispatcher) { int ret; uint32_t type; DispatcherMessage *msg = NULL; uint8_t *payload = dispatcher->priv->payload; uint32_t ack = ACK; if ((ret = read_safe(dispatcher->priv->recv_fd, (uint8_t*)&type, sizeof(type), 0)) == -1) { spice_printerr("error reading from dispatcher: %d", errno); return 0; } if (ret == 0) { /* no messsage */ return 0; } msg = &dispatcher->priv->messages[type]; if (read_safe(dispatcher->priv->recv_fd, payload, msg->size, 1) == -1) { spice_printerr("error reading from dispatcher: %d", errno); /* TODO: close socketpair? */ return 0; } if (dispatcher->priv->any_handler) { dispatcher->priv->any_handler(dispatcher->priv->opaque, type, payload); } if (msg->handler) { msg->handler(dispatcher->priv->opaque, payload); } else { spice_printerr("error: no handler for message type %d", type); } if (msg->ack == DISPATCHER_ACK) { if (write_safe(dispatcher->priv->recv_fd, (uint8_t*)&ack, sizeof(ack)) == -1) { spice_printerr("error writing ack for message %d", type); /* TODO: close socketpair? */ } } else if (msg->ack == DISPATCHER_ASYNC && dispatcher->priv->handle_async_done) { dispatcher->priv->handle_async_done(dispatcher->priv->opaque, type, (void *)payload); } return 1; }
int main(int argc, char **argv) { int fd, fd_s, ctl_fd; pid_t extpid; int pfd[2]; int sk_bsize; int ret, snd, snd_size, rcv_size = 0, rcv_buf_size; #ifdef ZDTM_TCP_LOCAL test_init(argc, argv); #endif if (pipe(pfd)) { pr_perror("pipe() failed"); return 1; } extpid = fork(); if (extpid < 0) { pr_perror("fork() failed"); return 1; } else if (extpid == 0) { int size; char c; #ifndef ZDTM_TCP_LOCAL test_ext_init(argc, argv); #endif close(pfd[1]); read_safe(pfd[0], &port, sizeof(port)); fd = tcp_init_client(ZDTM_FAMILY, "127.0.0.1", port); if (fd < 0) return 1; ctl_fd = tcp_init_client(ZDTM_FAMILY, "127.0.0.1", port); if (fd < 0) return 1; snd_size = fill_sock_buf(fd); if (snd_size <= 0) return 1; write_safe(ctl_fd, &snd_size, sizeof(snd_size)); read_safe(ctl_fd, &rcv_buf_size, sizeof(rcv_buf_size)); while (1) { /* heart beat */ read_safe(ctl_fd, &ret, sizeof(ret)); if (ret < 0) break; rcv_buf_size += ret; snd = fill_sock_buf(fd); if (snd < 0) return -1; snd_size += snd; if (rcv_buf_size / 2) { ret = clean_sk_buf(fd, rcv_buf_size / 2); if (ret <= 0) return 1; } else ret = 0; rcv_buf_size -= ret; rcv_size += ret; write_safe(ctl_fd, &snd, sizeof(snd)); } read_safe(ctl_fd, &ret, sizeof(ret)); rcv_buf_size += ret; write_safe(ctl_fd, &snd_size, sizeof(snd_size)); if (read(ctl_fd, &c, 1) != 0) { pr_perror("read"); return 1; } if (shutdown(fd, SHUT_WR) == -1) { pr_perror("shutdown"); return 1; } size = clean_sk_buf(fd, 0); if (size < 0) return 1; if (size != rcv_buf_size) { fail("the received buffer contains only %d bytes (%d)\n", size, rcv_buf_size); } rcv_size += size; write_safe(ctl_fd, &rcv_size, sizeof(rcv_size)); close(fd); return 0; } #ifndef ZDTM_TCP_LOCAL test_init(argc, argv); #endif if ((fd_s = tcp_init_server(ZDTM_FAMILY, &port)) < 0) { pr_perror("initializing server failed"); return 1; } close(pfd[0]); write_safe(pfd[1], &port, sizeof(port)); close(pfd[1]); /* * parent is server of TCP connection */ fd = tcp_accept_server(fd_s); if (fd < 0) { pr_perror("can't accept client connection %m"); return 1; } ctl_fd = tcp_accept_server(fd_s); if (ctl_fd < 0) { pr_perror("can't accept client connection %m"); return 1; } sk_bsize = TCP_MAX_BUF; if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sk_bsize, sizeof(sk_bsize)) == -1) { pr_perror("Can't set snd buf"); return 1; } sk_bsize = TCP_MAX_BUF; if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &sk_bsize, sizeof(sk_bsize)) == -1) { pr_perror("Can't set snd buf"); return 1; } snd_size = fill_sock_buf(fd); if (snd_size <= 0) return 1; read_safe(ctl_fd, &rcv_buf_size, sizeof(rcv_buf_size)); write_safe(ctl_fd, &snd_size, sizeof(snd_size)); test_daemon(); snd = 0; while (test_go()) { /* heart beat */ if (rcv_buf_size / 2) { ret = clean_sk_buf(fd, rcv_buf_size / 2); if (ret <= 0) return 1; } else ret = 0; rcv_size += ret; rcv_buf_size -= ret; write_safe(ctl_fd, &snd, sizeof(snd)); read_safe(ctl_fd, &ret, sizeof(ret)); rcv_buf_size += ret; snd = fill_sock_buf(fd); if (snd < 0) return -1; snd_size += snd; } ret = -1; write_safe(ctl_fd, &ret, sizeof(ret)); write_safe(ctl_fd, &snd, sizeof(ret)); read_safe(ctl_fd, &snd, sizeof(snd)); if (shutdown(ctl_fd, SHUT_WR) == -1) { pr_perror("shutdown"); return 1; } if (shutdown(fd, SHUT_WR) == -1) { pr_perror("shutdown"); return 1; } ret = clean_sk_buf(fd, 0); if (ret != rcv_buf_size) { fail("the received buffer contains only %d bytes (%d)\n", ret, rcv_buf_size); } rcv_size += ret; if (snd != rcv_size) { fail("The child sent %d bytes, but the parent received %d bytes\n", rcv_buf_size, rcv_size); return 1; } read_safe(ctl_fd, &ret, sizeof(ret)); if (ret != snd_size) { fail("The parent sent %d bytes, but the child received %d bytes\n", snd_size, ret); return 1; } pass(); return 0; }