LibC: Implement popen and pclose
This commit is contained in:
parent
f73e954b28
commit
1ba883719a
|
@ -4,6 +4,7 @@
|
||||||
#include <scanf_impl.h>
|
#include <scanf_impl.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -15,6 +16,8 @@ struct FILE
|
||||||
bool eof { false };
|
bool eof { false };
|
||||||
bool error { false };
|
bool error { false };
|
||||||
|
|
||||||
|
int pid { -1 };
|
||||||
|
|
||||||
unsigned char buffer[BUFSIZ] {};
|
unsigned char buffer[BUFSIZ] {};
|
||||||
uint32_t buffer_index { 0 };
|
uint32_t buffer_index { 0 };
|
||||||
};
|
};
|
||||||
|
@ -455,8 +458,28 @@ char* gets(char* buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
int pclose(FILE* file)
|
||||||
int pclose(FILE*);
|
{
|
||||||
|
if (file->pid == -1)
|
||||||
|
{
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = file->pid;
|
||||||
|
(void)fclose(file);
|
||||||
|
|
||||||
|
int stat;
|
||||||
|
while (waitpid(pid, &stat, 0) != -1)
|
||||||
|
{
|
||||||
|
if (errno != EINTR)
|
||||||
|
{
|
||||||
|
stat = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
void perror(const char* string)
|
void perror(const char* string)
|
||||||
{
|
{
|
||||||
|
@ -471,8 +494,60 @@ void perror(const char* string)
|
||||||
stderr->error = true;
|
stderr->error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
FILE* popen(const char* command, const char* mode_str)
|
||||||
FILE* popen(const char*, const char*);
|
{
|
||||||
|
if ((mode_str[0] != 'r' && mode_str[0] != 'w') || mode_str[1] != '\0')
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read = (mode_str[0] == 'r');
|
||||||
|
|
||||||
|
int fds[2];
|
||||||
|
if (pipe(fds) == -1)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
pid_t pid = fork();
|
||||||
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
if (read)
|
||||||
|
dup2(fds[1], STDOUT_FILENO);
|
||||||
|
else
|
||||||
|
dup2(fds[0], STDIN_FILENO);
|
||||||
|
close(fds[0]);
|
||||||
|
close(fds[1]);
|
||||||
|
|
||||||
|
execl("/bin/Shell", "sh", "-c", command, nullptr);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == -1)
|
||||||
|
{
|
||||||
|
close(fds[0]);
|
||||||
|
close(fds[1]);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(read ? fds[1] : fds[0]);
|
||||||
|
|
||||||
|
// FIXME: when threads are implemented
|
||||||
|
for (int i = 0; i < FOPEN_MAX; i++)
|
||||||
|
{
|
||||||
|
if (s_files[i].fd == -1)
|
||||||
|
{
|
||||||
|
s_files[i] = {
|
||||||
|
.fd = read ? fds[0] : fds[1],
|
||||||
|
.mode = (unsigned)(read ? O_RDONLY : O_WRONLY),
|
||||||
|
.pid = pid
|
||||||
|
};
|
||||||
|
return &s_files[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = EMFILE;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
int printf(const char* format, ...)
|
int printf(const char* format, ...)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue