static void test_istream_unix_server(int fd) { struct istream *input; const unsigned char *data; size_t size; input = i_stream_create_unix(fd, 1024); /* 1) simple read */ test_server_read_nofd(input, 1); write_one(fd); /* 2) fd was sent but we won't get it */ test_server_read_nofd(input, 2); /* we still shouldn't have the fd */ fd_set_nonblock(fd, TRUE); i_stream_unix_set_read_fd(input); test_assert(i_stream_read_data(input, &data, &size, 0) == 0); test_assert(i_stream_unix_get_read_fd(input) == -1); fd_set_nonblock(fd, FALSE); write_one(fd); /* 3) the previous fd should be lost now */ test_server_read_nofd(input, 3); write_one(fd); /* 4) we should get the fd now */ test_server_read_fd(input, send_fd2, 4); write_one(fd); /* 5) the previous fd shouldn't be returned anymore */ i_stream_unix_set_read_fd(input); test_server_read_nofd(input, 5); write_one(fd); /* 6) with i_stream_unix_unset_read_fd() we shouldn't get fd anymore */ i_stream_unix_unset_read_fd(input); test_server_read_nofd(input, 6); write_one(fd); /* 7-8) two fds were sent, but we'll get only the first one */ i_stream_unix_set_read_fd(input); test_server_read_fd(input, send_fd, 7); test_server_read_nofd(input, 8); write_one(fd); /* 9-10) two fds were sent, and we'll get them both */ i_stream_unix_set_read_fd(input); test_server_read_fd(input, send_fd, 9); i_stream_unix_set_read_fd(input); test_server_read_fd(input, send_fd2, 10); write_one(fd); i_stream_destroy(&input); i_close_fd(&fd); }
void imap_master_client_create(int fd) { struct imap_master_client *client; client = i_new(struct imap_master_client, 1); client->conn.unix_socket = TRUE; connection_init_server(master_clients, &client->conn, "imap-master", fd, fd); /* read the first file descriptor that we can */ i_stream_unix_set_read_fd(client->conn.input); }
void imap_hibernate_client_create(int fd, bool debug) { struct imap_hibernate_client *client; client = i_new(struct imap_hibernate_client, 1); client->debug = debug; connection_init_server(hibernate_clients, &client->conn, "imap-hibernate", fd, fd); i_assert(client->conn.input == NULL); client->conn.input = i_stream_create_unix(fd, (size_t)-1); i_stream_unix_set_read_fd(client->conn.input); }
static int imap_hibernate_client_input_line(struct connection *conn, const char *line) { struct imap_hibernate_client *client = (struct imap_hibernate_client *)conn; int fd = -1, ret; if (!conn->version_received) { if (connection_verify_version(conn, t_strsplit_tabescaped(line)) < 0) return -1; conn->version_received = TRUE; return 1; } if (client->imap_client == NULL) { char *const *args; pool_t pool; fd = i_stream_unix_get_read_fd(conn->input); if (fd == -1) { i_error("IMAP client fd not received"); return -1; } pool = pool_alloconly_create("client cmd", 1024); args = p_strsplit_tabescaped(pool, line); ret = imap_hibernate_client_input_args(conn, (void *)args, fd, pool); if (ret >= 0 && client->debug) i_debug("Create client with input: %s", line); pool_unref(&pool); } else { fd = i_stream_unix_get_read_fd(conn->input); if (fd == -1) { i_error("IMAP notify fd not received (input: %s)", line); ret = -1; } else if (line[0] != '\0') { i_error("Expected empty notify fd line from client, but got: %s", line); o_stream_send_str(conn->output, "Expected empty notify fd line"); ret = -1; } else { imap_client_add_notify_fd(client->imap_client, fd); ret = 1; } } if (ret < 0) { if (client->imap_client != NULL) imap_client_destroy(&client->imap_client, NULL); if (fd != -1) i_close_fd(&fd); return -1; } else if (ret == 0) { /* still need to read another fd */ i_stream_unix_set_read_fd(conn->input); o_stream_send_str(conn->output, "+\n"); return 1; } else { /* finished - always disconnect the hibernate client afterwards */ o_stream_send_str(conn->output, "+\n"); imap_client_create_finish(client->imap_client); return -1; } }