diff options
author | koral <koral@mailoo.org> | 2011-02-10 14:57:01 +0100 |
---|---|---|
committer | koral <koral@mailoo.org> | 2011-02-10 14:57:01 +0100 |
commit | ece7f8a0bc6f4b45e931ce2634f79fe6c84a18c9 (patch) | |
tree | e820930903e5da1cab71ef1129ccbb6db80a8eaf /src/uzbl-core.c | |
parent | aa565b52f9f82b6c137b2af2178d7ffb9297f310 (diff) |
Moves I/O functions to a dedicated source file.
Diffstat (limited to 'src/uzbl-core.c')
-rw-r--r-- | src/uzbl-core.c | 333 |
1 files changed, 1 insertions, 332 deletions
diff --git a/src/uzbl-core.c b/src/uzbl-core.c index b83e13f..8cc20bb 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -36,6 +36,7 @@ #include "config.h" #include "util.h" #include "menu.h" +#include "io.h" UzblCore uzbl; @@ -1316,338 +1317,6 @@ parse_cmd_line(const char* ctl_line, GString* result) { g_free(ctlstrip); } -/*@null@*/ gchar* -build_stream_name(int type, const gchar* dir) { - State *s = &uzbl.state; - gchar *str = NULL; - - if (type == FIFO) { - str = g_strdup_printf - ("%s/uzbl_fifo_%s", dir, s->instance_name); - } else if (type == SOCKET) { - str = g_strdup_printf - ("%s/uzbl_socket_%s", dir, s->instance_name); - } - return str; -} - -gboolean -control_fifo(GIOChannel *gio, GIOCondition condition) { - if (uzbl.state.verbose) - printf("triggered\n"); - gchar *ctl_line; - GIOStatus ret; - GError *err = NULL; - - if (condition & G_IO_HUP) - g_error ("Fifo: Read end of pipe died!\n"); - - if(!gio) - g_error ("Fifo: GIOChannel broke\n"); - - ret = g_io_channel_read_line(gio, &ctl_line, NULL, NULL, &err); - if (ret == G_IO_STATUS_ERROR) { - g_error ("Fifo: Error reading: %s\n", err->message); - g_error_free (err); - } - - parse_cmd_line(ctl_line, NULL); - g_free(ctl_line); - - return TRUE; -} - -gboolean -attach_fifo(gchar *path) { - GError *error = NULL; - /* we don't really need to write to the file, but if we open the - * file as 'r' we will block here, waiting for a writer to open - * the file. */ - GIOChannel *chan = g_io_channel_new_file(path, "r+", &error); - if (chan) { - if (g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_fifo, NULL)) { - if (uzbl.state.verbose) - printf ("attach_fifo: created successfully as %s\n", path); - send_event(FIFO_SET, path, NULL); - uzbl.comm.fifo_path = path; - g_setenv("UZBL_FIFO", uzbl.comm.fifo_path, TRUE); - return TRUE; - } else g_warning ("attach_fifo: could not add watch on %s\n", path); - } else g_warning ("attach_fifo: can't open: %s\n", error->message); - - if (error) g_error_free (error); - return FALSE; -} - -/*@null@*/ gchar* -init_fifo(gchar *dir) { /* return dir or, on error, free dir and return NULL */ - if (uzbl.comm.fifo_path) { /* get rid of the old fifo if one exists */ - if (unlink(uzbl.comm.fifo_path) == -1) - g_warning ("Fifo: Can't unlink old fifo at %s\n", uzbl.comm.fifo_path); - g_free(uzbl.comm.fifo_path); - uzbl.comm.fifo_path = NULL; - } - - gchar *path = build_stream_name(FIFO, dir); - - if (!file_exists(path)) { - if (mkfifo (path, 0666) == 0 && attach_fifo(path)) { - return dir; - } else g_warning ("init_fifo: can't create %s: %s\n", path, strerror(errno)); - } else { - /* the fifo exists. but is anybody home? */ - int fd = open(path, O_WRONLY|O_NONBLOCK); - if(fd < 0) { - /* some error occurred, presumably nobody's on the read end. - * we can attach ourselves to it. */ - if(attach_fifo(path)) - return dir; - else - g_warning("init_fifo: can't attach to %s: %s\n", path, strerror(errno)); - } else { - /* somebody's there, we can't use that fifo. */ - close(fd); - /* whatever, this instance can live without a fifo. */ - g_warning ("init_fifo: can't create %s: file exists and is occupied\n", path); - } - } - - /* if we got this far, there was an error; cleanup */ - g_free(dir); - g_free(path); - return NULL; -} - -gboolean -control_stdin(GIOChannel *gio, GIOCondition condition) { - (void) condition; - gchar *ctl_line = NULL; - GIOStatus ret; - - ret = g_io_channel_read_line(gio, &ctl_line, NULL, NULL, NULL); - if ( (ret == G_IO_STATUS_ERROR) || (ret == G_IO_STATUS_EOF) ) - return FALSE; - - parse_cmd_line(ctl_line, NULL); - g_free(ctl_line); - - return TRUE; -} - -void -create_stdin () { - GIOChannel *chan = NULL; - GError *error = NULL; - - chan = g_io_channel_unix_new(fileno(stdin)); - if (chan) { - if (!g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_stdin, NULL)) { - g_error ("Stdin: could not add watch\n"); - } else { - if (uzbl.state.verbose) - printf ("Stdin: watch added successfully\n"); - } - } else { - g_error ("Stdin: Error while opening: %s\n", error->message); - } - if (error) g_error_free (error); -} - -gboolean -remove_socket_from_array(GIOChannel *chan) { - gboolean ret = 0; - - ret = g_ptr_array_remove_fast(uzbl.comm.connect_chan, chan); - if(!ret) - ret = g_ptr_array_remove_fast(uzbl.comm.client_chan, chan); - - if(ret) - g_io_channel_unref (chan); - return ret; -} - -gboolean -control_socket(GIOChannel *chan) { - struct sockaddr_un remote; - unsigned int t = sizeof(remote); - GIOChannel *iochan; - int clientsock; - - clientsock = accept (g_io_channel_unix_get_fd(chan), - (struct sockaddr *) &remote, &t); - - if(!uzbl.comm.client_chan) - uzbl.comm.client_chan = g_ptr_array_new(); - - if ((iochan = g_io_channel_unix_new(clientsock))) { - g_io_channel_set_encoding(iochan, NULL, NULL); - g_io_add_watch(iochan, G_IO_IN|G_IO_HUP, - (GIOFunc) control_client_socket, iochan); - g_ptr_array_add(uzbl.comm.client_chan, (gpointer)iochan); - } - return TRUE; -} - -void -init_connect_socket() { - int sockfd, replay = 0; - struct sockaddr_un local; - GIOChannel *chan; - gchar **name = NULL; - - if(!uzbl.comm.connect_chan) - uzbl.comm.connect_chan = g_ptr_array_new(); - - name = uzbl.state.connect_socket_names; - - while(name && *name) { - sockfd = socket (AF_UNIX, SOCK_STREAM, 0); - local.sun_family = AF_UNIX; - strcpy (local.sun_path, *name); - - if(!connect(sockfd, (struct sockaddr *) &local, sizeof(local))) { - if ((chan = g_io_channel_unix_new(sockfd))) { - g_io_channel_set_encoding(chan, NULL, NULL); - g_io_add_watch(chan, G_IO_IN|G_IO_HUP, - (GIOFunc) control_client_socket, chan); - g_ptr_array_add(uzbl.comm.connect_chan, (gpointer)chan); - replay++; - } - } - else - g_warning("Error connecting to socket: %s\n", *name); - name++; - } - - /* replay buffered events */ - if(replay) - send_event_socket(NULL); -} - -gboolean -control_client_socket(GIOChannel *clientchan) { - char *ctl_line; - GString *result = g_string_new(""); - GError *error = NULL; - GIOStatus ret; - gsize len; - - ret = g_io_channel_read_line(clientchan, &ctl_line, &len, NULL, &error); - if (ret == G_IO_STATUS_ERROR) { - g_warning ("Error reading: %s", error->message); - g_clear_error (&error); - ret = g_io_channel_shutdown (clientchan, TRUE, &error); - remove_socket_from_array (clientchan); - if (ret == G_IO_STATUS_ERROR) { - g_warning ("Error closing: %s", error->message); - g_clear_error (&error); - } - return FALSE; - } else if (ret == G_IO_STATUS_EOF) { - /* shutdown and remove channel watch from main loop */ - ret = g_io_channel_shutdown (clientchan, TRUE, &error); - remove_socket_from_array (clientchan); - if (ret == G_IO_STATUS_ERROR) { - g_warning ("Error closing: %s", error->message); - g_clear_error (&error); - } - return FALSE; - } - - if (ctl_line) { - parse_cmd_line (ctl_line, result); - g_string_append_c(result, '\n'); - ret = g_io_channel_write_chars (clientchan, result->str, result->len, - &len, &error); - if (ret == G_IO_STATUS_ERROR) { - g_warning ("Error writing: %s", error->message); - g_clear_error (&error); - } - if (g_io_channel_flush(clientchan, &error) == G_IO_STATUS_ERROR) { - g_warning ("Error flushing: %s", error->message); - g_clear_error (&error); - } - } - - g_string_free(result, TRUE); - g_free(ctl_line); - return TRUE; -} - - -gboolean -attach_socket(gchar *path, struct sockaddr_un *local) { - GIOChannel *chan = NULL; - int sock = socket (AF_UNIX, SOCK_STREAM, 0); - - if (bind (sock, (struct sockaddr *) local, sizeof(*local)) != -1) { - if (uzbl.state.verbose) - printf ("init_socket: opened in %s\n", path); - - if(listen (sock, 5) < 0) - g_warning ("attach_socket: could not listen on %s: %s\n", path, strerror(errno)); - - if( (chan = g_io_channel_unix_new(sock)) ) { - g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_socket, chan); - uzbl.comm.socket_path = path; - send_event(SOCKET_SET, path, NULL); - g_setenv("UZBL_SOCKET", uzbl.comm.socket_path, TRUE); - return TRUE; - } - } else g_warning ("attach_socket: could not bind to %s: %s\n", path, strerror(errno)); - - return FALSE; -} - - -/*@null@*/ gchar* -init_socket(gchar *dir) { /* return dir or, on error, free dir and return NULL */ - if (uzbl.comm.socket_path) { /* remove an existing socket should one exist */ - if (unlink(uzbl.comm.socket_path) == -1) - g_warning ("init_socket: couldn't unlink socket at %s\n", uzbl.comm.socket_path); - g_free(uzbl.comm.socket_path); - uzbl.comm.socket_path = NULL; - } - - if (*dir == ' ') { - g_free(dir); - return NULL; - } - - struct sockaddr_un local; - gchar *path = build_stream_name(SOCKET, dir); - - local.sun_family = AF_UNIX; - strcpy (local.sun_path, path); - - if(!file_exists(path) && attach_socket(path, &local)) { - /* it's free for the taking. */ - return dir; - } else { - /* see if anybody's listening on the socket path we want. */ - int sock = socket (AF_UNIX, SOCK_STREAM, 0); - if(connect(sock, (struct sockaddr *) &local, sizeof(local)) < 0) { - /* some error occurred, presumably nobody's listening. - * we can attach ourselves to it. */ - unlink(path); - if(attach_socket(path, &local)) - return dir; - else - g_warning("init_socket: can't attach to existing socket %s: %s\n", path, strerror(errno)); - } else { - /* somebody's there, we can't use that socket path. */ - close(sock); - /* whatever, this instance can live without a socket. */ - g_warning ("init_socket: can't create %s: socket exists and is occupied\n", path); - } - } - - /* if we got this far, there was an error; cleanup */ - g_free(path); - g_free(dir); - return NULL; -} - void update_title(void) { |