summaryrefslogtreecommitdiffstats
path: root/TraceScreen.c
diff options
context:
space:
mode:
authorBenny Baumann <BenBE@geshi.org>2020-10-17 22:32:43 +0200
committerBenny Baumann <BenBE@geshi.org>2020-10-18 17:35:32 +0200
commit4dfedd3930fffcf7e5c43cea103ccf4640ae3b9e (patch)
tree733a26d8e5884cfa66218acfc8fb3d63a89f8e93 /TraceScreen.c
parentc138d148974ab383044d1eec9922127faeb020f0 (diff)
Fix various file descriptor leaks
Diffstat (limited to 'TraceScreen.c')
-rw-r--r--TraceScreen.c79
1 files changed, 56 insertions, 23 deletions
diff --git a/TraceScreen.c b/TraceScreen.c
index 314efc93..957e80e5 100644
--- a/TraceScreen.c
+++ b/TraceScreen.c
@@ -59,10 +59,11 @@ void TraceScreen_delete(Object* cast) {
if (this->child > 0) {
kill(this->child, SIGTERM);
waitpid(this->child, NULL, 0);
- fclose(this->strace);
}
+ if (this->strace)
+ fclose(this->strace);
CRT_enableDelay();
- free(InfoScreen_done((InfoScreen*)cast));
+ free(InfoScreen_done((InfoScreen*)this));
}
void TraceScreen_draw(InfoScreen* this) {
@@ -74,43 +75,75 @@ void TraceScreen_draw(InfoScreen* this) {
}
bool TraceScreen_forkTracer(TraceScreen* this) {
- int error = pipe(this->fdpair);
- if (error == -1) return false;
- this->child = fork();
- if (this->child == -1) return false;
- if (this->child == 0) {
+ int fdpair[2] = {0, 0};
+
+ if (pipe(fdpair) == -1)
+ return false;
+
+ if(fcntl(fdpair[0], F_SETFL, O_NONBLOCK) < 0)
+ goto err;
+
+ if(fcntl(fdpair[1], F_SETFL, O_NONBLOCK) < 0)
+ goto err;
+
+ pid_t child = fork();
+ if (child == -1)
+ goto err;
+
+ if (child == 0) {
+ close(fdpair[0]);
+
+ dup2(fdpair[1], STDOUT_FILENO);
+ dup2(fdpair[1], STDERR_FILENO);
+ close(fdpair[1]);
+
CRT_dropPrivileges();
- dup2(this->fdpair[1], STDERR_FILENO);
- int ok = fcntl(this->fdpair[1], F_SETFL, O_NONBLOCK);
- if (ok != -1) {
- char buffer[32] = {0};
- xSnprintf(buffer, sizeof(buffer), "%d", this->super.process->pid);
- execlp("strace", "strace", "-T", "-tt", "-s", "512", "-p", buffer, NULL);
- }
+
+ char buffer[32] = {0};
+ xSnprintf(buffer, sizeof(buffer), "%d", this->super.process->pid);
+ execlp("strace", "strace", "-T", "-tt", "-s", "512", "-p", buffer, NULL);
+
+ // Should never reach here, unless execlp fails ...
const char* message = "Could not execute 'strace'. Please make sure it is available in your $PATH.";
- ssize_t written = write(this->fdpair[1], message, strlen(message));
+ ssize_t written = write(STDERR_FILENO, message, strlen(message));
(void) written;
- exit(1);
+
+ exit(127);
}
- int ok = fcntl(this->fdpair[0], F_SETFL, O_NONBLOCK);
- if (ok == -1) return false;
- this->strace = fdopen(this->fdpair[0], "r");
- this->fd_strace = fileno(this->strace);
+
+ FILE* fd = fdopen(fdpair[0], "r");
+ if (!fd)
+ goto err;
+
+ close(fdpair[1]);
+
+ this->child = child;
+ this->strace = fd;
return true;
+
+err:
+ close(fdpair[1]);
+ close(fdpair[0]);
+ return false;
}
void TraceScreen_updateTrace(InfoScreen* super) {
TraceScreen* this = (TraceScreen*) super;
char buffer[1025];
+
+ int fd_strace = fileno(this->strace);
+ assert(fd_strace != -1);
+
fd_set fds;
FD_ZERO(&fds);
// FD_SET(STDIN_FILENO, &fds);
- FD_SET(this->fd_strace, &fds);
+ FD_SET(fd_strace, &fds);
+
struct timeval tv;
tv.tv_sec = 0; tv.tv_usec = 500;
- int ready = select(this->fd_strace+1, &fds, NULL, NULL, &tv);
+ int ready = select(fd_strace+1, &fds, NULL, NULL, &tv);
size_t nread = 0;
- if (ready > 0 && FD_ISSET(this->fd_strace, &fds))
+ if (ready > 0 && FD_ISSET(fd_strace, &fds))
nread = fread(buffer, 1, sizeof(buffer) - 1, this->strace);
if (nread && this->tracing) {
const char* line = buffer;

© 2014-2024 Faster IT GmbH | imprint | privacy policy