/* See LICENSE file for copyright and license details. */ #include "common.h" int patheq(const char *have, const char *want, const char **end_out) { while (*want) { if (*have != *want) return 0; if (*have == '/') { while (*++have == '/'); while (*++want == '/'); } } if (!end_out) return !*have; *end_out = have; return 1; } int openfile(const char *path, int *is_new_fd_out, const char **fname_out) { const char *p; int fd, digit; *fname_out = path; if (patheq(path, "/dev/fd/", &p) || patheq(path, "/proc/self/fd/", &p)) { fd = 0; while (isdigit(*p)) { digit = (int)(*p & 15); if (fd > (INT_MAX - digit) / 10) goto fallback; fd = fd * 10 + digit; } if (*p) goto fallback; *is_new_fd_out = 0; return 0; } else if (!strcmp(path, "-")) { *fname_out = ""; *is_new_fd_out = 0; return STDIN_FILENO; } else if (patheq(path, "/dev/stdin", NULL)) { *is_new_fd_out = 0; return STDIN_FILENO; } else if (patheq(path, "/dev/stdout", NULL)) { *is_new_fd_out = 0; return STDOUT_FILENO; } else if (patheq(path, "/dev/stderr", NULL)) { *is_new_fd_out = 0; return STDERR_FILENO; } else { fallback: fd = open(path, O_RDONLY); if (fd < 0) { weprintf("%s:", path); return -1; } *is_new_fd_out = 0; return fd; } }