/* Lustre Test - LU-2277
 * Written By: Nathaniel Clark <nathaniel.l.clark@intel.com>
 *
 * This does a normal copy, except it does an extra open and close of dest file
 * which triggers bug LU-2277 when dest has a stripe width >= 54
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define BLOCK 512

int main(int argc, char *argv[]) {
	int src = 0, dst = 0, s;
	int rc = 0, doextra = 0;
	void *foo;
	struct stat stat;

	if (argc < 2) {
		printf("Usage: %s [src] [dest]\n", argv[0]);
		printf("  LU-2277 Test: Copy file with double open/close\n");
		return(0);
	}

	src = open(argv[1], O_RDONLY|O_NOCTTY);
	if (src < 0) {
		printf("ERROR: open(%s) -> %d\n", argv[1], src);
		rc = 2;
		goto out;
	}
	fstat(src, &stat);

	// Create as final executable
	dst = open(argv[2], O_RDWR|O_CREAT|O_TRUNC, stat.st_mode);
	if (dst < 0) {
		printf("ERROR: open(%s, %#o) -> %d\n", argv[2], stat.st_mode, dst);
		rc = 3;
		goto out;
	}

	foo = malloc(BLOCK);
	if (foo == NULL) {
		printf("malloc(%dB): failed\n", BLOCK);
		rc = 4;
		goto out;
	}

	while ( (s = read(src, foo, BLOCK)) > 0) {
		write(dst, foo, s);
	}
	doextra = 1;
	free(foo);

out:
	if (src)
		close(src);

	if (dst)
		close(dst);

	/* Simple File copy to this point.  Extra open and close, and executable
	 * fails to run */
	if (doextra) {
		dst = open(argv[2], O_RDWR);
		close(dst);
	}

	return rc;
}