pwm: use posix open instead of fopen
* Add safety to output char arrays and filepaths. Signed-off-by: Thomas Ingleby <thomas.c.ingleby@intel.com> Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
committed by
Brendan Le Foll
parent
e2f72540ef
commit
fa7180cb91
131
src/pwm/pwm.c
131
src/pwm/pwm.c
@@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND/
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
#include "pwm.h"
|
#include "pwm.h"
|
||||||
|
|
||||||
|
#define MAX_SIZE 64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A structure representing a PWM pin
|
* A structure representing a PWM pin
|
||||||
*/
|
*/
|
||||||
@@ -33,17 +35,18 @@ struct _pwm {
|
|||||||
/*@{*/
|
/*@{*/
|
||||||
int pin; /**< the pin number, as known to the os. */
|
int pin; /**< the pin number, as known to the os. */
|
||||||
int chipid; /**< the chip id, which the pwm resides */
|
int chipid; /**< the chip id, which the pwm resides */
|
||||||
FILE *duty_fp; /**< File pointer to duty file */
|
int duty_fp; /**< File pointer to duty file */
|
||||||
/*@}*/
|
/*@}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
maa_pwm_setup_duty_fp(maa_pwm_context dev)
|
maa_pwm_setup_duty_fp(maa_pwm_context dev)
|
||||||
{
|
{
|
||||||
char bu[64];
|
char bu[MAX_SIZE];
|
||||||
sprintf(bu, "/sys/class/pwm/pwmchip%d/pwm%d/duty_cycle", dev->chipid, dev->pin);
|
snprintf(bu,MAX_SIZE, "/sys/class/pwm/pwmchip%d/pwm%d/duty_cycle", dev->chipid, dev->pin);
|
||||||
|
|
||||||
if ((dev->duty_fp = fopen(bu, "r+b")) == NULL) {
|
dev->duty_fp = open(bu, O_RDWR);
|
||||||
|
if (dev->duty_fp == -1) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -52,31 +55,34 @@ maa_pwm_setup_duty_fp(maa_pwm_context dev)
|
|||||||
static maa_result_t
|
static maa_result_t
|
||||||
maa_pwm_write_period(maa_pwm_context dev, int period)
|
maa_pwm_write_period(maa_pwm_context dev, int period)
|
||||||
{
|
{
|
||||||
FILE *period_f;
|
char bu[MAX_SIZE];
|
||||||
char bu[64];
|
snprintf(bu,MAX_SIZE ,"/sys/class/pwm/pwmchip%d/pwm%d/period", dev->chipid, dev->pin);
|
||||||
sprintf(bu, "/sys/class/pwm/pwmchip%d/pwm%d/period", dev->chipid, dev->pin);
|
|
||||||
|
|
||||||
if ((period_f = fopen(bu, "r+b")) == NULL) {
|
int period_f = open(bu, O_RDWR);
|
||||||
|
if (period_f == -1) {
|
||||||
fprintf(stderr, "Failed to open period for writing!\n");
|
fprintf(stderr, "Failed to open period for writing!\n");
|
||||||
return MAA_ERROR_INVALID_RESOURCE;
|
return MAA_ERROR_INVALID_RESOURCE;
|
||||||
}
|
}
|
||||||
fprintf(period_f, "%d", period);
|
char out[MAX_SIZE];
|
||||||
fclose(period_f);
|
int length = snprintf(out, MAX_SIZE, "%d", dev->pin);
|
||||||
if (ferror(period_f) != 0)
|
if (write(period_f, out, length*sizeof(char)) == -1) {
|
||||||
|
close(period_f);
|
||||||
return MAA_ERROR_INVALID_RESOURCE;
|
return MAA_ERROR_INVALID_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(period_f);
|
||||||
return MAA_SUCCESS;
|
return MAA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static maa_result_t
|
static maa_result_t
|
||||||
maa_pwm_write_duty(maa_pwm_context dev, int duty)
|
maa_pwm_write_duty(maa_pwm_context dev, int duty)
|
||||||
{
|
{
|
||||||
if (dev->duty_fp == NULL) {
|
if (dev->duty_fp == -1) {
|
||||||
maa_pwm_setup_duty_fp(dev);
|
maa_pwm_setup_duty_fp(dev);
|
||||||
}
|
}
|
||||||
fprintf(dev->duty_fp, "%d", duty);
|
char bu[64];
|
||||||
rewind(dev->duty_fp);
|
int length = sprintf(bu, "%d", duty);
|
||||||
fflush(dev->duty_fp);
|
if (write(dev->duty_fp, bu, length * sizeof(char)) == -1)
|
||||||
if (ferror(dev->duty_fp) != 0)
|
|
||||||
return MAA_ERROR_INVALID_RESOURCE;
|
return MAA_ERROR_INVALID_RESOURCE;
|
||||||
return MAA_SUCCESS;
|
return MAA_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -84,17 +90,20 @@ maa_pwm_write_duty(maa_pwm_context dev, int duty)
|
|||||||
static int
|
static int
|
||||||
maa_pwm_get_period(maa_pwm_context dev)
|
maa_pwm_get_period(maa_pwm_context dev)
|
||||||
{
|
{
|
||||||
FILE *period_f;
|
char bu[MAX_SIZE];
|
||||||
char bu[64];
|
char output[MAX_SIZE];
|
||||||
char output[16];
|
snprintf(bu,MAX_SIZE, "/sys/class/pwm/pwmchip%d/pwm%d/period", dev->chipid, dev->pin);
|
||||||
|
|
||||||
sprintf(bu, "/sys/class/pwm/pwmchip%d/pwm%d/period", dev->chipid, dev->pin);
|
int period_f = open(bu, O_RDWR);
|
||||||
if ((period_f = fopen(bu, "rb")) == NULL) {
|
if (period_f == -1) {
|
||||||
fprintf(stderr, "Failed to open period for reading!\n");
|
fprintf(stderr, "Failed to open period for reading!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fgets(output, 16, period_f);
|
off_t size = lseek(period_f, 0, SEEK_END);
|
||||||
fclose(period_f);
|
lseek(period_f, 0, SEEK_SET);
|
||||||
|
|
||||||
|
read(period_f, output, size + 1);
|
||||||
|
close(period_f);
|
||||||
int ret = strtol(output, NULL, 10);
|
int ret = strtol(output, NULL, 10);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -103,12 +112,15 @@ maa_pwm_get_period(maa_pwm_context dev)
|
|||||||
static int
|
static int
|
||||||
maa_pwm_get_duty(maa_pwm_context dev)
|
maa_pwm_get_duty(maa_pwm_context dev)
|
||||||
{
|
{
|
||||||
if (dev->duty_fp == NULL) {
|
if (dev->duty_fp == -1) {
|
||||||
maa_pwm_setup_duty_fp(dev);
|
maa_pwm_setup_duty_fp(dev);
|
||||||
|
} else {
|
||||||
|
lseek(dev->duty_fp, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
char output[16];
|
off_t size = lseek(dev->duty_fp, 0, SEEK_END);
|
||||||
fgets(output, 16, dev->duty_fp);
|
lseek(dev->duty_fp, 0, SEEK_SET);
|
||||||
fseek(dev->duty_fp, SEEK_SET, 0);
|
char output[MAX_SIZE];
|
||||||
|
read(dev->duty_fp, output, size+1);
|
||||||
|
|
||||||
int ret = strtol(output, NULL, 10);
|
int ret = strtol(output, NULL, 10);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -131,23 +143,27 @@ maa_pwm_init_raw(int chipin, int pin)
|
|||||||
maa_pwm_context dev = (maa_pwm_context) malloc(sizeof(struct _pwm));
|
maa_pwm_context dev = (maa_pwm_context) malloc(sizeof(struct _pwm));
|
||||||
if (dev == NULL)
|
if (dev == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
dev->duty_fp == -1;
|
||||||
dev->chipid = chipin;
|
dev->chipid = chipin;
|
||||||
dev->pin = pin;
|
dev->pin = pin;
|
||||||
|
|
||||||
FILE *export_f;
|
char buffer[MAX_SIZE];
|
||||||
char buffer[64];
|
snprintf(buffer, MAX_SIZE, "/sys/class/pwm/pwmchip%d/export", dev->chipid);
|
||||||
snprintf(buffer, 64, "/sys/class/pwm/pwmchip%d/export", dev->chipid);
|
int export_f = open(buffer, O_WRONLY);
|
||||||
|
if (export_f == -1) {
|
||||||
if ((export_f = fopen(buffer, "w")) == NULL) {
|
|
||||||
fprintf(stderr, "Failed to open export for writing!\n");
|
fprintf(stderr, "Failed to open export for writing!\n");
|
||||||
free(dev);
|
free(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
|
||||||
fprintf(export_f, "%d", dev->pin);
|
|
||||||
fclose(export_f);
|
|
||||||
maa_pwm_setup_duty_fp(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char out[MAX_SIZE];
|
||||||
|
int size = snprintf(out, MAX_SIZE, "%d", dev->pin);
|
||||||
|
if (write(export_f, out, size*sizeof(char)) == -1) {
|
||||||
|
fprintf(stderr, "Failed to write to export! Potentially already enabled\n");
|
||||||
|
}
|
||||||
|
close(export_f);
|
||||||
|
maa_pwm_setup_duty_fp(dev);
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,36 +225,47 @@ maa_pwm_enable(maa_pwm_context dev, int enable)
|
|||||||
} else {
|
} else {
|
||||||
status = enable;
|
status = enable;
|
||||||
}
|
}
|
||||||
FILE *enable_f;
|
char bu[MAX_SIZE];
|
||||||
char bu[64];
|
snprintf(bu,MAX_SIZE, "/sys/class/pwm/pwmchip%d/pwm%d/enable", dev->chipid, dev->pin);
|
||||||
sprintf(bu, "/sys/class/pwm/pwmchip%d/pwm%d/enable", dev->chipid, dev->pin);
|
|
||||||
|
|
||||||
if ((enable_f = fopen(bu, "w")) == NULL) {
|
int enable_f = open(bu, O_RDWR);
|
||||||
|
|
||||||
|
if (enable_f == -1) {
|
||||||
fprintf(stderr, "Failed to open enable for writing!\n");
|
fprintf(stderr, "Failed to open enable for writing!\n");
|
||||||
return MAA_ERROR_INVALID_RESOURCE;
|
return MAA_ERROR_INVALID_RESOURCE;
|
||||||
}
|
}
|
||||||
fprintf(enable_f, "%d", status);
|
char out[2];
|
||||||
fclose(enable_f);
|
int size = snprintf(out, sizeof(out), "%d", enable);
|
||||||
if (ferror(enable_f) != 0)
|
if (write(enable_f, out, size * sizeof(char)) == -1) {
|
||||||
|
fprintf(stderr, "Failed to write to enable!\n");
|
||||||
|
close(enable_f);
|
||||||
return MAA_ERROR_INVALID_RESOURCE;
|
return MAA_ERROR_INVALID_RESOURCE;
|
||||||
|
}
|
||||||
|
close(enable_f);
|
||||||
return MAA_SUCCESS;
|
return MAA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
maa_result_t
|
maa_result_t
|
||||||
maa_pwm_unexport(maa_pwm_context dev)
|
maa_pwm_unexport(maa_pwm_context dev)
|
||||||
{
|
{
|
||||||
FILE *unexport_f;
|
char filepath[MAX_SIZE];
|
||||||
char buffer[64];
|
snprintf(filepath, MAX_SIZE, "/sys/class/pwm/pwmchip%d/unexport", dev->chipid);
|
||||||
snprintf(buffer, 64, "/sys/class/pwm/pwmchip%d/unexport", dev->chipid);
|
|
||||||
|
|
||||||
if ((unexport_f = fopen(buffer, "w")) == NULL) {
|
int unexport_f = open(filepath, O_WRONLY);
|
||||||
|
if (unexport_f == -1) {
|
||||||
fprintf(stderr, "Failed to open unexport for writing!\n");
|
fprintf(stderr, "Failed to open unexport for writing!\n");
|
||||||
return MAA_ERROR_INVALID_RESOURCE;
|
return MAA_ERROR_INVALID_RESOURCE;
|
||||||
}
|
}
|
||||||
fprintf(unexport_f, "%d", dev->pin);
|
|
||||||
fclose(unexport_f);
|
char out[MAX_SIZE];
|
||||||
if (ferror(unexport_f) != 0)
|
int size = snprintf(out, MAX_SIZE, "%d", dev->pin);
|
||||||
|
if (write(unexport_f, out, size*sizeof(char)) == -1) {
|
||||||
|
fprintf(stderr, "Failed to write to unexport!\n");
|
||||||
|
close(unexport_f);
|
||||||
return MAA_ERROR_INVALID_RESOURCE;
|
return MAA_ERROR_INVALID_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(unexport_f);
|
||||||
return MAA_SUCCESS;
|
return MAA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user