gboolean test_check_tcp_works (void) { #ifdef DBUS_UNIX /* In pathological container environments, we might not have a * working 127.0.0.1 */ int res; struct addrinfo *addrs = NULL; struct addrinfo hints; int saved_errno; _DBUS_ZERO (hints); #ifdef AI_ADDRCONFIG hints.ai_flags |= AI_ADDRCONFIG; #endif hints.ai_flags = AI_ADDRCONFIG; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; res = getaddrinfo ("127.0.0.1", "0", &hints, &addrs); saved_errno = errno; if (res != 0) { const gchar *system_message; gchar *skip_message; #ifdef EAI_SYSTEM if (res == EAI_SYSTEM) system_message = g_strerror (saved_errno); else #endif system_message = gai_strerror (res); skip_message = g_strdup_printf ("Name resolution does not work here: " "getaddrinfo(\"127.0.0.1\", \"0\", " "{flags=ADDRCONFIG, family=INET," "socktype=STREAM, protocol=TCP}): " "%s", system_message); g_test_skip (skip_message); free (skip_message); } if (addrs != NULL) freeaddrinfo (addrs); return (res == 0); #else /* Assume that on Windows, TCP always works */ return TRUE; #endif }
/** * Creates a VMCI stream socket connected to the given cid and port. * The connection fd is returned, and is set up as nonblocking. * * This will set FD_CLOEXEC for the socket returned. * * @param path the path to UNIX domain socket * @param abstract #TRUE to use abstract namespace * @param error return location for error code * @returns connection file descriptor or -1 on error */ static int _dbus_connect_vmci (const char *cid_str, const char *port_str, DBusError *error) { int fd; size_t path_len; struct sockaddr_vm addr; unsigned int af_vmci, cid, port; _DBUS_ASSERT_ERROR_IS_CLEAR (error); _dbus_verbose ("connecting to VMCI stream socket %s:%s\n", cid_str, port_str); cid = atoi(cid_str); port = atoi(port_str); if ((af_vmci = VMCISock_GetAFValue()) < 0) { assert(0); } if (_dbus_open_socket(&fd, af_vmci, SOCK_STREAM, 0, error) < 0) { return fd; } _DBUS_ZERO (addr); addr.svm_family = af_vmci; addr.svm_cid = cid; addr.svm_port = port; if (connect (fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) { dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to connect to VMCI (cid, port): %s:%s: %s", cid_str, port_str, _dbus_strerror (errno)); _dbus_close (fd, NULL); fd = -1; return -1; } if (!_dbus_set_fd_nonblocking (fd, error)) { _DBUS_ASSERT_ERROR_IS_SET (error); _dbus_close (fd, NULL); fd = -1; return -1; } return fd; }
static BusDesktopFileLine * new_line (BusDesktopFileParser *parser) { BusDesktopFileSection *section; BusDesktopFileLine *line; section = &parser->desktop_file->sections[parser->current_section]; if (section->n_allocated_lines == section->n_lines) { if (!grow_lines_in_section (section)) return NULL; } line = §ion->lines[section->n_lines++]; _DBUS_ZERO(*line); return line; }
static void* plain_sockets_thread_func (void *data) { GMainContext *context; ClientData cd; int fd; struct sockaddr_un addr; GIOChannel *channel; GSource *gsource; g_printerr ("Starting client thread %p\n", g_thread_self()); fd = socket (PF_UNIX, SOCK_STREAM, 0); if (fd < 0) { g_printerr ("Failed to create socket: %s", strerror (errno)); exit (1); } _DBUS_ZERO (addr); addr.sun_family = AF_UNIX; #ifdef HAVE_ABSTRACT_SOCKETS /* remember that abstract names aren't nul-terminated so we rely * on sun_path being filled in with zeroes above. */ addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ strncpy (&addr.sun_path[1], plain_sockets_address, _DBUS_MAX_SUN_PATH_LENGTH - 2); /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ #else /* HAVE_ABSTRACT_SOCKETS */ strncpy (addr.sun_path, plain_sockets_address, _DBUS_MAX_SUN_PATH_LENGTH - 1); #endif /* ! HAVE_ABSTRACT_SOCKETS */ if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0) { g_printerr ("Failed to connect to socket %s: %s", plain_sockets_address, strerror (errno)); exit (1); } context = g_main_context_new (); cd.iterations = 1; cd.loop = g_main_loop_new (context, FALSE); cd.vtable = data; channel = g_io_channel_unix_new (fd); gsource = g_io_create_watch (channel, G_IO_IN | G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_PRI); g_source_set_callback (gsource, (GSourceFunc)plain_sockets_client_side_watch, &cd, NULL); g_source_attach (gsource, context); g_io_channel_unref (channel); g_printerr ("Client thread writing to prime pingpong\n"); write_junk (fd, echo_call_size, cd.vtable->fake_malloc_overhead); g_printerr ("Client thread done writing primer\n"); g_printerr ("Client thread entering main loop\n"); g_main_loop_run (cd.loop); g_printerr ("Client thread %p exiting main loop\n", g_thread_self()); g_source_destroy (gsource); close (fd); g_main_loop_unref (cd.loop); g_main_context_unref (context); return NULL; }
static void* plain_sockets_init_server (ServerData *sd) { PlainSocketServer *server; struct sockaddr_un addr; static char path[] = "/tmp/dbus-test-profile-XXXXXX"; char *p; GIOChannel *channel; server = g_new0 (PlainSocketServer, 1); server->sd = sd; server->vtable = sd->vtable; /* for convenience */ p = path; while (*p) { if (*p == 'X') *p = 'a' + (int) (26.0*rand()/(RAND_MAX+1.0)); ++p; } g_printerr ("Socket is %s\n", path); server->listen_fd = socket (PF_UNIX, SOCK_STREAM, 0); if (server->listen_fd < 0) { g_printerr ("Failed to create socket: %s", strerror (errno)); exit (1); } _DBUS_ZERO (addr); addr.sun_family = AF_UNIX; #ifdef HAVE_ABSTRACT_SOCKETS /* remember that abstract names aren't nul-terminated so we rely * on sun_path being filled in with zeroes above. */ addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ strncpy (&addr.sun_path[1], path, _DBUS_MAX_SUN_PATH_LENGTH - 2); /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ #else /* HAVE_ABSTRACT_SOCKETS */ { struct stat sb; if (stat (path, &sb) == 0 && S_ISSOCK (sb.st_mode)) unlink (path); } strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1); #endif /* ! HAVE_ABSTRACT_SOCKETS */ if (bind (server->listen_fd, (struct sockaddr*) &addr, sizeof (addr)) < 0) { g_printerr ("Failed to bind socket \"%s\": %s", path, strerror (errno)); exit (1); } if (listen (server->listen_fd, 30 /* backlog */) < 0) { g_printerr ("Failed to listen on socket \"%s\": %s", path, strerror (errno)); exit (1); } plain_sockets_address = path; channel = g_io_channel_unix_new (server->listen_fd); server->source_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_PRI, plain_sockets_new_client_watch, server); g_io_channel_unref (channel); return server; }