blob: bed0d8157754b915939e087180bb9905f302d8c2 [file] [log] [blame]
/* SPDX-License-Identifier: MediaTekProprietary */
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <syslog.h>
#include "utility.h"
/*******************************************************************************/
/* UTILITY local definitions */
/*******************************************************************************/
/*******************************************************************************/
/* UTILITY local prototypes */
/*******************************************************************************/
/*******************************************************************************/
/* UTILITY local variables */
/*******************************************************************************/
int libsncfg_rw_block = 1;
/*******************************************************************************/
/* UTILITY local functions */
/*******************************************************************************/
/*******************************************************************************/
/* UTILITY functions */
/*******************************************************************************/
int safe_close(int fd)
{
int ret;
do {
ret = close(fd);
} while (ret < 0 && errno == EINTR);
if (ret < 0) {
int errnoTmp = errno;
fprintf(stderr, "[LIBSNCFG][%d] close(%d) @ safe_close() failed : %s !!\n", getpid(), fd, strerror(errnoTmp));
syslog(LOG_WARNING, "[LIBSNCFG][%d] close(%d) @ safe_close() failed : %s !!", getpid(), fd, strerror(errnoTmp));
}
return ret;
}
ssize_t safe_read(int fd, void *buf, size_t count)
{
ssize_t n;
again:
do {
n = read(fd, buf, count);
} while (n < 0 && errno == EINTR);
if (n < 0) {
int errnoTmp = errno;
fprintf(stderr, "[LIBSNCFG][%d] read(%d) @ safe_read() failed : %s !!\n", getpid(), fd, strerror(errnoTmp));
syslog(LOG_WARNING, "[LIBSNCFG][%d] read(%d) @ safe_read() failed : %s !!", getpid(), fd, strerror(errnoTmp));
if ((errnoTmp == EWOULDBLOCK || errnoTmp == EAGAIN) && libsncfg_rw_block) {
goto again;
}
}
return n;
}
ssize_t safe_write(int fd, const void *buf, size_t count)
{
ssize_t n;
again:
do {
n = write(fd, buf, count);
if (n == 0) {
fprintf(stderr, "[LIBSNCFG][%d] write(%d) @ safe_write : write zero byte !!\n", getpid(), fd);
syslog(LOG_WARNING, "[LIBSNCFG][%d] write(%d) @ safe_write : write zero byte !!", getpid(), fd);
}
} while (n < 0 && errno == EINTR);
if (n < 0) {
int errnoTmp = errno;
fprintf(stderr, "[LIBSNCFG][%d] write(%d) @ safe_write() failed : %s !!\n", getpid(), fd, strerror(errnoTmp));
syslog(LOG_WARNING, "[LIBSNCFG][%d] write(%d) @ safe_write() failed : %s !!", getpid(), fd, strerror(errnoTmp));
if ((errno == EWOULDBLOCK || errno == EAGAIN) && libsncfg_rw_block) {
goto again;
}
}
return n;
}
char *dupstr(char* s)
{
char *r;
r = malloc (strlen (s) + 1);
if (r)
strcpy (r, s);
return (r);
}
int nonrt_system(const char *cmd)
{
int wait_val, pid;
sig_t save_quit, save_int, save_chld;
struct sched_param sched;
if (cmd == 0) {
return 1;
}
save_quit = signal(SIGQUIT, SIG_IGN);
save_int = signal(SIGINT, SIG_IGN);
save_chld = signal(SIGCHLD, SIG_DFL);
if ((pid = vfork()) < 0) {
signal(SIGQUIT, save_quit);
signal(SIGINT, save_int);
signal(SIGCHLD, save_chld);
return -1;
}
if (pid == 0) {
signal(SIGQUIT, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
/* child, can only call thread safe functions before exec ... */
sched.sched_priority = 0;
if (sched_setscheduler(0, SCHED_OTHER, &sched) == -1) {
exit(127);
}
execl("/bin/sh", "sh", "-c", cmd, (char *) 0);
exit(127);
}
/* Signals are not absolutly guarenteed with vfork */
signal(SIGQUIT, SIG_IGN);
signal(SIGINT, SIG_IGN);
if (wait4(pid, &wait_val, 0, 0) == -1) {
wait_val = -1;
}
signal(SIGQUIT, save_quit);
signal(SIGINT, save_int);
signal(SIGCHLD, save_chld);
return wait_val;
}