Connect minish-once to minish using a pipe
[minish.git] / src / minish-once.c
blob88f8e099d5396b5f1643692c2cd92f6eaa5a744b
1 #define _POSIX_C_SOURCE 200809L
3 #include <errno.h> // EBADF,ENOMEM,errno
4 #include <limits.h> // CHAR_BIT
5 #include <locale.h> // LC_ALL,setlocale
6 #include <stdio.h> // ferror,fputs,getline,perror,ssize_t,stderr,stdin
7 #include <stdlib.h> // EXIT_FAILURE,NULL,malloc,size_t
8 #include <unistd.h> // close,execv,write
10 #define PROGRAM_NAME "minish-once: "
12 static int write_return(int const fd, int const result) {
13 if (write(fd, &result, sizeof(result)) == -1) {
14 perror(PROGRAM_NAME "write()");
15 return EXIT_FAILURE;
17 return result;
20 int main(int argc, char** argv) {
21 setlocale(LC_ALL, "");
22 int fd = 0;
23 if ((size_t)argc < sizeof(fd)) {
24 errno = EBADF;
25 perror(PROGRAM_NAME "argv");
27 for (size_t i = 0u; i < sizeof(int); ++i) {
28 fd |= argv[i + 1u][0] << CHAR_BIT * i;
30 char* line = NULL;
31 size_t size = 0u;
32 ssize_t len = getline(&line, &size, stdin);
33 if (len == -1) {
34 if (ferror(stdin)) {
35 perror(PROGRAM_NAME "stdin");
36 return write_return(fd, EXIT_FAILURE);
38 return write_return(fd, 0);
40 if (line[len - 1] == '\n') { // NOTE len cannot be 0
41 line[--len] = '\0';
43 size_t words = 1u;
44 for (char* s = line; s < line + len; ++s) {
45 if (!*s) {
46 ++words;
49 char** const child_argv = malloc(words * sizeof(char*));
50 if (!child_argv) {
51 errno = ENOMEM;
52 perror(PROGRAM_NAME "malloc()");
53 return write_return(fd, EXIT_FAILURE);
55 close(fd);
56 child_argv[0] = line;
57 size_t i = 1u;
58 for (char* s = line; s < line + len; ++s) {
59 if (!*s) {
60 child_argv[i++] = s + 1;
63 child_argv[i] = NULL;
64 execv(line, child_argv);
65 int const tmp = errno;
66 fputs(PROGRAM_NAME, stderr);
67 errno = tmp;
68 perror(line);
69 return EXIT_FAILURE;