blob: a7cc58278d61ae5c3bd28bbdf8914f3e14d65f98 [file] [log] [blame]
/*
* Copyright 2016 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "bs_drm.h"
// Suppresses warnings for our usage of asprintf with one of the parameters.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
void bs_open_enumerate(const char *format, unsigned start, unsigned end,
bs_open_enumerate_func body, void *user)
{
assert(end >= start);
for (unsigned dev_index = start; dev_index < end; dev_index++) {
char *file_path = NULL;
int ret = asprintf(&file_path, format, dev_index);
if (ret == -1)
continue;
assert(file_path);
int fd = open(file_path, O_RDWR);
free(file_path);
if (fd < 0)
continue;
bool end = body(user, fd);
close(fd);
if (end)
return;
}
}
#pragma GCC diagnostic pop
struct bs_open_filtered_user {
bs_open_filter_func filter;
int fd;
};
static bool bs_open_filtered_body(void *user, int fd)
{
struct bs_open_filtered_user *data = (struct bs_open_filtered_user *)user;
if (data->filter(fd)) {
data->fd = dup(fd);
return true;
}
return false;
}
int bs_open_filtered(const char *format, unsigned start, unsigned end, bs_open_filter_func filter)
{
struct bs_open_filtered_user data = { filter, -1 };
bs_open_enumerate(format, start, end, bs_open_filtered_body, &data);
return data.fd;
}
struct bs_open_ranked_user {
bs_open_rank_func rank;
uint32_t rank_index;
int fd;
};
static bool bs_open_ranked_body(void *user, int fd)
{
struct bs_open_ranked_user *data = (struct bs_open_ranked_user *)user;
uint32_t rank_index = data->rank(fd);
if (data->rank_index > rank_index) {
data->rank_index = rank_index;
if (data->fd >= 0)
close(data->fd);
data->fd = dup(fd);
}
return rank_index == 0;
}
int bs_open_ranked(const char *format, unsigned start, unsigned end, bs_open_rank_func rank)
{
struct bs_open_ranked_user data = { rank, UINT32_MAX, -1 };
bs_open_enumerate(format, start, end, bs_open_ranked_body, &data);
return data.fd;
}