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()");
20 int main(int argc
, char** argv
) {
21 setlocale(LC_ALL
, "");
23 if ((size_t)argc
< sizeof(fd
)) {
25 perror(PROGRAM_NAME
"argv");
27 for (size_t i
= 0u; i
< sizeof(int); ++i
) {
28 fd
|= argv
[i
+ 1u][0] << CHAR_BIT
* i
;
32 ssize_t len
= getline(&line
, &size
, 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
44 for (char* s
= line
; s
< line
+ len
; ++s
) {
49 char** const child_argv
= malloc(words
* sizeof(char*));
52 perror(PROGRAM_NAME
"malloc()");
53 return write_return(fd
, EXIT_FAILURE
);
58 for (char* s
= line
; s
< line
+ len
; ++s
) {
60 child_argv
[i
++] = s
+ 1;
64 execv(line
, child_argv
);
65 int const tmp
= errno
;
66 fputs(PROGRAM_NAME
, stderr
);