ctpv/utils.c

133 lines
2.7 KiB
C
Raw Normal View History

#include <stdio.h>
2022-05-22 09:55:04 +02:00
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
2022-05-22 09:55:04 +02:00
#include "error.h"
#include "utils.h"
char *program = NULL;
2022-05-22 09:55:04 +02:00
2022-05-24 02:46:34 +02:00
int spawn_redirect(const void *arg)
{
2022-05-25 23:57:50 +02:00
int *fds = (int *)arg;
2022-05-24 02:46:34 +02:00
2022-05-25 23:57:50 +02:00
ERRCHK_RET(close(fds[0]) == -1, FUNCFAILED("close"), ERRNOS);
ERRCHK_RET(dup2(fds[1], fds[2]) == -1, FUNCFAILED("dup2"), ERRNOS);
return OK;
}
int spawn_wait(pid_t pid, int *exitcode)
{
int stat;
ERRCHK_RET(waitpid(pid, &stat, 0) == -1, FUNCFAILED("waitpid"), ERRNOS);
if (exitcode && WIFEXITED(stat))
*exitcode = WEXITSTATUS(stat);
2022-05-24 02:46:34 +02:00
return OK;
}
2022-05-22 09:55:04 +02:00
/*
2022-06-01 00:18:22 +02:00
* Run command
2022-05-22 09:55:04 +02:00
*
* If cpid is NULL, wait for the command to finish executing;
* otherwise store pid in cpid
2022-05-23 03:32:09 +02:00
*
2022-05-24 02:46:34 +02:00
* cfunc is a function to call when child process is created
2022-05-22 09:55:04 +02:00
*/
2022-05-24 02:46:34 +02:00
int spawn(char *args[], pid_t *cpid, int *exitcode, int (*cfunc)(const void *),
const void *carg)
2022-05-22 09:55:04 +02:00
{
if (exitcode)
*exitcode = -1;
pid_t pid = fork();
ERRCHK_RET(pid == -1, FUNCFAILED("fork"), ERRNOS);
2022-05-22 09:55:04 +02:00
/* Child process */
if (pid == 0) {
2022-05-24 02:46:34 +02:00
if (cfunc && (cfunc(carg) != OK))
exit(EXIT_FAILURE);
2022-05-23 03:32:09 +02:00
2022-05-22 09:55:04 +02:00
execvp(args[0], args);
2022-05-25 23:57:50 +02:00
if (errno == ENOENT)
exit(NOTEXIST_EC);
PRINTINTERR(FUNCFAILED("exec"), ERRNOS);
2022-05-22 09:55:04 +02:00
exit(EXIT_FAILURE);
}
2022-05-25 23:57:50 +02:00
if (cpid)
2022-05-22 09:55:04 +02:00
*cpid = pid;
2022-05-25 23:57:50 +02:00
if (exitcode)
ERRCHK_RET_OK(spawn_wait(pid, exitcode));
2022-05-22 09:55:04 +02:00
return OK;
}
2022-06-02 01:37:43 +02:00
int strcmpnull(const char *s1, const char *s2)
{
if (!s1 && !s2)
return 0;
else if (s1 && !s2)
return 1;
else if (!s1 && s2)
return -1;
return strcmp(s1, s2);
}
2022-06-02 01:37:43 +02:00
int strlennull(const char *s)
2022-06-01 18:17:47 +02:00
{
return s ? strlen(s) : 0;
}
2022-06-08 01:27:30 +02:00
static int get_xdg_dir(char *buf, size_t len, char *var, char *var_sub, char *name)
{
2022-06-08 01:27:30 +02:00
char *home, *dir, dir_buf[FILENAME_MAX];
2022-06-08 01:27:30 +02:00
if (!(dir = getenv(var))) {
home = getenv("HOME");
ERRCHK_RET(!home, "HOME env var does not exist");
2022-06-08 01:27:30 +02:00
snprintf(dir_buf, LEN(dir_buf)-1, "%s/%s", home, var_sub);
dir = dir_buf;
}
2022-06-08 01:27:30 +02:00
snprintf(buf, len - 1, "%s/%s", dir, name);
return OK;
}
2022-06-08 01:27:30 +02:00
int get_cache_dir(char *buf, size_t len, char *name)
{
return get_xdg_dir(buf, len, "XDG_CACHE_HOME", ".cache", name);
}
int get_config_dir(char *buf, size_t len, char *name)
{
return get_xdg_dir(buf, len, "XDG_CONFIG_HOME", ".config", name);
}
int mkpath(char* file_path, mode_t mode)
{
for (char* p = strchr(file_path + 1, '/'); p; p = strchr(p + 1, '/')) {
*p = '\0';
if (mkdir(file_path, mode) == -1) {
if (errno != EEXIST) {
*p = '/';
return -1;
}
}
*p = '/';
}
return 0;
}