static void start_request_input (CockpitRequest *request) { GPollableInputStream *poll_in; GInputStream *in; /* Both GSocketConnection and GTlsServerConnection are pollable */ in = g_io_stream_get_input_stream (request->io); poll_in = NULL; if (G_IS_POLLABLE_INPUT_STREAM (in)) poll_in = (GPollableInputStream *)in; if (!poll_in || !g_pollable_input_stream_can_poll (poll_in)) { g_critical ("cannot use a non-pollable input stream: %s", G_OBJECT_TYPE_NAME (in)); cockpit_request_finish (request); return; } /* Replace with a new source */ if (request->source) { g_source_destroy (request->source); g_source_unref (request->source); } request->source = g_pollable_input_stream_create_source (poll_in, NULL); g_source_set_callback (request->source, (GSourceFunc)on_request_input, request, NULL); g_source_attach (request->source, request->web_server->main_context); }
static void initialize_io (CockpitStream *self) { GInputStream *is; GOutputStream *os; g_return_if_fail (self->priv->in_source == NULL); is = g_io_stream_get_input_stream (self->priv->io); os = g_io_stream_get_output_stream (self->priv->io); if (!G_IS_POLLABLE_INPUT_STREAM (is) || !g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (is)) || !G_IS_POLLABLE_OUTPUT_STREAM (os) || !g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (os))) { g_warning ("%s: stream is not pollable", self->priv->name); close_immediately (self, "internal-error"); return; } if (self->priv->connecting) { g_object_unref (self->priv->connecting); self->priv->connecting = NULL; } self->priv->in_source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (is), NULL); g_source_set_name (self->priv->in_source, "stream-input"); g_source_set_callback (self->priv->in_source, (GSourceFunc)dispatch_input, self, NULL); g_source_attach (self->priv->in_source, self->priv->context); start_output (self); }
static gboolean sysroot_setup_stdout_redirect (RpmostreedSysroot *self, GError **error) { g_autoptr(GInputStream) stream = NULL; g_autoptr(GSource) source = NULL; StdoutClosure *closure; gint pipefd[2]; gboolean ret = FALSE; /* XXX libostree logs messages to systemd's journal and also to stdout. * Redirect our own stdout back to ourselves so we can capture those * messages and pass them on to clients. Admittedly hokey but avoids * hacking libostree directly (for now). */ closure = g_slice_new0 (StdoutClosure); g_weak_ref_set (&closure->sysroot, self); /* Save the real stdout before overwriting its file descriptor. */ closure->real_stdout = g_unix_output_stream_new (dup (STDOUT_FILENO), FALSE); if (pipe (pipefd) < 0) { glnx_set_prefix_error_from_errno (error, "%s", "pipe() failed"); goto out; } if (dup2 (pipefd[1], STDOUT_FILENO) < 0) { glnx_set_prefix_error_from_errno (error, "%s", "dup2() failed"); goto out; } stream = g_memory_input_stream_new (); closure->data_stream = g_data_input_stream_new (stream); g_clear_object (&stream); stream = g_unix_input_stream_new (pipefd[0], FALSE); source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (stream), NULL); /* Transfer ownership of the StdoutClosure. */ g_source_set_callback (source, (GSourceFunc) sysroot_stdout_ready_cb, closure, (GDestroyNotify) stdout_closure_free); closure = NULL; self->stdout_source_id = g_source_attach (source, NULL); ret = TRUE; out: if (closure != NULL) stdout_closure_free (closure); return ret; }
static gboolean schedule_wakeups_with_timerfd (GoaAlarm *self) { #ifdef HAVE_TIMERFD struct itimerspec timer_spec; int fd; int result; GSource *source; static gboolean seen_before = FALSE; if (!seen_before) { g_debug ("GoaAlarm: trying to use kernel timer"); seen_before = TRUE; } fd = timerfd_create (CLOCK_REALTIME, TFD_CLOEXEC | TFD_NONBLOCK); if (fd < 0) { g_debug ("GoaAlarm: could not create timer fd: %m"); return FALSE; } memset (&timer_spec, 0, sizeof (timer_spec)); timer_spec.it_value.tv_sec = g_date_time_to_unix (self->priv->time) + 1; result = timerfd_settime (fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &timer_spec, NULL); if (result < 0) { g_debug ("GoaAlarm: could not set timer: %m"); return FALSE; } self->priv->type = GOA_ALARM_TYPE_TIMER; self->priv->stream = g_unix_input_stream_new (fd, TRUE); source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (self->priv->stream), NULL); self->priv->scheduled_wakeup_source = source; g_source_set_callback (self->priv->scheduled_wakeup_source, (GSourceFunc) on_timer_source_ready, self, (GDestroyNotify) clear_wakeup_source_pointer); g_source_attach (self->priv->scheduled_wakeup_source, self->priv->context); g_source_unref (source); return TRUE; #endif /*HAVE_TIMERFD */ return FALSE; }
static void let_me_quit (GMainLoop *loop) { GInputStream *g_stdin = g_unix_input_stream_new (0, FALSE); GSource *source = g_pollable_input_stream_create_source ( G_POLLABLE_INPUT_STREAM (g_stdin), NULL); g_source_set_callback (source, (GSourceFunc) stdin_func, loop, NULL); g_source_attach (source, NULL); g_printf ("Hit Enter to stop logging. (Do not hit Control-C.)\n"); }
static void tls_source_sync (GTlsConnectionBaseSource *tls_source) { GTlsConnectionBase *tls = tls_source->tls; gboolean io_waiting, op_waiting; /* Was the source destroyed earlier in this main context iteration? */ if (g_source_is_destroyed ((GSource *) tls_source)) return; g_mutex_lock (&tls->op_mutex); if (((tls_source->condition & G_IO_IN) && tls->reading) || ((tls_source->condition & G_IO_OUT) && tls->writing) || (tls->handshaking && !tls->need_finish_handshake)) op_waiting = TRUE; else op_waiting = FALSE; if (!op_waiting && !tls->need_handshake && !tls->need_finish_handshake) io_waiting = TRUE; else io_waiting = FALSE; g_mutex_unlock (&tls->op_mutex); if (op_waiting == tls_source->op_waiting && io_waiting == tls_source->io_waiting) return; tls_source->op_waiting = op_waiting; tls_source->io_waiting = io_waiting; if (tls_source->child_source) { g_source_remove_child_source ((GSource *)tls_source, tls_source->child_source); g_source_unref (tls_source->child_source); } if (op_waiting) tls_source->child_source = g_cancellable_source_new (tls->waiting_for_op); else if (io_waiting && G_IS_POLLABLE_INPUT_STREAM (tls_source->stream)) tls_source->child_source = g_pollable_input_stream_create_source (tls->base_istream, NULL); else if (io_waiting && G_IS_POLLABLE_OUTPUT_STREAM (tls_source->stream)) tls_source->child_source = g_pollable_output_stream_create_source (tls->base_ostream, NULL); else tls_source->child_source = g_timeout_source_new (0); g_source_set_dummy_callback (tls_source->child_source); g_source_add_child_source ((GSource *)tls_source, tls_source->child_source); }
GSource * soup_message_io_get_source (SoupMessage *msg, GCancellable *cancellable, SoupMessageSourceFunc callback, gpointer user_data) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; GSource *base_source, *source; SoupMessageSource *message_source; if (!io) { base_source = g_timeout_source_new (0); } else if (io->paused) { base_source = NULL; } else if (io->async_close_wait) { base_source = g_cancellable_source_new (io->async_close_wait); } else if (SOUP_MESSAGE_IO_STATE_POLLABLE (io->read_state)) { GPollableInputStream *istream; if (io->body_istream) istream = G_POLLABLE_INPUT_STREAM (io->body_istream); else istream = G_POLLABLE_INPUT_STREAM (io->istream); base_source = g_pollable_input_stream_create_source (istream, cancellable); } else if (SOUP_MESSAGE_IO_STATE_POLLABLE (io->write_state)) { GPollableOutputStream *ostream; if (io->body_ostream) ostream = G_POLLABLE_OUTPUT_STREAM (io->body_ostream); else ostream = G_POLLABLE_OUTPUT_STREAM (io->ostream); base_source = g_pollable_output_stream_create_source (ostream, cancellable); } else base_source = g_timeout_source_new (0); source = g_source_new (&message_source_funcs, sizeof (SoupMessageSource)); g_source_set_name (source, "SoupMessageSource"); message_source = (SoupMessageSource *)source; message_source->msg = g_object_ref (msg); message_source->paused = io && io->paused; if (base_source) { g_source_set_dummy_callback (base_source); g_source_add_child_source (source, base_source); g_source_unref (base_source); } g_source_set_callback (source, (GSourceFunc) callback, user_data, NULL); return source; }
static void initialize_io (CockpitStream *self) { GInputStream *is; GOutputStream *os; g_return_if_fail (self->priv->in_source == NULL); is = g_io_stream_get_input_stream (self->priv->io); os = g_io_stream_get_output_stream (self->priv->io); if (!G_IS_POLLABLE_INPUT_STREAM (is) || !g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (is)) || !G_IS_POLLABLE_OUTPUT_STREAM (os) || !g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (os))) { g_warning ("%s: stream is not pollable", self->priv->name); close_immediately (self, "internal-error"); return; } if (self->priv->connecting) { cockpit_connectable_unref (self->priv->connecting); self->priv->connecting = NULL; } self->priv->in_source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (is), NULL); g_source_set_name (self->priv->in_source, "stream-input"); g_source_set_callback (self->priv->in_source, (GSourceFunc)dispatch_input, self, NULL); g_source_attach (self->priv->in_source, self->priv->context); if (G_IS_TLS_CONNECTION (self->priv->io)) { self->priv->sig_accept_cert = g_signal_connect (G_TLS_CONNECTION (self->priv->io), "accept-certificate", G_CALLBACK (on_rejected_certificate), self); } else { self->priv->sig_accept_cert = 0; } start_output (self); g_signal_emit (self, cockpit_stream_sig_open, 0); }
static gboolean on_new_connection (GSocketService * service, GSocketConnection * connection, GObject * source_object, gpointer user_data) { Client *client = g_slice_new0 (Client); GSocketAddress *addr; GInetAddress *iaddr; gchar *ip; guint16 port; addr = g_socket_connection_get_remote_address (connection, NULL); iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr)); port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)); ip = g_inet_address_to_string (iaddr); client->name = g_strdup_printf ("%s:%u", ip, port); g_free (ip); g_object_unref (addr); g_print ("New connection %s\n", client->name); client->connection = (GSocketConnection *) g_object_ref (connection); client->socket = g_socket_connection_get_socket (connection); client->istream = g_io_stream_get_input_stream (G_IO_STREAM (client->connection)); client->ostream = g_io_stream_get_output_stream (G_IO_STREAM (client->connection)); client->current_message = g_byte_array_sized_new (1024); client->tosource = g_timeout_source_new_seconds (5); g_source_set_callback (client->tosource, (GSourceFunc) on_timeout, client, NULL); g_source_attach (client->tosource, NULL); client->isource = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (client->istream), NULL); g_source_set_callback (client->isource, (GSourceFunc) on_read_bytes, client, NULL); g_source_attach (client->isource, NULL); G_LOCK (clients); clients = g_list_prepend (clients, client); G_UNLOCK (clients); return TRUE; }
GamepadDevice::GamepadDevice(int fd, Nix::Gamepad* gamepad) : m_fileDescriptor(fd) , m_nixGamepad(gamepad) , m_inputStream(0) , m_source(0) { char deviceId[Nix::Gamepad::idLengthCap]; if (ioctl(m_fileDescriptor, JSIOCGNAME(sizeof(deviceId)), deviceId) < 0) return; uint8_t numberOfAxes; uint8_t numberOfButtons; if (ioctl(m_fileDescriptor, JSIOCGAXES, &numberOfAxes) < 0 || ioctl(m_fileDescriptor, JSIOCGBUTTONS, &numberOfButtons) < 0) return; memset(m_nixGamepad->id, 0, Nix::Gamepad::idLengthCap); gsize bytesWritten, bytesRead; GError* error = 0; gchar* deviceIdUTF16 = g_convert(deviceId, -1, "UTF-16", "ASCII", &bytesRead, &bytesWritten, &error); if (!error) { memcpy(m_nixGamepad->id, deviceIdUTF16, bytesWritten); g_free(deviceIdUTF16); } else g_error_free(error); m_nixGamepad->connected = false; m_nixGamepad->timestamp = 0; m_nixGamepad->axesLength = std::min<unsigned>(numberOfAxes, Nix::Gamepad::axesLengthCap); m_nixGamepad->buttonsLength = std::min<unsigned>(numberOfButtons, Nix::Gamepad::buttonsLengthCap); unsigned i, total; for (i = 0, total = m_nixGamepad->axesLength; i < total; i++) m_nixGamepad->axes[i] = 0; for (i = 0, total = m_nixGamepad->buttonsLength; i < total; i++) m_nixGamepad->buttons[i] = 0; m_inputStream = g_unix_input_stream_new(m_fileDescriptor, FALSE); m_source = g_pollable_input_stream_create_source(G_POLLABLE_INPUT_STREAM(m_inputStream), 0); g_source_set_callback(m_source, reinterpret_cast<GSourceFunc>(readCallback), this, 0); g_source_attach(m_source, 0); }
static GSource * soup_content_sniffer_stream_create_source (GPollableInputStream *stream, GCancellable *cancellable) { SoupContentSnifferStream *sniffer = SOUP_CONTENT_SNIFFER_STREAM (stream); GSource *base_source, *pollable_source; if (sniffer->priv->error || (!sniffer->priv->sniffing && sniffer->priv->buffer)) base_source = g_timeout_source_new (0); else base_source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (G_FILTER_INPUT_STREAM (stream)->base_stream), cancellable); g_source_set_dummy_callback (base_source); pollable_source = g_pollable_source_new (G_OBJECT (stream)); g_source_add_child_source (pollable_source, base_source); g_source_unref (base_source); return pollable_source; }
static GSource * soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond, GPollableSourceFunc callback, gpointer user_data, GCancellable *cancellable) { GSource *watch; GMainContext *async_context; if (cond == G_IO_IN) watch = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (priv->istream), cancellable); else watch = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (priv->ostream), cancellable); g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL); if (priv->use_thread_context) async_context = g_main_context_get_thread_default (); else async_context = priv->async_context; g_source_attach (watch, async_context); g_source_unref (watch); return watch; }
static void test_pollable_cancellation (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; GPollableInputStream *pollable_input_stream; GPollableOutputStream *pollable_output_stream; guint8 buf[65536]; GError *error = NULL; GSource *stream_source; GCancellable *cancellable; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Add a stream. */ stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); /* Grab the input and output streams. */ input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_INPUT_STREAM (input_stream)); pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream); output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_OUTPUT_STREAM (output_stream)); pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream); /* Check the non-blocking read() and write() return immediately if called with * a cancelled cancellable. */ cancellable = g_cancellable_new (); g_cancellable_cancel (cancellable); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, sizeof (buf), cancellable, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_clear_error (&error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, sizeof (buf), cancellable, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_clear_error (&error); g_object_unref (cancellable); /* Check the GSources invoke a callback when run with the cancellable * cancelled. */ cancellable = g_cancellable_new (); stream_source = g_pollable_input_stream_create_source (pollable_input_stream, cancellable); check_pollable_source_cancellation (stream_source, cancellable); g_source_unref (stream_source); g_object_unref (cancellable); /* And for the output stream. */ cancellable = g_cancellable_new (); stream_source = g_pollable_output_stream_create_source (pollable_output_stream, cancellable); check_pollable_source_cancellation (stream_source, cancellable); g_object_unref (io_stream); g_source_unref (stream_source); g_object_unref (cancellable); g_object_unref (agent); }
static void test_pollable_properties (NiceAddress *addr) { NiceAgent *agent; guint stream_id; GIOStream *io_stream; GInputStream *input_stream; GOutputStream *output_stream; GPollableInputStream *pollable_input_stream; GPollableOutputStream *pollable_output_stream; guint8 buf[65536]; GError *error = NULL; GSource *stream_source; agent = nice_agent_new_reliable (NULL, NICE_COMPATIBILITY_RFC5245); nice_agent_add_local_address (agent, addr); /* Add a stream. */ stream_id = nice_agent_add_stream (agent, 1); /* Try building an I/O stream around it. */ io_stream = nice_agent_get_io_stream (agent, stream_id, 1); g_assert (G_IS_IO_STREAM (io_stream)); g_assert (NICE_IS_IO_STREAM (io_stream)); /* Check the input stream’s properties. */ input_stream = g_io_stream_get_input_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_INPUT_STREAM (input_stream)); pollable_input_stream = G_POLLABLE_INPUT_STREAM (input_stream); g_assert (g_pollable_input_stream_can_poll (pollable_input_stream)); g_assert (!g_pollable_input_stream_is_readable (pollable_input_stream)); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, sizeof (buf), NULL, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); g_clear_error (&error); stream_source = g_pollable_input_stream_create_source (pollable_input_stream, NULL); g_assert (stream_source != NULL); g_source_unref (stream_source); /* Check the output stream’s properties. */ output_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream)); g_assert (G_IS_POLLABLE_OUTPUT_STREAM (output_stream)); pollable_output_stream = G_POLLABLE_OUTPUT_STREAM (output_stream); g_assert (g_pollable_output_stream_can_poll (pollable_output_stream)); g_assert (!g_pollable_output_stream_is_writable (pollable_output_stream)); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, sizeof (buf), NULL, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK); g_clear_error (&error); stream_source = g_pollable_output_stream_create_source (pollable_output_stream, NULL); g_assert (stream_source != NULL); g_source_unref (stream_source); /* Remove the component and check that the I/O streams close. */ nice_agent_remove_stream (agent, stream_id); g_assert (!g_pollable_input_stream_is_readable (pollable_input_stream)); g_assert (!g_pollable_output_stream_is_writable (pollable_output_stream)); g_assert ( g_pollable_input_stream_read_nonblocking (pollable_input_stream, buf, sizeof (buf), NULL, &error) == 0); g_assert_no_error (error); g_assert ( g_pollable_output_stream_write_nonblocking (pollable_output_stream, buf, sizeof (buf), NULL, &error) == -1); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED); g_clear_error (&error); g_object_unref (io_stream); g_object_unref (agent); }
static void do_console_raw_update_events(GVirSandboxConsoleRaw *console) { GVirSandboxConsoleRawPrivate *priv = console->priv; if (!priv->attached) /* Closed */ return; if (priv->localStdin) { if ((priv->localToConsoleOffset < priv->localToConsoleLength) && (!priv->localEOF)) { if (priv->localStdinSource == NULL) { priv->localStdinSource = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM(priv->localStdin), NULL); g_source_set_callback(priv->localStdinSource, (GSourceFunc)do_console_raw_local_read, console, NULL); g_source_attach(priv->localStdinSource, g_main_context_default()); } } else { if (priv->localStdinSource) { g_source_destroy(priv->localStdinSource); g_source_unref(priv->localStdinSource); priv->localStdinSource = NULL; } } } /* * With raw consoles we can't distinguish stdout/stderr, so everything * goes to stdout */ if (priv->localStdout) { if (priv->consoleToLocalOffset) { if (priv->localStdoutSource == NULL) { priv->localStdoutSource = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM(priv->localStdout), NULL); g_source_set_callback(priv->localStdoutSource, (GSourceFunc)do_console_raw_local_write, console, NULL); g_source_attach(priv->localStdoutSource, g_main_context_default()); } } else { if (priv->localStdoutSource) { g_source_destroy(priv->localStdoutSource); g_source_unref(priv->localStdoutSource); priv->localStdoutSource = NULL; } } } else { if (priv->consoleToLocalOffset) { if (priv->localStderrSource == NULL) { priv->localStderrSource = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM(priv->localStderr), NULL); g_source_set_callback(priv->localStderrSource, (GSourceFunc)do_console_raw_local_write, console, NULL); g_source_attach(priv->localStderrSource, g_main_context_default()); } } else { if (priv->localStderrSource) { g_source_destroy(priv->localStderrSource); g_source_unref(priv->localStderrSource); priv->localStderrSource = NULL; } } } if (priv->console) { GVirStreamIOCondition cond = 0; if (priv->localToConsoleOffset) cond |= GVIR_STREAM_IO_CONDITION_WRITABLE; if (priv->consoleToLocalOffset < priv->consoleToLocalLength) cond |= GVIR_STREAM_IO_CONDITION_READABLE; if (priv->consoleWatch) { g_source_remove(priv->consoleWatch); priv->consoleWatch = 0; } if (cond) { priv->consoleWatch = gvir_stream_add_watch(priv->console, cond, do_console_raw_stream_readwrite, console); } } else { if (priv->consoleToLocalOffset < priv->consoleToLocalLength) { if (priv->consoleInputSource == NULL) { priv->consoleInputSource = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM(priv->consoleInput), NULL); g_source_set_callback(priv->consoleInputSource, (GSourceFunc)do_console_raw_console_read, console, NULL); g_source_attach(priv->consoleInputSource, g_main_context_default()); } } else { if (priv->consoleInputSource) { g_source_destroy(priv->consoleInputSource); g_source_unref(priv->consoleInputSource); priv->consoleInputSource = NULL; } } if (priv->localToConsoleOffset) { if (priv->consoleOutputSource == NULL) { priv->consoleOutputSource = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM(priv->consoleOutput), NULL); g_source_set_callback(priv->consoleOutputSource, (GSourceFunc)do_console_raw_console_write, console, NULL); g_source_attach(priv->consoleOutputSource, g_main_context_default()); } } else { if (priv->consoleOutputSource) { g_source_destroy(priv->consoleOutputSource); g_source_unref(priv->consoleOutputSource); priv->consoleOutputSource = NULL; } } } }