Redid sysfs access to work outside of udev rule context
This commit is contained in:
parent
5cfcf558ff
commit
e06b405b20
156
src/rex-edid.c
156
src/rex-edid.c
@ -22,6 +22,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define REX_EDID_VERSION_MAJ 0u
|
||||
#define REX_EDID_VERSION_MIN 2u
|
||||
@ -189,102 +190,103 @@ int rex_edid_xrandr(void){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*get device name from DEVPATH environment variable and prepend '/sys' to it*/
|
||||
char* get_device_path(int* len){
|
||||
char* devpath;
|
||||
int length;
|
||||
char* tmp;
|
||||
|
||||
/*udev stores the device location in sysfs in DEVPATH environment variable*/
|
||||
devpath = getenv("DEVPATH");
|
||||
if(!devpath)
|
||||
return NULL;
|
||||
length = strlen(devpath) + 5;
|
||||
tmp = malloc(length);
|
||||
if(!tmp)
|
||||
return NULL;
|
||||
tmp[length-1] = 0;
|
||||
|
||||
snprintf(tmp, length, "/sys%s", devpath);
|
||||
if(len)
|
||||
*len = length-1;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*extract device name from the device path (the last part of the pathname)*/
|
||||
char* get_device_name(char* devpath, int strlength){
|
||||
int i;
|
||||
for(i = strlength-1;i >= 0;--i){
|
||||
if(devpath[i] == '/'){
|
||||
if(i == strlength)
|
||||
return NULL;
|
||||
return &(devpath[i])+1;
|
||||
}
|
||||
char** add_interface(char* str, size_t slen, char** list, size_t cap, size_t len){
|
||||
if(len >= cap){
|
||||
list = realloc(list, cap*2 * sizeof(char*));
|
||||
}
|
||||
return NULL;
|
||||
list[len] = malloc(slen+1);
|
||||
strncpy(list[len], str, slen);
|
||||
list[len][slen] = 0;
|
||||
return list;
|
||||
}
|
||||
void free_int_list(char** list, size_t len){
|
||||
for(size_t i = 0;i < len;++i)
|
||||
free(list[i]);
|
||||
free(list);
|
||||
}
|
||||
|
||||
int rex_edid_sysfs(void){
|
||||
int devpath_len; /*length of device path name*/
|
||||
int devname_len; /*length of device name*/
|
||||
char* devpath; /*name of device path*/
|
||||
char* devname; /*name of the device*/
|
||||
char** dev_int_names = malloc(sizeof(char*)); /*name of device interfaces*/
|
||||
size_t num_names = 0;
|
||||
size_t names_size = 1;
|
||||
DIR* dp; /*pointer to open device directory in sysfs*/
|
||||
struct dirent* dir; /*accessor to sysfs directory*/
|
||||
|
||||
/*set up device names*/
|
||||
devpath = get_device_path(&devpath_len);
|
||||
if(!devpath){
|
||||
fprintf(stderr, "DEVPATH is empty!\n");
|
||||
return -3;
|
||||
}
|
||||
devname = get_device_name(devpath, devpath_len);
|
||||
devname_len = strlen(devname);
|
||||
|
||||
/*open directory*/
|
||||
dp = opendir(devpath);
|
||||
dp = opendir("/sys/class/drm");
|
||||
if(!dp){
|
||||
fprintf(stderr, "Unable to open DEVPATH!\n");
|
||||
fprintf(stderr, "Unable to open device path!\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
/*check all contents of device directory*/
|
||||
while((dir = readdir(dp))){
|
||||
if(!strncmp(dir->d_name, devname, devname_len)){
|
||||
int edid_len; /*length of full path to edid file*/
|
||||
char* edid_file; /*buffer for edid path name*/
|
||||
unsigned char c; /*place to store char from file*/
|
||||
|
||||
/*set up edid file path*/
|
||||
edid_len = strlen(dir->d_name)+1 + devpath_len + 6;
|
||||
edid_file = malloc(edid_len);
|
||||
snprintf(edid_file, edid_len, "%s/%s/edid", devpath, dir->d_name);
|
||||
printf("%s:", dir->d_name + devname_len+1);
|
||||
|
||||
/*read in edid data from file*/
|
||||
FILE* fd = fopen(edid_file, "r");
|
||||
if(!fd){
|
||||
fprintf(stderr, "Unable to open edid file\n");
|
||||
free(edid_file);
|
||||
printf("\n");
|
||||
continue;
|
||||
if(!strncmp(dir->d_name, "card", 4)){
|
||||
size_t l = strlen(dir->d_name);
|
||||
int add = 1;
|
||||
for(size_t i = 4;i < l;++i){
|
||||
if(dir->d_name[i] == '-'){
|
||||
add = 0;
|
||||
}
|
||||
}
|
||||
|
||||
c = fgetc(fd);
|
||||
while(!feof(fd)){
|
||||
printf("%02x", c);
|
||||
c = fgetc(fd);
|
||||
if(add){
|
||||
dev_int_names = add_interface(dir->d_name, l, dev_int_names, names_size, num_names);
|
||||
++num_names;
|
||||
}
|
||||
|
||||
/*cleanup*/
|
||||
fclose(fd);
|
||||
free(edid_file);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
free(devpath);
|
||||
|
||||
chdir("/sys/class/drm");
|
||||
|
||||
for(size_t i = 0;i < num_names;++i){
|
||||
devname = dev_int_names[i];
|
||||
devname_len = strlen(devname);
|
||||
|
||||
/*open directory*/
|
||||
dp = opendir(devname);
|
||||
if(!dp){
|
||||
fprintf(stderr, "Unable to open %s!\n", devname);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*check all contents of device directory*/
|
||||
while((dir = readdir(dp))){
|
||||
if(!strncmp(dir->d_name, devname, devname_len)){
|
||||
int edid_len; /*length of full path to edid file*/
|
||||
char* edid_file; /*buffer for edid path name*/
|
||||
unsigned char c; /*place to store char from file*/
|
||||
|
||||
/*set up edid file path*/
|
||||
edid_len = strlen(dir->d_name)+6;
|
||||
edid_file = malloc(edid_len);
|
||||
snprintf(edid_file, edid_len, "%s/edid", dir->d_name);
|
||||
printf("%s:", dir->d_name + devname_len+1);
|
||||
|
||||
/*read in edid data from file*/
|
||||
FILE* fd = fopen(edid_file, "r");
|
||||
if(!fd){
|
||||
fprintf(stderr, "Unable to open edid file\n");
|
||||
free(edid_file);
|
||||
continue;
|
||||
}
|
||||
|
||||
c = fgetc(fd);
|
||||
while(!feof(fd)){
|
||||
printf("%02x", c);
|
||||
c = fgetc(fd);
|
||||
}
|
||||
|
||||
/*cleanup*/
|
||||
fclose(fd);
|
||||
free(edid_file);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
}
|
||||
free_int_list(dev_int_names, num_names);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user