shithub: diff

ref: b61ca21ef5e741a68439c84e9f8c79f690215375
dir: /util.c/

View raw version
#include <u.h>
#include <libc.h>
#include <bio.h>
#include "diff.h"

Biobuf	stdout;
char	mode;			/* '\0', 'e', 'f', 'h' */
char	bflag;			/* ignore multiple and trailing blanks */
char	rflag;			/* recurse down directory trees */
char	mflag;			/* pseudo flag: doing multiple files, one dir */
int	anychange;

static char *tmp[] = {"/tmp/diff1XXXXXXXXXXX", "/tmp/diff2XXXXXXXXXXX"};
static int whichtmp;

void *
emalloc(unsigned n)
{
	register void *p;

	if ((p = malloc(n)) == 0)
		sysfatal("malloc: %r");
	return p;
}

void *
erealloc(void *p, unsigned n)
{
	void *rp;

	if ((rp = realloc(p, n)) == 0)
		sysfatal("realloc: %r");
	return rp;
}

int
mkpathname(char *pathname, char *path, char *name)
{
	if (strlen(path) + strlen(name) > MAXPATHLEN) {
		sysfatal("pathname %s/%s too long", path, name);
		return 1;
	}
	sprint(pathname, "%s/%s", path, name);
	return 0;
}

char *
mktmpfile(int input, Dir **sb)
{
	int fd, i;
	char *p;
	char buf[8192];

	p = mktemp(tmp[whichtmp++]);
	fd = create(p, OWRITE|ORCLOSE, 0600);
	if (fd < 0) {
		sysfatal("cannot create %s: %r", p);
		return 0;
	}
	while ((i = read(input, buf, sizeof(buf))) > 0) {
		if ((i = write(fd, buf, i)) < 0)
			break;
	}
	*sb = dirfstat(fd);
	close(fd);
	if (i < 0) {
		sysfatal("cannot read/write %s: %r", p);
		return 0;
	}
	return p;
}

void
rmtmpfiles(void)
{
	while (whichtmp > 0) {
		whichtmp--;
		remove(tmp[whichtmp]);
	}
}

char *
statfile(char *file, Dir **sb)
{
	Dir *dir;
	int input;

	dir = dirstat(file);
	if(dir == nil) {
		if (strcmp(file, "-") || (dir = dirfstat(0)) == nil) {
			sysfatal("cannot stat %s: %r", file);
			return 0;
		}
		free(dir);
		return mktmpfile(0, sb);
	} else if (!REGULAR_FILE(dir) && !DIRECTORY(dir)) {
		free(dir);
		if ((input = open(file, OREAD)) == -1) {
			sysfatal("cannot open %s: %r", file);
			return 0;
		}
		file = mktmpfile(input, sb);
		close(input);
	} else
		*sb = dir;
	return file;
}