diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2011-07-04 01:09:58 +0300 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2011-07-16 17:50:44 +0300 |
commit | fef1f399dd6487b1aac8820693f9d65a5ce306b9 (patch) | |
tree | e86d1dcf0922000676f9e13c0306951f142a64e5 /tools/test-server.c | |
parent | d476b7dbca9edcbd1c366fd6d74a039f63f33f5e (diff) | |
download | obexd-fef1f399dd6487b1aac8820693f9d65a5ce306b9.tar.gz |
gobex: Add a skeleton for a test server
Diffstat (limited to 'tools/test-server.c')
-rw-r--r-- | tools/test-server.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/tools/test-server.c b/tools/test-server.c new file mode 100644 index 0000000..1030009 --- /dev/null +++ b/tools/test-server.c @@ -0,0 +1,160 @@ +/* + * + * OBEX library with GLib integration + * + * Copyright (C) 2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <gobex/gobex.h> + +static GObex *obex = NULL; + +static GMainLoop *main_loop = NULL; + +static void sig_term(int sig) +{ + g_print("Terminating due to signal %d\n", sig); + g_main_loop_quit(main_loop); +} + +static GOptionEntry options[] = { + { NULL }, +}; + +static gboolean unix_accept(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + struct sockaddr_un addr; + socklen_t addrlen; + int sk, cli_sk; + GIOChannel *io; + + if (cond & G_IO_NVAL) + return FALSE; + + if (cond & (G_IO_HUP | G_IO_ERR)) { + g_io_channel_shutdown(chan, TRUE, NULL); + 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) { + g_printerr("accept: %s (%d)\n", strerror(errno), errno); + return TRUE; + } + + g_print("Accepted new client connection on unix socket (fd=%d)\n", + cli_sk); + + io = g_io_channel_unix_new(cli_sk); + g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL); + + obex = g_obex_new(io, G_OBEX_TRANSPORT_STREAM, -1, -1); + + return TRUE; +} + +static GIOChannel *unix_listen(int sock_type) +{ + GIOChannel *io; + struct sockaddr_un addr = { + AF_UNIX, "\0/gobex/server" + }; + int sk, err; + + sk = socket(PF_LOCAL, sock_type, 0); + if (sk < 0) { + err = errno; + g_printerr("Can't create unix socket: %s (%d)\n", + strerror(err), err); + return NULL; + } + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + g_printerr("Can't bind unix socket: %s (%d)\n", + strerror(errno), errno); + close(sk); + return NULL; + } + + if (listen(sk, 1) < 0) { + g_printerr("Can't listen on unix socket: %s (%d)\n", + strerror(errno), errno); + close(sk); + return NULL; + } + + io = g_io_channel_unix_new(sk); + g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + unix_accept, NULL); + + g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL); + g_io_channel_set_close_on_unref(io, TRUE); + + g_print("Unix socket created: %d\n", sk); + + return io; +} + +int main(int argc, char *argv[]) +{ + GOptionContext *context; + GError *err = NULL; + struct sigaction sa; + GIOChannel *io; + + context = g_option_context_new(NULL); + g_option_context_add_main_entries(context, options, NULL); + + g_option_context_parse(context, &argc, &argv, &err); + if (err != NULL) { + g_printerr("%s\n", err->message); + g_error_free(err); + exit(EXIT_FAILURE); + } + + io = unix_listen(SOCK_STREAM); + if (io == NULL) + exit(EXIT_FAILURE); + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sig_term; + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + + main_loop = g_main_loop_new(NULL, FALSE); + + g_main_loop_run(main_loop); + + g_io_channel_unref(io); + g_option_context_free(context); + g_main_loop_unref(main_loop); + + exit(EXIT_SUCCESS); +} |