예제 #1
0
void
tcp_connect_address(const struct sockaddr *address, size_t address_length,
		    unsigned timeout_ms,
		    const struct tcp_connect_handler *handler, void *ctx,
		    struct tcp_connect **handle_r)
{
	assert(address != NULL);
	assert(address_length > 0);
	assert(handler != NULL);
	assert(handler->success != NULL);
	assert(handler->error != NULL);
	assert(handler->canceled != NULL);
	assert(handler->timeout != NULL || timeout_ms == 0);
	assert(handle_r != NULL);
	assert(*handle_r == NULL);

	int fd = socket_cloexec_nonblock(address->sa_family, SOCK_STREAM, 0);
	if (fd < 0) {
		GError *error =
			g_error_new_literal(g_file_error_quark(), errno,
					    g_strerror(errno));
		handler->error(error, ctx);
		return;
	}

	int ret = connect(fd, address, address_length);
	if (ret >= 0) {
		/* quick connect, no I/O thread */
		handler->success(fd, ctx);
		return;
	}

	if (!is_in_progress_errno(errno)) {
		GError *error =
			g_error_new_literal(g_file_error_quark(), errno,
					    g_strerror(errno));
		close_socket(fd);
		handler->error(error, ctx);
		return;
	}

	/* got EINPROGRESS, use the I/O thread to wait for the
	   operation to finish */

	struct tcp_connect *c = g_new(struct tcp_connect, 1);
	c->handler = handler;
	c->handler_ctx = ctx;
	c->fd = fd;
	c->source = NULL;
	c->timeout_ms = timeout_ms;
	c->timeout_source = NULL;

	*handle_r = c;

	io_thread_call(tcp_connect_init, c);
}
예제 #2
0
GPtrArray *
spl_list(GError **error_r)
{
    const char *parent_path_fs = spl_map(error_r);
    DIR *dir;
    struct dirent *ent;
    GPtrArray *list;
    struct stored_playlist_info *playlist;

    if (parent_path_fs == NULL)
        return NULL;

    dir = opendir(parent_path_fs);
    if (dir == NULL) {
        g_set_error_literal(error_r, g_file_error_quark(), errno,
                            g_strerror(errno));
        return NULL;
    }

    list = g_ptr_array_new();

    while ((ent = readdir(dir)) != NULL) {
        playlist = load_playlist_info(parent_path_fs, ent->d_name);
        if (playlist != NULL)
            g_ptr_array_add(list, playlist);
    }

    closedir(dir);
    return list;
}
예제 #3
0
gboolean chassis_log_backend_file_close(chassis_log_backend_t* backend, GError **error) {
	g_assert(backend);
	
	if (backend->fd < 0) return TRUE;

	if (-1 == close(backend->fd)) {
		g_set_error(error, g_file_error_quark(), g_file_error_from_errno(errno), "%s", g_strerror(errno));
		return FALSE;
	}
	backend->fd = -1;
	return TRUE;
}
예제 #4
0
/* the file backend */
gboolean chassis_log_backend_file_open(chassis_log_backend_t* backend, GError **error) {
	g_assert(backend);
	g_assert(backend->file_path);
	g_assert_cmpint(backend->fd, ==, -1);

	backend->fd = g_open(backend->file_path, O_RDWR | O_CREAT | O_APPEND, 0660);
	if (backend->fd == -1) {
		g_set_error(error, g_file_error_quark(), g_file_error_from_errno(errno), "%s", g_strerror(errno));
		return FALSE;
	}
	return TRUE;
}
예제 #5
0
/**
 * Create a GError for the current errno.
 */
static void
playlist_errno(GError **error_r)
{
    switch (errno) {
    case ENOENT:
        g_set_error_literal(error_r, playlist_quark(),
                            PLAYLIST_RESULT_NO_SUCH_LIST,
                            "No such playlist");
        break;

    default:
        g_set_error_literal(error_r, g_file_error_quark(), errno,
                            g_strerror(errno));
        break;
    }
}
예제 #6
0
static gboolean
tcp_connect_event(G_GNUC_UNUSED GIOChannel *source,
		  G_GNUC_UNUSED GIOCondition condition,
		  gpointer data)
{
	struct tcp_connect *c = data;

	assert(c->source != NULL);
	assert(c->timeout_source != NULL);

	/* clear the socket source */
	g_source_unref(c->source);
	c->source = NULL;

	/* delete the timeout source */
	g_source_destroy(c->timeout_source);
	g_source_unref(c->timeout_source);
	c->timeout_source = NULL;

	/* obtain the connect result */
	int s_err = 0;
	socklen_t s_err_size = sizeof(s_err);
	if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR,
		       (char*)&s_err, &s_err_size) < 0)
		s_err = errno;

	if (s_err == 0) {
		/* connection established successfully */

		c->handler->success(c->fd, c->handler_ctx);
	} else {
		/* there was an I/O error; close the socket and pass
		   the error to the handler */

		close_socket(c->fd);

		GError *error =
			g_error_new_literal(g_file_error_quark(), s_err,
					    g_strerror(s_err));
		c->handler->error(error, c->handler_ctx);
	}

	return false;
}
예제 #7
0
파일: context.c 프로젝트: ukleinek/rauc
static void r_context_configure(void)
{
	gboolean res = TRUE;
	GError *error = NULL;

	g_assert_nonnull(context);
	g_assert_false(context->busy);

	g_clear_pointer(&context->config, free_config);
	res = load_config(context->configpath, &context->config, &error);
	if (!res && error->domain==g_file_error_quark()) {
		g_debug("system config not found, using default values");
		g_clear_error(&error);
		res = default_config(&context->config);
	}
	if (!res) {
		g_error("failed to initialize context: %s", error->message);
		g_clear_error(&error);
	}

	if (context->config->system_variant_type == R_CONFIG_SYS_VARIANT_DTB) {
		gchar *compatible = get_system_dtb_compatible(&error);
		if (!compatible) {
			g_warning("Failed to read dtb compatible: %s", error->message);
			g_clear_error(&error);
		}
		g_free(context->config->system_variant);
		context->config->system_variant = compatible;
	} else if (context->config->system_variant_type == R_CONFIG_SYS_VARIANT_FILE) {
		gchar *variant = get_variant_from_file(context->config->system_variant, &error);
		if (!variant) {
			g_warning("Failed to read system variant from file: %s", error->message);
			g_clear_error(&error);
		}
		g_free(context->config->system_variant);
		context->config->system_variant = variant;
	}

	if (context->config->systeminfo_handler &&
	    g_file_test(context->config->systeminfo_handler, G_FILE_TEST_EXISTS)) {

		GError *ierror = NULL;
		g_autoptr(GHashTable) vars = NULL;
		GHashTableIter iter;
		gchar *key = NULL;
		gchar *value = NULL;

		vars = g_hash_table_new(g_str_hash, g_str_equal);

		g_message("Getting Systeminfo: %s", context->config->systeminfo_handler);
		res = launch_and_wait_variables_handler(context->config->systeminfo_handler, vars, &ierror);
		if (!res) {
			g_error("Failed to read system-info variables: %s", ierror->message);
			g_clear_error(&ierror);
		}

		g_hash_table_iter_init(&iter, vars);
		while (g_hash_table_iter_next(&iter, (gpointer*) &key, (gpointer*) &value)) {
			if (g_strcmp0(key, "RAUC_SYSTEM_SERIAL") == 0)
				r_context_conf()->system_serial = g_strdup(value);
		}
	}

	if (context->bootslot == NULL) {
		context->bootslot = g_strdup(get_cmdline_bootname());
	}

	if (context->mountprefix) {
		g_free(context->config->mount_prefix);
		context->config->mount_prefix = g_strdup(context->mountprefix);
	}

	if (context->keyringpath) {
		context->config->keyring_path = context->keyringpath;
	}

	context->pending = FALSE;
}