#include "gbos.h" /* cp SRC DST: copy a file. There is no rename syscall, so `mv` is this plus * rm - and O_WRITE truncates (see fs.asm sys_open .trunc), which is exactly * why the SRC == DST case below has to be rejected before opening DST. */ static unsigned char streq(const char *a, const char *b) { while (*a && *a == *b) { a++; b++; } return (unsigned char)(*a == *b); } void main(void) { char *argv[4]; unsigned char argc = argv_parse(argv, 4); unsigned char in, out; int ch; if (argc < 2) { puts("usage: cp SRC DST"); nl(); sexit(2); } if (streq(argv[0], argv[1])) { puts("cp: SRC and DST are the same file"); nl(); sexit(2); } in = open(argv[0], O_READ); if (in == EISDIR) { puts("cp: SRC is a directory"); nl(); sexit(2); } if (in == NOFD) { puts("cp: no such file: "); puts(argv[0]); nl(); sexit(2); } out = open(argv[1], O_WRITE); /* creates, or truncates an existing file */ if (out == EISDIR) { puts("cp: DST is a directory"); nl(); close(in); sexit(2); } if (out == NOFD) { puts("cp: cannot create "); puts(argv[1]); nl(); close(in); sexit(2); /* out of inodes/blocks, or a bad path */ } while ((ch = fgetc(in)) >= 0) fputc(out, (char)ch); close(in); close(out); /* flushes the inode */ }