static void simple_readpipe(SIMPLE_THREAD_REC *rec, GIOChannel *pipe) { RESOLVED_IP_REC iprec; GIOChannel *handle; IPADDR *ip; g_return_if_fail(rec != NULL); g_source_remove(rec->tag); net_gethostbyname_return(pipe, &iprec); g_free_not_null(iprec.errorstr); g_io_channel_close(rec->pipes[0]); g_io_channel_unref(rec->pipes[0]); g_io_channel_close(rec->pipes[1]); g_io_channel_unref(rec->pipes[1]); ip = iprec.ip4.family != 0 ? &iprec.ip4 : &iprec.ip6; handle = iprec.error == -1 ? NULL : net_connect_ip(ip, rec->port, rec->my_ip); g_free_not_null(rec->my_ip); if (handle == NULL) { /* failed */ rec->func(NULL, rec->data); g_free(rec); return; } rec->tag = g_input_add(handle, G_INPUT_READ | G_INPUT_WRITE, (GInputFunction) simple_init, rec); }
/* connection to server failed */ void server_connect_failed(SERVER_REC *server, const char *msg) { g_return_if_fail(IS_SERVER(server)); lookup_servers = g_slist_remove(lookup_servers, server); signal_emit("server connect failed", 2, server, msg); if (server->connect_tag != -1) { g_source_remove(server->connect_tag); server->connect_tag = -1; } if (server->handle != NULL) { net_sendbuffer_destroy(server->handle, TRUE); server->handle = NULL; } if (server->connect_pipe[0] != NULL) { g_io_channel_close(server->connect_pipe[0]); g_io_channel_unref(server->connect_pipe[0]); g_io_channel_close(server->connect_pipe[1]); g_io_channel_unref(server->connect_pipe[1]); server->connect_pipe[0] = NULL; server->connect_pipe[1] = NULL; } server_unref(server); }
static gboolean input_callback (GIOChannel *source, GIOCondition condition, gpointer data) { int val; GIOChannel *dest = (GIOChannel *)data; if (!read_all (source, (char *)&val, sizeof(val))) { fprintf (stderr, "Unexpected EOF\n"); exit (1); } if (val) { write_all (dest, (char *)&val, sizeof(val)); return TRUE; } else { g_io_channel_close (source); g_io_channel_close (dest); n_active_children--; if (n_active_children == 0) g_main_loop_quit (loop); return FALSE; } }
static gboolean incoming_data(GIOChannel *io, GIOCondition cond, gpointer ptr) { int fd = g_io_channel_unix_get_fd(io); UNUSED(cond); UNUSED(ptr); char filename[FILENAME_MAX + 1]; ssize_t len = recvfrom(fd, filename, FILENAME_MAX, 0, NULL, 0); if (len < 0) { if (errno == EAGAIN) return 0; warning("recv failed (%s)\n", strerror(errno)); g_io_channel_close(io); return FALSE; } if (len == 0) { g_io_channel_close(io); return FALSE; } filename[len] = 0; struct playlist_entry *entry = add_file_playlist(main_playlist, filename); if (entry) put_entry(entry); return TRUE; }
/*---------------------------------------------------------------------*/ static void close_io_channels() { if( hop_stdout ) g_io_channel_close( hop_stdout ); if( hop_stderr ) g_io_channel_close( hop_stderr ); close( hop_pipe_stdout[ 0 ] ); close( hop_pipe_stdout[ 1 ] ); close( hop_pipe_stderr[ 0 ] ); close( hop_pipe_stderr[ 1 ] ); }
static gboolean listen_from_server(GIOChannel *io, GIOCondition condition, void *cnt) { gchar buf[512]; gsize nbr; t_message msg; debug("listen_from_server()"); (void) condition; if (g_io_channel_read(io, buf, CLIENT_READ_BUF_SIZE, &nbr) != G_IO_ERROR_NONE) { g_io_channel_close(io); return (-1); } buf[nbr] = '\0'; if (nbr > 0) { extract_msg((char *) buf, &msg); printf("[%s]\n", msg.command); mesg_init(cnt, &msg); insert_mesg_to_list(cnt, EMPTY, "server", trim(buf)); } scrolled_window(cnt, SCROLL_MESG); g_io_add_watch(io, G_IO_IN, listen_from_server, cnt); return (0); }
static void save_log (const char *filename) { GIOChannel *file; GError *err; gssize size; char *history; err = NULL; file = g_io_channel_new_file (filename, "w", &err); if (file == NULL) { print_error (err); return; } print_error (err); g_assert (err == NULL); history = warlock_view_get_text (NULL); (void)g_io_channel_write_chars (file, history, -1, &size, &err); debug ("%" G_GSSIZE_FORMAT " characters written to file\n", size); print_error (err); g_free (history); g_io_channel_close (file); g_io_channel_unref (file); }
/* Disconnect socket */ void net_disconnect(GIOChannel *handle) { g_return_if_fail(handle != NULL); g_io_channel_close(handle); g_io_channel_unref(handle); }
static void rc_line_buf_finalize (GObject *obj) { RCLineBuf *line_buf; line_buf = RC_LINE_BUF (obj); if (line_buf->priv->buf) { g_string_free (line_buf->priv->buf, TRUE); } if (line_buf->priv->cb_id) { g_source_remove (line_buf->priv->cb_id); } if (line_buf->priv->channel) { g_io_channel_close (line_buf->priv->channel); g_io_channel_unref (line_buf->priv->channel); } g_free (line_buf->priv); if (parent_class->finalize) parent_class->finalize (obj); } /* rc_line_buf_finalize */
static void create_child (void) { int pid; GIOChannel *in_channels[2]; GIOChannel *out_channels[2]; GSource *source; io_pipe (in_channels); io_pipe (out_channels); pid = fork (); if (pid > 0) /* Parent */ { g_io_channel_close (in_channels[0]); g_io_channel_close (out_channels[1]); source = g_io_create_watch (out_channels[0], G_IO_IN | G_IO_HUP); g_source_set_closure (source, g_cclosure_new (G_CALLBACK (input_callback), in_channels[1], (GClosureNotify)g_io_channel_unref)); g_source_attach (source, NULL); g_source_unref (source); g_io_channel_unref (in_channels[0]); g_io_channel_unref (out_channels[0]); g_io_channel_unref (out_channels[1]); } else if (pid == 0) /* Child */ { g_io_channel_close (in_channels[1]); g_io_channel_close (out_channels[0]); setsid (); run_child (in_channels[0], out_channels[1]); } else /* Error */ { fprintf (stderr, "Cannot fork: %s\n", g_strerror (errno)); exit (1); } }
static void on_log_button_toggled (GtkWidget *widget, gpointer data) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { gtk_editable_set_editable( GTK_EDITABLE(mb_gui.entry_log), FALSE ); const gchar *log_file_name = gtk_entry_get_text (GTK_ENTRY (mb_gui.entry_log)); GError* my_err = NULL; mb_state.log_channel = g_io_channel_new_file (log_file_name, "w", &my_err); GString* static_name = g_string_sized_new(128); g_string_printf(static_name,"%s%s", log_file_name, "_static"); mb_state.log_channel_static = g_io_channel_new_file (static_name->str, "w", &my_err); g_string_free(static_name, TRUE); } else { gtk_editable_set_editable( GTK_EDITABLE(mb_gui.entry_log), TRUE ); if (mb_state.log_channel) { g_io_channel_close(mb_state.log_channel); g_io_channel_close(mb_state.log_channel_static); mb_state.log_channel = NULL; mb_state.log_channel_static = NULL; } } }
static void close_connection(struct vhci_conn *conn) { syslog(LOG_INFO, "Closing connection %s handle %d", batostr(&conn->dest), conn->handle); g_io_channel_close(conn->chan); g_io_channel_unref(conn->chan); vconn[conn->handle - 1] = NULL; disconn_complete(conn); free(conn); }
static int scan_enable(uint8_t *data) { struct sockaddr_in sa; GIOChannel *sk_io; bdaddr_t ba; int sk, opt; if (!(*data & SCAN_PAGE)) { if (vdev.scan) { g_io_channel_close(vdev.scan); vdev.scan = NULL; } return 0; } if (vdev.scan) return 0; if ((sk = socket(AF_INET, SOCK_STREAM, 0)) < 0) { syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); return 1; } opt = 1; setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); baswap(&ba, &vdev.bdaddr); sa.sin_family = AF_INET; sa.sin_addr.s_addr = *(uint32_t *) &ba; sa.sin_port = *(uint16_t *) &ba.b[4]; if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) { syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); goto failed; } if (listen(sk, 10)) { syslog(LOG_ERR, "Can't listen on socket: %s (%d)", strerror(errno), errno); goto failed; } sk_io = g_io_channel_unix_new(sk); g_io_add_watch(sk_io, G_IO_IN | G_IO_NVAL, io_conn_ind, NULL); vdev.scan = sk_io; return 0; failed: close(sk); return 1; }
static void create_child (void) { int pid, errsv; GIOChannel *in_channels[2]; GIOChannel *out_channels[2]; io_pipe (in_channels); io_pipe (out_channels); pid = fork (); errsv = errno; if (pid > 0) /* Parent */ { g_io_channel_close (in_channels[0]); g_io_channel_unref (in_channels[0]); g_io_channel_close (out_channels[1]); g_io_channel_unref (out_channels[1]); g_io_add_watch (out_channels[0], G_IO_IN | G_IO_HUP, input_callback, in_channels[1]); } else if (pid == 0) /* Child */ { g_io_channel_close (in_channels[1]); g_io_channel_close (out_channels[0]); setsid (); run_child (in_channels[0], out_channels[1]); } else /* Error */ { fprintf (stderr, "Cannot fork: %s\n", g_strerror (errsv)); exit (1); } }
gboolean handle_read( GIOChannel *sock, GIOCondition cond, http_request *h ) { g_debug( "entering handle_read" ); http_request_read( h ); if (! http_request_ok(h)) return TRUE; handle_request(h); g_io_channel_close( h->sock ); g_io_channel_unref( h->sock ); http_request_free( h ); g_debug( "exiting handle_read" ); return FALSE; }
static void simple_init(SIMPLE_THREAD_REC *rec, GIOChannel *handle) { g_return_if_fail(rec != NULL); g_source_remove(rec->tag); if (net_geterror(handle) != 0) { /* failed */ g_io_channel_close(handle); g_io_channel_unref(handle); handle = NULL; } rec->func(handle, rec->data); g_free(rec); }
static gboolean file_read_data (GIOChannel *iochannel, GIOCondition condition, gpointer user_data) { RCDTransfer *t = user_data; RCDTransferProtocolFile *protocol = (RCDTransferProtocolFile *) t->protocol; GIOError err; char buf[BLOCK_SIZE]; gsize bytes; if (!(condition & G_IO_IN)) goto ERROR; err = g_io_channel_read (iochannel, buf, BLOCK_SIZE, &bytes); if (bytes) rcd_transfer_emit_data (t, buf, bytes); if (err == G_IO_ERROR_AGAIN) return TRUE; if (err != G_IO_ERROR_NONE) goto ERROR; if (bytes > 0) { /* More data to read. Whee. */ return TRUE; } else { /* No more bytes to read and no error condition; the file is done */ g_io_channel_close (iochannel); rcd_transfer_emit_done (t); return FALSE; } ERROR: g_source_remove (protocol->watch); rcd_transfer_set_error (t, RCD_TRANSFER_ERROR_IO, NULL); rcd_transfer_emit_done (t); return FALSE; }
static void rfcomm_node_free(struct rfcomm_node *node) { if (node->device) g_free(node->device); if (node->conn) dbus_connection_unref(node->conn); if (node->owner) g_free(node->owner); if (node->svcname) g_free(node->svcname); if (node->io) { g_source_remove(node->io_id); g_io_channel_close(node->io); g_io_channel_unref(node->io); } rfcomm_release(node->id); g_free(node); }
void avrcp_exit(void) { if (!avctp_server) return; g_io_channel_close(avctp_server); g_io_channel_unref(avctp_server); avctp_server = NULL; #ifndef ANDROID remove_record_from_server(ct_record_id); ct_record_id = 0; #endif remove_record_from_server(tg_record_id); tg_record_id = 0; dbus_connection_unref(connection); connection = NULL; }
RemminaFile* remmina_rdp_file_import(const gchar* from_file) { GIOChannel* channel; GError* error = NULL; RemminaFile* remminafile; channel = g_io_channel_new_file(from_file, "r", &error); if (channel == NULL) { g_print("Failed to import %s: %s\n", from_file, error->message); return NULL; } remminafile = remmina_rdp_file_import_channel(channel); g_io_channel_close(channel); return remminafile; }
/* Callback handling data */ static int receive_data(int fd, int revents, void *session_data) { struct sr_datafeed_packet packet; struct sr_datafeed_logic logic; static uint64_t samples_received = 0; unsigned char c[BUFSIZE]; gsize z; /* Avoid compiler warnings. */ (void)fd; (void)revents; do { g_io_channel_read_chars(channels[0], (gchar *)&c, BUFSIZE, &z, NULL); if (z > 0) { packet.type = SR_DF_LOGIC; packet.payload = &logic; packet.timeoffset = samples_received * period_ps; packet.duration = z * period_ps; logic.length = z; logic.unitsize = 1; logic.data = c; sr_session_bus(session_data, &packet); samples_received += z; } } while (z > 0); if (!thread_running && z <= 0) { /* Make sure we don't receive more packets. */ g_io_channel_close(channels[0]); /* Send last packet. */ packet.type = SR_DF_END; sr_session_bus(session_data, &packet); return FALSE; } return TRUE; }
void alleyoop_kill (Alleyoop *grind) { vg_tool_view_disconnect ((VgToolView *) grind->view); if (grind->gio) { g_io_channel_close (grind->gio); g_io_channel_unref (grind->gio); grind->watch_id = 0; grind->gio = NULL; } if (grind->pid != (pid_t) -1) { process_kill (grind->pid); grind->pid = (pid_t) -1; } gtk_widget_set_sensitive (grind->toolbar_run, TRUE); gtk_widget_set_sensitive (grind->toolbar_kill, FALSE); }
static gboolean server_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { struct sockaddr_un addr; socklen_t addrlen; int sk, cli_sk; struct unix_client *client; GIOChannel *io; if (cond & G_IO_NVAL) return FALSE; if (cond & (G_IO_HUP | G_IO_ERR)) { g_io_channel_close(chan); return FALSE; } sk = g_io_channel_unix_get_fd(chan); memset(&addr, 0, sizeof(addr)); addrlen = sizeof(addr); cli_sk = accept(sk, (struct sockaddr *) &addr, &addrlen); if (cli_sk < 0) { error("accept: %s (%d)", strerror(errno), errno); return TRUE; } DBG("Accepted new client connection on unix socket (fd=%d)", cli_sk); set_nonblocking(cli_sk); client = g_new0(struct unix_client, 1); client->sock = cli_sk; clients = g_slist_append(clients, client); io = g_io_channel_unix_new(cli_sk); g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, client_cb, client); g_io_channel_unref(io); return TRUE; }
static void process_destroy(PROCESS_REC *rec, int status) { processes = g_slist_remove(processes, rec); signal_emit("exec remove", 2, rec, GINT_TO_POINTER(status)); if (rec->read_tag != -1) g_source_remove(rec->read_tag); if (rec->target_item != NULL) exec_wi_destroy(rec->target_item); line_split_free(rec->databuf); g_io_channel_close(rec->in); g_io_channel_unref(rec->in); net_sendbuffer_destroy(rec->out, TRUE); g_free_not_null(rec->name); g_free_not_null(rec->target); g_free(rec->args); g_free(rec); }
static gint generate_support_data (const gchar *filename) { GIOChannel *channel; GError *error = NULL; if (g_str_equal (filename, "-")) { channel = g_io_channel_unix_new (0); } else if (!(channel = g_io_channel_new_file (filename, "w", &error))) { g_printerr ("%s\n", error->message); g_error_free (error); return EXIT_FAILURE; } g_io_channel_write_chars (channel, "[system]\n", -1, NULL, NULL); generate_date (channel); generate_system_info (channel); g_io_channel_write_chars (channel, "\n", -1, NULL, NULL); g_io_channel_write_chars (channel, "[perfkit]\n", -1, NULL, NULL); write_kv (channel, "lib.version", PK_VERSION_S); write_kv (channel, "agent.version", PKA_VERSION_S); g_io_channel_write_chars (channel, "\n", -1, NULL, NULL); generate_channels (channel); /* TODO */ if (!g_io_channel_flush (channel, &error)) { g_printerr ("%s\n", error->message); g_error_free (error); return EXIT_FAILURE; } g_io_channel_close (channel); return EXIT_SUCCESS; }
void rc_line_buf_set_fd (RCLineBuf *line_buf, int fd) { if (line_buf->priv->cb_id) { g_source_remove (line_buf->priv->cb_id); } if (line_buf->priv->channel) { g_io_channel_close (line_buf->priv->channel); g_io_channel_unref (line_buf->priv->channel); } if (line_buf->priv->buf) { g_string_truncate (line_buf->priv->buf, 0); } line_buf->priv->channel = g_io_channel_unix_new (fd); line_buf->priv->cb_id = g_io_add_watch (line_buf->priv->channel, G_IO_IN | G_IO_HUP | G_IO_ERR, (GIOFunc) rc_line_buf_cb, (gpointer) line_buf); } /* rc_line_buf_set_fd */
// to be called at program start and anytime the value of auto-log changes static void log_toggle (void) { char *key; gboolean autolog; key = preferences_get_key (PREF_AUTO_LOG); autolog = preferences_get_bool (key); g_free (key); if (autolog && log_file == NULL) { GError *err; char *filename, *name, *path, *path_key; path_key = preferences_get_key (PREF_LOG_PATH); path = preferences_get_string (path_key); g_free (path_key); name = warlock_log_get_name (); filename = g_build_filename (path, name, NULL); g_free (name); g_free (path); err = NULL; log_file = g_io_channel_new_file (filename, "a", &err); if (log_file == NULL) { echo_f ("Error: \"%s\" for file \"%s\".\n", err->message, filename); } } else if (!autolog && log_file != NULL) { g_io_channel_close (log_file); g_io_channel_unref (log_file); log_file = NULL; } }
static void server_connect_callback_readpipe(SERVER_REC *server) { RESOLVED_IP_REC iprec; IPADDR *ip; const char *errormsg; char *servername = NULL; g_source_remove(server->connect_tag); server->connect_tag = -1; net_gethostbyname_return(server->connect_pipe[0], &iprec); g_io_channel_close(server->connect_pipe[0]); g_io_channel_unref(server->connect_pipe[0]); g_io_channel_close(server->connect_pipe[1]); g_io_channel_unref(server->connect_pipe[1]); server->connect_pipe[0] = NULL; server->connect_pipe[1] = NULL; /* figure out if we should use IPv4 or v6 address */ if (iprec.error != 0) { /* error */ ip = NULL; } else if (server->connrec->family == AF_INET) { /* force IPv4 connection */ ip = iprec.ip4.family == 0 ? NULL : &iprec.ip4; servername = iprec.host4; } else if (server->connrec->family == AF_INET6) { /* force IPv6 connection */ ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6; servername = iprec.host6; } else { /* pick the one that was found, or if both do it like /SET resolve_prefer_ipv6 says. */ if (iprec.ip4.family == 0 || (iprec.ip6.family != 0 && settings_get_bool("resolve_prefer_ipv6"))) { ip = &iprec.ip6; servername = iprec.host6; } else { ip = &iprec.ip4; servername = iprec.host4; } } if (ip != NULL) { /* host lookup ok */ if (servername) { g_free(server->connrec->address); server->connrec->address = g_strdup(servername); } server_real_connect(server, ip, NULL); errormsg = NULL; } else { if (iprec.error == 0 || net_hosterror_notfound(iprec.error)) { /* IP wasn't found for the host, don't try to reconnect back to this server */ server->dns_error = TRUE; } if (iprec.error == 0) { /* forced IPv4 or IPv6 address but it wasn't found */ errormsg = server->connrec->family == AF_INET ? "IPv4 address not found for host" : "IPv6 address not found for host"; } else { /* gethostbyname() failed */ errormsg = iprec.errorstr != NULL ? iprec.errorstr : "Host lookup failed"; } server->connection_lost = TRUE; server_connect_failed(server, errormsg); } g_free(iprec.errorstr); g_free(iprec.host4); g_free(iprec.host6); }
/** cgi_handoff - hand off to CGI v1.1 (subset of) * @see http://tools.ietf.org/html/draft-robinson-www-interface-00 * @param url requested * @param client to serve to * @param data - cgiroot * * TODO: * - fix input/output to child. I should be able to dup the socket * such that the child processes stdin is the un-read payload data in * in the socket and its stdout writes to the socket yet I haven't figured * that out yet. In the meantime I'm saving the payload to a file * and providing that to the CGI as PAYLOAD_FILE */ gboolean cgi_handoff(MediaURL *url, GstHTTPClient *client, gpointer data) { const char *cgiroot = (const char*) data; gchar *path; gchar *scriptname; char *physpath; int pid; int outfd[2]; int infd[2]; #ifdef CAPTURE_PAYLOAD int payload_len = 0; #endif scriptname = url->path + strlen(CGI_PATH) + 2; path = g_strconcat(cgiroot, "/", scriptname, NULL); physpath = realpath(path, NULL); if (!physpath) goto err; /* ensure physpath is within cgiroot */ if (strncmp(physpath, cgiroot, strlen(cgiroot)) || ((physpath[strlen(cgiroot)] != 0) && (physpath[strlen(cgiroot)] != '/')) ) { goto err; } /* ensure file is executable */ if (access(physpath, X_OK) < 0) { goto err; } /* capture post data to a file */ #ifdef CAPTURE_PAYLOAD { gsize rz; gsize sz; gchar buf[100]; gchar *str; int len; str = gst_http_client_get_header(client, "Content-Length"); if (str) payload_len = atoi(str); if (payload_len) { len = payload_len; GST_DEBUG("Reading %d byte payload\n", len); GIOChannel *out = g_io_channel_new_file(CAPTURE_PAYLOAD, "w+", NULL); if (!out) { GST_ERROR("failed to open payload file %s: %s (%d)\n", CAPTURE_PAYLOAD, strerror(errno), errno); } else { while (len) { sz = sizeof(buf); if (len < sz) sz = len; g_io_channel_read_chars(client->gio, buf, sz, &rz, NULL); // why does g_io_channel_read_chars work and read block? // rz = read(client->sock, &buf, sz); len -= rz; g_io_channel_write_chars(out, buf, rz, &sz, NULL); } g_io_channel_flush(out, NULL); g_io_channel_close(out); } } } #endif GST_INFO("Executing %s to %s:%d", physpath, client->peer_ip, client->port); pipe(outfd); // where the parent is going to write to pipe(infd); // from where parent is going to read pid = fork(); if (pid < 0) { GST_ERROR("fork failed: %d\n", errno); goto err; } // child if (pid == 0) { char *envp[32]; int envc = 0; #ifdef CAPTURE_PAYLOAD if (payload_len) envp[envc++] = g_strdup_printf("PAYLOAD_FILE=%s", CAPTURE_PAYLOAD); #endif envp[envc++] = g_strdup_printf("REQUEST_URI=%s", url->path); envp[envc++] = g_strdup_printf("DOCUMENT_ROOT=%s", docroot); envp[envc++] = g_strdup_printf("SERVER_PROTOCOL=1.0"); envp[envc++] = g_strdup_printf("SERVER_SOFTWARE=gst-httpd/" VERSION); envp[envc++] = g_strdup_printf("CONTENT_LENGTH=%s", gst_http_client_get_header(client, "Content-Length")); envp[envc++] = g_strdup_printf("CONTENT_TYPE=%s", gst_http_client_get_header(client, "Content-Type")); envp[envc++] = g_strdup_printf("REQUEST_METHOD=%s", url->method); envp[envc++] = g_strdup_printf("SCRIPT_FILENAME=%s", physpath); envp[envc++] = g_strdup_printf("SCRIPT_NAME=%s", scriptname); envp[envc++] = g_strdup_printf("QUERY_STRING=%s", url->query); envp[envc++] = g_strdup_printf("REMOTE_ADDR=%s", client->peer_ip); envp[envc++] = 0; close(STDOUT_FILENO); close(STDIN_FILENO); dup2(outfd[0], STDIN_FILENO); dup2(infd[1], STDOUT_FILENO); // not required for child close(outfd[0]); close(outfd[1]); close(infd[0]); close(infd[1]); // execl(physpath, physpath, NULL); execle(physpath, physpath, NULL, envp); /* should not get here unless error */ exit(0); } // parent else { int sz; char buf[1024]; siginfo_t status; int res; int waiting; GST_INFO("spawned CGI child pid=%d\n", pid); // these are being used by the child close(outfd[0]); close(infd[1]); /* write(outfd[1], "foobar\n", 7); // write to childs stdin char input[100]; input[read(infd[0], input, 100)] = 0; // read for child's stdin */ /* send childs stdout to client socket */ waiting = 1; while (waiting) { if ((sz = read(infd[0], buf, sizeof(buf))) > 0) { write(client->sock, buf, sz); } status.si_pid = 0; res = waitid(P_PID, pid, &status, WEXITED | WSTOPPED | WNOHANG | WNOWAIT); if (status.si_pid == 0) continue; switch (status.si_code) { case CLD_EXITED: // child called exit (normal) case CLD_KILLED: // child killed by signal case CLD_DUMPED: // child killed by signal and dumped core case CLD_STOPPED: // child stopped by signal case CLD_TRAPPED: // child trapped waiting = 0; break; } } GST_DEBUG("cgi returned %d\n", status.si_status); write(client->sock, "", 0); close(outfd[1]); close(infd[0]); // reap the process waitpid(pid, NULL, 0); } free(physpath); g_free(path); return TRUE; err: GST_ERROR("404 Not Found: %s", path); if (physpath) free(physpath); g_free(path); return TRUE; }