#include <stdio.h> // for BUFSIZ 8192
#include <unistd.h> // for read(), write(), fd 0 (stdin), 1 (stdout)
int main() // copy input to output (2 lines)
{
char buf[BUFSIZ]; // 8192 bytes
int n;
// read from file descriptor 0 (stdin) into buf[]
while ((n = read(0, buf, BUFSIZ)) > 0)
{write(1, buf, n);}
// write n bytes from buf[] into file descriptor 1 (stdout)
return 0;
}
/*
gcc copy.c -o copy
./copy
Hello! // Enter
Hello!
Goodbye! // Enter
Goodbye!
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./copy < copy.c // redirect input to source file
./copy < copy // redirect input to binary file
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for BUFSIZ, EOF
#include <unistd.h> // for read(), write(), fd 0 (stdin), 1 (stdout)
int getchar1(void); // read one char at a time
int getchar2(void); // buffer version
int main() // copy input to output
{
int c;
while ((c = getchar1()) != '\n' && c != EOF)
{write(1, &c, 1);}
// write to 1 (stdout) 1 byte (second 1) from &c
write(1, &c, 1); // '\n' or EOF
while ((c = getchar2()) != '\n' && c != EOF)
{write(1, &c, 1);}
write(1, &c, 1); // '\n' or EOF
return 0;
}
int getchar1(void) // read one char at a time
{
char c;
// read from 0 (stdin) 1 byte into &c
return (read(0, &c, 1) == 1) ? (unsigned char) c : EOF;
}
int getchar2(void) // buffer version
{
static char buf[BUFSIZ]; // 8192 bytes
static char *bufp = buf; // initialize
static int n = 0; // initialize
if (n == 0) // static var n keeps its value
{ // from one function call to the other
n = read(0, buf, sizeof buf); // read from stdin (fd 0)
bufp = buf; // reset
}
// bufp keeps its incremented value until it is reset
return (--n >= 0) ? (unsigned char) *bufp++ : EOF;
} // when bufp reaches the end of buf[], n reaches 0
/*
gcc getchar.c -o getchar
./getchar
Hello! // Enter
Hello!
Goodbye! // Enter
Goodbye!
./getchar < getchar.c // write 2 lines
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for BUFSIZ, fprintf(), vfprintf(), stderr
#include <stdlib.h> // for exit()
#include <fcntl.h> // for open(), creat(), O_RDONLY
#include <unistd.h> // for read(), write(), fd 0 (stdin), 1 (stdout)
#define PERM 0666 // RW for owner, group, others
void error(char *, ...);
int main(int argc, char *argv[]) // copy file1 to file2
{
char buf[BUFSIZ]; // 8192 bytes
int f1, f2, n;
if (argc != 3)
{error("Usage: %s from to", argv[0]);}
if ((f1 = open(argv[1], O_RDONLY, 0)) == -1) // 0 - permissions
{error("%s: can't open \"%s\"", argv[0], argv[1]);}
if ((f2 = creat(argv[2], PERM)) == -1)
{error("%s: can't create \"%s\", mode %03o", argv[0], argv[2], PERM);}
while ((n = read(f1, buf, BUFSIZ)) > 0)
if (write(f2, buf, n) != n)
{error("%s: write error on file \"%s\"", argv[0], argv[2]);}
close(f1), close(f2);
return 0;
}
#include <stdarg.h> // for va_list, va_start, va_end
// print an error message and die (end program)
void error(char *fmt, ...)
{
va_list args;
va_start(args, fmt);
fprintf(stderr, "Error: ");
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
va_end(args);
exit(1); // end program from outside main()
}
/*
gcc cp.c -o cp
./cp
Error: Usage: ./cp from to
./cp stdin stdout
Error: ./cp: can't open "stdin"
./cp 0 1
Error: ./cp: can't open "0"
./cp cp.c cp2.c
diff -s cp.c cp2.c
// Files cp.c and cp2.c are identical
meld cp.c cp2.c
// Files are identical
rm cp2.c // clean
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // BUFSIZ, fprintf(), vfprintf(), fopen(), fclose(),
// ferror(), getc(), putc(), stdin, stdout, stderr, FILE, EOF, NULL
#include <stdlib.h> // for exit()
#include <time.h> // for clock_t, clock(), CLOCKS_PER_SEC
#include <fcntl.h> // for open(), O_RDONLY
#include <unistd.h> // for read(), write(), fd 0 (stdin), 1 (stdout)
#define PERM 0666 // RW for owner, group, others
void filecopy(FILE *, FILE *);
void error(char *, ...);
// concatenate files, high-level and low-level versions
int main(int argc, char *argv[])
{
FILE *fp; // file pointer
int fd; // file descriptor
int i, n;
char buf[BUFSIZ]; // 8192 bytes
char *prog = argv[0]; // program name
clock_t start, end;
double time;
start = clock();
// high-level version
if (argc == 1) // no command-line args, just program name
{ // copy standard input to standard output
filecopy(stdin, stdout);
}
else
{
for (i = 1; i < argc; i++) // start after argv[0], program name
{ // open file for reading
if ((fp = fopen(argv[i], "r")) == NULL)
{
fprintf(stderr, "%s: can't open \"%s\"\n", prog, *argv);
exit(1); // end program, signalling error
}
// else // fp != NULL, file open for reading
filecopy(fp, stdout);
fclose(fp); // close file, free fp
}
}
if (ferror(stdout))
{
fprintf(stderr, "%s: error writing stdout\n", prog);
exit(2); // end program, signal other error code
}
end = clock();
time = ((double) (end - start)) / CLOCKS_PER_SEC;
fprintf(stderr, "Execution time for high-level version: %f\n", time);
start = clock();
// low-level version
if (argc == 1) // no command-line args, just program name
{ // copy standard input to standard output
// read from file descriptor 0 (stdin) into buf[]
while ((n = read(0, buf, BUFSIZ)) > 0)
{write(1, buf, n);}
// write n bytes from buf[] into file descriptor 1 (stdout)
}
else
{
for (i = 1; i < argc; i++) // start after argv[0], program name
{ // open file for reading
if ((fd = open(argv[i], O_RDONLY, 0)) == -1) // 0 - permissions
{error("%s: can't open \"%s\"", prog, argv[i]);}
// else // fd != -1, file open for reading
while ((n = read(fd, buf, BUFSIZ)) > 0)
if (write(1, buf, n) != n)
{error("%s: write error on stdout", prog);}
close(fd); // close file, free fd
}
}
end = clock();
time = ((double) (end - start)) / CLOCKS_PER_SEC;
fprintf(stderr, "Execution time for low-level version: %f\n", time);
exit(0); // end program normally
}
// copy from ifp (input) to ofp (output)
void filecopy(FILE *ifp, FILE *ofp)
{
int c;
while ((c = getc(ifp)) != EOF)
{putc(c, ofp);}
}
#include <stdarg.h> // for va_list, va_start, va_end
// print an error message and die (end program)
void error(char *fmt, ...)
{
va_list args;
va_start(args, fmt);
fprintf(stderr, "Error: ");
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
va_end(args);
exit(1); // end program from outside main()
}
/*
gcc cat.c -o cat
./cat
Hello! // Enter
Hello!
What's up? // Enter
What's up?
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
Execution time for high-level version: 0.000130
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
Execution time for low-level version: 0.000015
./cat me.txt > copyme.txt
Execution time for high-level version: 0.005651
Execution time for low-level version: 0.000764
./cat me.txt me.txt me.txt me.txt me.txt > copyme.txt
Execution time for high-level version: 0.030387
Execution time for low-level version: 0.003533
rm copyme.txt // clean
*/