Redid sysfs access to work outside of udev rule context

This commit is contained in:
rexy712 2019-01-15 11:07:15 -08:00
parent 5cfcf558ff
commit e06b405b20

View File

@ -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;
}