Files
fastfetch/src/common/io.c
T

193 lines
4.3 KiB
C
Raw Normal View History

2021-04-09 14:07:05 +02:00
#include "fastfetch.h"
2022-07-25 11:48:48 +02:00
#include "common/io.h"
2021-04-09 14:07:05 +02:00
2022-06-18 14:25:31 +02:00
#include <sys/stat.h>
2021-04-09 14:07:05 +02:00
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <poll.h>
2021-04-09 14:07:05 +02:00
2022-04-21 15:50:45 +02:00
static void createSubfolders(const char* fileName)
{
2022-04-21 15:50:45 +02:00
FFstrbuf path;
ffStrbufInit(&path);
while(*fileName != '\0')
{
ffStrbufAppendC(&path, *fileName);
if(*fileName == '/')
mkdir(path.chars, S_IRWXU | S_IRGRP | S_IROTH);
++fileName;
}
ffStrbufDestroy(&path);
}
2022-06-19 18:22:00 +02:00
bool ffWriteFDBuffer(int fd, const FFstrbuf* content)
{
2022-06-20 16:27:33 +02:00
return write(fd, content->chars, content->length) != -1;
2022-06-19 18:22:00 +02:00
}
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
2022-04-21 15:50:45 +02:00
{
int openFlagsModes = O_WRONLY | O_CREAT | O_TRUNC;
int openFlagsRights = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int fd = open(fileName, openFlagsModes, openFlagsRights);
if(fd == -1)
2022-04-21 15:50:45 +02:00
{
createSubfolders(fileName);
fd = open(fileName, openFlagsModes, openFlagsRights);
if(fd == -1)
return false;
}
2022-06-20 16:27:33 +02:00
bool ret = write(fd, data, dataSize) != -1;
close(fd);
2022-04-21 15:50:45 +02:00
return ret;
}
2022-06-19 18:22:00 +02:00
bool ffWriteFileBuffer(const char* fileName, const FFstrbuf* buffer)
{
return ffWriteFileData(fileName, buffer->length, buffer->chars);
}
2022-06-20 16:27:33 +02:00
bool ffAppendFDBuffer(int fd, FFstrbuf* buffer)
2021-04-09 14:07:05 +02:00
{
2021-11-17 10:59:31 +01:00
ssize_t readed = 0;
ffStrbufEnsureFree(buffer, 31); // 32 - 1 for the null terminator
uint32_t free = ffStrbufGetFree(buffer);
while(
(readed = read(fd, buffer->chars + buffer->length, free)) > 0 &&
(uint32_t) readed == free
) {
2021-11-17 18:38:57 +01:00
buffer->length += (uint32_t) readed;
2022-06-08 17:14:11 +02:00
ffStrbufEnsureFree(buffer, buffer->allocated - 1); // Doubles capacity every round. -1 for the null byte.
2021-11-17 10:59:31 +01:00
free = ffStrbufGetFree(buffer);
2021-04-09 14:07:05 +02:00
}
2021-11-17 10:59:31 +01:00
// In case of failure, read returns -1. We don't want to substract the length of the buffer.
2021-05-08 16:24:57 +02:00
if(readed > 0)
2021-04-09 14:07:05 +02:00
buffer->length += (uint32_t) readed;
2021-05-08 16:24:57 +02:00
buffer->chars[buffer->length] = '\0';
2021-04-09 14:07:05 +02:00
ffStrbufTrimRight(buffer, '\n');
ffStrbufTrimRight(buffer, ' ');
2022-06-20 16:27:33 +02:00
return readed >= 0;
}
2022-06-20 16:35:15 +02:00
ssize_t ffReadFileData(const char* fileName, size_t dataSize, void* data)
2022-06-20 16:27:33 +02:00
{
int fd = open(fileName, O_RDONLY);
if(fd == -1)
return -1;
ssize_t readed = read(fd, data, dataSize);
close(fd);
return readed;
2021-04-18 15:19:21 +02:00
}
2022-06-20 16:27:33 +02:00
bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
2021-04-18 15:19:21 +02:00
{
int fd = open(fileName, O_RDONLY);
if(fd == -1)
2021-06-13 14:23:35 +02:00
return false;
2021-04-18 15:19:21 +02:00
2022-06-20 16:27:33 +02:00
bool ret = ffAppendFDBuffer(fd, buffer);
2021-04-09 14:07:05 +02:00
close(fd);
2022-06-20 16:27:33 +02:00
return ret;
2021-04-09 14:07:05 +02:00
}
2022-06-20 16:35:15 +02:00
bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
2021-04-09 14:07:05 +02:00
{
ffStrbufClear(buffer);
2022-06-20 16:27:33 +02:00
return ffAppendFileBuffer(fileName, buffer);
2021-04-09 14:07:05 +02:00
}
2021-12-15 15:42:33 +01:00
// Not thread safe!
void ffSuppressIO(bool suppress)
2021-12-15 15:42:33 +01:00
{
static bool init = false;
static int origOut = -1;
static int origErr = -1;
static int nullFile = -1;
2021-12-15 15:42:33 +01:00
if(!init)
2021-12-15 15:42:33 +01:00
{
if(!suppress)
return;
origOut = dup(STDOUT_FILENO);
origErr = dup(STDERR_FILENO);
nullFile = open("/dev/null", O_WRONLY);
init = true;
2021-12-15 15:42:33 +01:00
}
if(nullFile == -1)
return;
2021-12-15 15:42:33 +01:00
fflush(stdout);
fflush(stderr);
dup2(suppress ? nullFile : origOut, STDOUT_FILENO);
dup2(suppress ? nullFile : origErr, STDERR_FILENO);
2021-12-15 15:42:33 +01:00
}
2021-12-19 22:39:22 +01:00
2022-02-12 12:06:16 +01:00
bool ffFileExists(const char* fileName, mode_t mode)
{
struct stat fileStat;
return stat(fileName, &fileStat) == 0 && ((fileStat.st_mode & S_IFMT) == mode);
}
void ffGetTerminalResponse(const char* request, const char* format, ...)
{
struct termios oldTerm, newTerm;
if(tcgetattr(STDIN_FILENO, &oldTerm) == -1)
return;
newTerm = oldTerm;
newTerm.c_lflag &= (tcflag_t) ~(ICANON | ECHO);
if(tcsetattr(STDIN_FILENO, TCSANOW, &newTerm) == -1)
return;
fputs(request, stdout);
fflush(stdout);
struct pollfd pfd;
pfd.fd = STDIN_FILENO;
pfd.events = POLLIN;
pfd.revents = 0;
2022-04-29 21:44:32 +02:00
//Give the terminal 35ms to respond
if(poll(&pfd, 1, 35) <= 0)
{
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
return;
}
char buffer[512];
ssize_t readed = read(STDIN_FILENO, buffer, sizeof(buffer) - 1);
tcsetattr(STDIN_FILENO, TCSANOW, &oldTerm);
if(readed <= 0)
return;
buffer[readed] = '\0';
va_list args;
va_start(args, format);
vsscanf(buffer, format, args);
va_end(args);
}