added rexledctl program and fixed some bugs

This commit is contained in:
Rexy712 2018-05-09 18:22:56 -07:00
parent 87d70841b0
commit 8686b9fa7a
8 changed files with 103 additions and 78 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
*.o
*.d
rexbacklight
rexledctl
*.swp

42
Makefile Normal file
View File

@ -0,0 +1,42 @@
all: obj/dep rexbacklight rexledctl
rexbacklight: obj/rexbacklight.o obj/common.o obj/cmd.o
gcc -o rexbacklight $^
rexledctl: obj/rexledctl.o obj/common.o obj/cmd.o
gcc -o rexledctl $^
obj/rexledctl.o: src/rexbacklight.c
gcc -c -g -o $@ $< -DREXLEDCTL -I"include" -MMD -MP -MF"obj/dep/rexledctl.d"
obj/%.o: src/%.c
gcc -c -g -o $@ $< -DREXBACKLIGHT -I"include" -MMD -MP -MF"obj/dep/$*.d"
.PHONY: install
install: rexbacklight rexledctl
install -m755 -o root -g root -s rexbacklight /usr/bin/rexbacklight
install -m755 -o root -g root -s rexledctl /usr/bin/rexledctl
install -m600 -o root -g root rules/91-backlight.rules /etc/udev/rules.d/91-backlight.rules
install -m600 -o root -g root rules/91-leds.rules /etc/udev/rules.d/91-leds.rules
install -m755 -o root -g root rules/rexbacklight.init /etc/init.d/rexbacklight
.PHONY: uninstall
uninstall:
rm /usr/bin/rexbacklight
rm /usr/bin/rexledctl
rm /etc/udev/rules.d/91-backlight.rules
rm /etc/udev/rules.d/91-leds.rules
rm /etc/init.d/rexbacklight
obj:
mkdir -p $@
obj/dep:
mkdir -p $@
.PHONY: clean
clean:
rm -rf obj
rm -f rexbacklight
rm -f rexledctl
-include $(wildcard obj/dep/*.d)

1
TODO
View File

@ -4,3 +4,4 @@
xbacklight compat option (-get/-set/-inc/-dec/-help/-time/-steps)
#allow fade in and fade out
a lot of cleanup
rename "backlight" things to "device" things because led/backlight ambiguity

View File

@ -26,6 +26,7 @@
#define RETVAL_UNRECOGNIZED_OPTION 3
#define RETVAL_MISSING_OPTION 4
#define RETVAL_INVALID_DEVICE -5
#define RETVAL_MEM_ERROR 6
#define RETVAL_SUCCESS EXIT_SUCCESS
_Noreturn void usage(int exit_val);

View File

@ -1,69 +0,0 @@
#Copyright 2018 rexy712 of Rexy & Co
#Makefile for project 'rexbacklight'
#Project directory and file setup
SOURCE_DIRS:=src
OBJDIR:=obj
DEPDIR:=obj/dep
INCLUDE_DIRS:=include
EXT:=c
MAIN_EXECUTABLE:=rexbacklight
#Compiler/Linker setup
CC:=gcc
CFLAGS:=-g -std=c11 -Wall -pedantic -Wextra
release: CFLAGS:=-std=c11 -Wall -pedantic -Wextra -O2
LDFLAGS=
LDLIBS:=
STRIP:=strip
#Internal management of sources/objects and additional cflags
INTERNAL_CFLAGS=-c $(foreach dir,$(INCLUDE_DIRS),-I"$(dir)") -MMD -MP -MF"$(DEPDIR)/$*.d"
SOURCES:=$(foreach source,$(SOURCE_DIRS),$(foreach ext,$(EXT),$(wildcard $(source)/*.$(ext))))
OBJECTS:=$(addprefix $(OBJDIR)/,$(subst \,.,$(subst /,.,$(addsuffix .o,$(SOURCES)))))
all: $(MAIN_EXECUTABLE)
$(MAIN_EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $^ -o "$(basename $@)" $(LDLIBS)
.PHONY: release
release: $(OBJECTS)
$(CC) $(LDFLAGS) $^ -o "$(basename $(MAIN_EXECUTABLE))" $(LDLIBS)
$(STRIP) --strip-all "$(MAIN_EXECUTABLE)"
.PHONY: install
install: $(MAIN_EXECUTABLE)
install -m755 -o root -g root -s "$(MAIN_EXECUTABLE)" /usr/bin/rexbacklight
install -m600 -o root -g root rules/91-backlight.rules /etc/udev/rules.d/91-backlight.rules
install -m755 -o root -g root rules/rexbacklight.init /etc/init.d/rexbacklight
.PHONY: uninstall
uninstall:
rm /usr/bin/rexbacklight
rm /etc/udev/rules.d/91-backlight-conf
rm /etc/init.d/rexbacklight.init
define GENERATE_OBJECTS
$$(OBJDIR)/$(subst \,.,$(subst /,.,$(1))).%.o: $(1)/%
$$(CC) $$(CFLAGS) $$(INTERNAL_CFLAGS) "$$<" -o "$$@"
endef
$(foreach dir,$(SOURCE_DIRS),$(eval $(call GENERATE_OBJECTS,$(dir))))
$(OBJECTS): | $(OBJDIR) $(DEPDIR)
$(OBJDIR):
mkdir -p "$@"
$(DEPDIR):
mkdir -p "$@"
.PHONY: clean
clean:
rm -rf "$(DEPDIR)"
rm -rf "$(OBJDIR)"
rm -f "$(MAIN_EXECUTABLE)"
-include $(wildcard $(DEPDIR)/*.d)

4
rules/91-leds.rules Normal file
View File

@ -0,0 +1,4 @@
SUBSYSTEM=="leds", ACTION="add", \
RUN+="/bin/chgrp video %S%p/brightness", \
RUN+="/bin/chmod g+w %S%p/brightness"

View File

@ -21,8 +21,11 @@
#include <stdio.h>
//name of the program being run so that we print the correct name in the usage
extern const char* executable_name;
_Noreturn void usage(int exit_val){
printf("Usage: rexbacklight [argument] [options] [argument]\n\n");
printf("Usage: %s [argument] [options] [argument]\n\n", executable_name);
printf("Options:\n");
for(int i = 0;i < rexbacklight_args_length;i++){
@ -38,7 +41,7 @@ _Noreturn void usage(int exit_val){
printf(" max\n");
printf(" min\n");
printf("\nrexbacklight Copyright (C) 2018 rexy712\n");
printf("\n%s Copyright (C) 2018 rexy712\n", executable_name);
printf("This program comes with ABSOLUTELY NO WARRANTY.\n");
printf("This is free software, and you are welcome to redistribute it\n");
printf("under certain conditions; see the GNU GPLv3 for details.\n");

View File

@ -29,11 +29,23 @@
#include "common.h"
#include "cmd.h"
//name of the program being run so that we print the correct name in the usage
//This is where backlight devices can be found in sysfs
#ifdef REXBACKLIGHT
static const char* backlight_dir = "/sys/class/backlight/";
const char* executable_name = "rexbacklight";
#elif defined(REXLEDCTL)
static const char* backlight_dir = "/sys/class/leds";
const char* executable_name = "rexledctl";
#else
#error "UNDEFINED PROGRAM NAME!"
#endif
static const char* backlight_file = "brightness";
static const char* max_backlight_file = "max_brightness";
static int return_value = RETVAL_SUCCESS;
//Used to store a dynamic array of dynamic strings and number of strings
struct string_array{
char** list;
@ -46,11 +58,14 @@ struct string_array{
#define IO_ERROR_READ "read"
#define IO_ERROR_WRITE "write to"
void io_error(const char* type, const char* error, const char* name){
void io_error(const char* error, const char* type, const char* name){
fprintf(stderr, "Unable to %s %s '%s'!\n", error, type, name);
}
void io_error_2(const char* type, const char* error, const char* name, const char* name2){
fprintf(stderr, "Unable to %s %s '%s%s'!\n", error, type, name, name2);
void io_error_2(const char* error, const char* type, const char* name, const char* name2){
fprintf(stderr, "Unable to %s %s '%s/%s'!\n", error, type, name, name2);
}
void mem_error(void){
fprintf(stderr, "Failed to allocate memory! Unable to continue!\n");
}
//Clean up a string array
@ -70,6 +85,7 @@ struct string_array get_backlight_sources(void){
//If the dir can't be opened, return no backlight devices
if(!fd){
io_error(IO_ERROR_OPEN, IO_ERROR_DIR, backlight_dir);
return_value = RETVAL_INVALID_DIR;
return (struct string_array){.list = NULL, .size = 0};
}
@ -84,7 +100,7 @@ struct string_array get_backlight_sources(void){
}
//Resize list if more than 8 backlight devices exist (not likely)
if(i > list_size){
if(i >= list_size){
char** tmp = malloc(sizeof(const char*) * (list_size += 8));
for(int j = 0;j < i;j++){
tmp[j] = list[j];
@ -93,8 +109,10 @@ struct string_array get_backlight_sources(void){
list = tmp;
}
list[i] = malloc(strlen(dir->d_name) + 1);
int slen = strlen(dir->d_name);
list[i] = malloc(slen + 1);
strcpy(list[i], dir->d_name);
list[i][slen] = 0;
i++;
}
@ -110,10 +128,12 @@ float get_brightness(const char* file){
FILE* bright = fopen(file, "r");
if(!bright){
io_error(IO_ERROR_OPEN, IO_ERROR_FILE, file);
return_value = RETVAL_INVALID_FILE;
return 0;
}
if(!fgets(buff, sizeof(buff), bright)){
io_error(IO_ERROR_READ, IO_ERROR_FILE, file);
return_value = RETVAL_INVALID_FILE;
fclose(bright);
return 0;
}
@ -137,6 +157,7 @@ void fade_out(int iv, int fv, int ms_duration, int steps){
fd = fopen(backlight_file, "w+");
if(!fd){
io_error_2(IO_ERROR_OPEN, IO_ERROR_FILE, backlight_dir, backlight_file);
return_value = RETVAL_INVALID_FILE;
return;
}
fprintf(fd, "%d", (int)value);
@ -160,6 +181,7 @@ void fade_out(int iv, int fv, int ms_duration, int steps){
fd = fopen(backlight_file, "w+");
if(!fd){
io_error_2(IO_ERROR_OPEN, IO_ERROR_FILE, backlight_dir, backlight_file);
return_value = RETVAL_INVALID_FILE;
return;
}
fprintf(fd, "%d", fv);
@ -190,6 +212,7 @@ void individual_device_loop(struct arg_values* a){
for(struct arg_values* curr = a->next;curr;curr = curr->next){
if(chdir(curr->device)){
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, backlight_dir, curr->device);
return_value = RETVAL_INVALID_DIR;
continue;
}
switch(curr->operation){
@ -214,9 +237,11 @@ void all_device_loop(struct string_array* backlight_names, struct arg_values* ar
for(int i = 0;i < backlight_names->size;i++){
if(chdir(backlight_names->list[i])){
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, backlight_dir, backlight_names->list[i]);
return_value = RETVAL_INVALID_DIR;
continue;
}
do_assignment(args);
chdir(backlight_dir);
}
break;
case OP_LIST:
@ -226,9 +251,11 @@ void all_device_loop(struct string_array* backlight_names, struct arg_values* ar
for(int i = 0;i < backlight_names->size;i++){
if(chdir(backlight_names->list[i])){
io_error_2(IO_ERROR_OPEN, IO_ERROR_DIR, backlight_dir, backlight_names->list[i]);
return_value = RETVAL_INVALID_DIR;
continue;
}
do_get(backlight_names->list[i]);
chdir(backlight_dir);
}
break;
}
@ -250,7 +277,13 @@ int main(int argc, char** argv){
//If there are no backlights, we can't do anything
if(backlight_names.size == 0){
#ifdef REXBACKLIGHT
fprintf(stderr, "No backlights devices found!\n");
#elif defined(REXLEDCTL)
fprintf(stderr, "No led devices found!\n");
#else
#error "UNDEFINED PROGRAM NAME!"
#endif
CLEANUP();
return RETVAL_INVALID_DEVICE;
}
@ -268,7 +301,16 @@ int main(int argc, char** argv){
continue_outer:;
}
char* starting_dir = getcwd(NULL, 0);
int starting_dir_max_len = pathconf(".", _PC_PATH_MAX);
char* starting_dir = malloc(starting_dir_max_len);
if(!starting_dir){
mem_error();
CLEANUP();
return RETVAL_MEM_ERROR;
}
if(!getcwd(starting_dir, starting_dir_max_len)){
fprintf(stderr, "Unable to determine starting dir!\nWill be unable to return to it on completion!\n");
}
#undef CLEANUP
#define CLEANUP() do{free_string_array(&backlight_names);free_cmd_args(&args);free(starting_dir);}while(0)
@ -300,6 +342,6 @@ int main(int argc, char** argv){
}
CLEANUP();
return RETVAL_SUCCESS;
return return_value;
}
#undef CLEANUP