aboutsummaryrefslogblamecommitdiffstats
path: root/openfile.c
blob: e019d05fada756596611734967f369096d33ad0a (plain) (tree)















































                                                                                 
/* See LICENSE file for copyright and license details. */
#include "common.h"


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 = "<stdin>";
		*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;
	}
}