--- /dev/null
+.TH CAT 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+cat \- concatenate file(s) to standard output
+.SH SYNOPSIS
+.B cat
+[-u] [file ...]
+.SH DESCRIPTION
+Sequentially read input files and write their contents to standard output.
+.SH OPTIONS
+.TP
+-u
+Fully unbuffered read and write.
+.SH OPERANDS
+.TP
+file
+Input file(s). If none provided, or the filename '-' is passed to cat,
+standard input will be used.
+.SH NOTES
+As files are processed sequentially, beware of shell commands like
+.P
+.RS
+cat x y > x
+.RE
+.P
+which destroy input files before reading them.
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/cat.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * cat.c - concatenate file(s) to standard output
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o cat cat.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/cat.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define USAGE "usage: cat [-u] [file ...]\n"
+#define BUFSIZE 4096
+
+static void catfile(int fd, char *fn);
+static void error(char *s);
+
+static int exitstatus;
+static int optu;
+
+
+int main(int argc, char **argv)
+{
+ extern int opterr, optind;
+ int c, fd;
+ char *fn;
+
+ setlocale(LC_ALL, "");
+ opterr = 0;
+
+ while ((c = getopt(argc, argv, "u")) != -1)
+ switch (c)
+ {
+ case 'u':
+ optu = 1;
+ break;
+ default:
+ fprintf(stderr, USAGE);
+ return(1);
+ }
+
+ if (optind >= argc)
+ catfile(STDIN_FILENO, "stdin");
+ else
+ while (optind < argc)
+ {
+ fn = argv[optind++];
+
+ if (strcmp(fn, "-") == 0)
+ catfile(STDIN_FILENO, "stdin");
+ else
+ if ((fd = open(fn, O_RDONLY)) == -1)
+ error(fn);
+ else
+ {
+ catfile(fd, fn);
+ if (close(fd) == -1)
+ error(fn);
+ }
+ }
+
+ return(exitstatus);
+}
+
+
+void catfile(int fd, char *fn)
+{
+ unsigned char buf[BUFSIZE];
+ ssize_t n;
+
+ while ((n = read(fd, buf, (optu ? 1 : BUFSIZE))) > 0)
+ if (write(STDOUT_FILENO, buf, (size_t)n) != n)
+ {
+ error("stdout");
+ break;
+ }
+
+ if (n < 0)
+ error(fn);
+}
+
+
+void error(char *s)
+{
+ fprintf(stderr, "cat: %s: %s\n", s, strerror(errno));
+ exitstatus = 1;
+}
--- /dev/null
+.TH CKSUM 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+cksum \- report checksum and octet count of file(s)
+.SH SYNOPSIS
+.B cksum
+[file ...]
+.SH DESCRIPTION
+Display CRC check value and octet count of given file(s).
+.SH OPTIONS
+.TP
+None
+.SH OPERANDS
+.TP
+file
+Input file. If none provided, or the filename '-' is passed to cksum,
+standard input will be used.
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/cksum.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * cksum - report checksum and octet count of file(s)
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o cksum cksum.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/cksum.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <locale.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define BUFSIZE 4096
+
+static void cksumfile(int fd, char *fn);
+static void error(char *s);
+
+static int exitstatus;
+
+
+int main(int argc, char **argv)
+{
+ int i, fd, hasrun = 0;
+ char *fn;
+
+ setlocale(LC_ALL, "");
+
+ for (i = 1; i < argc; i++)
+ {
+ fn = argv[i];
+
+ if (strcmp(fn, "--") == 0)
+ continue;
+ else
+ {
+ hasrun = 1;
+
+ if (strcmp(fn, "-") == 0)
+ cksumfile(STDIN_FILENO, "stdin");
+ else
+ if ((fd = open(fn, O_RDONLY)) == -1)
+ error(fn);
+ else
+ {
+ cksumfile(fd, fn);
+ if (close(fd) == -1)
+ error(fn);
+ }
+ }
+ }
+
+ if (! hasrun)
+ cksumfile(STDIN_FILENO, "stdin");
+
+ return(exitstatus);
+}
+
+
+void cksumfile(int fd, char *fn)
+{
+ unsigned char buf[BUFSIZE];
+ ssize_t cnt, n;
+ uint32_t crctab[256], crc, i;
+ int j;
+
+ for (i = 0; i < 256; ++i)
+ {
+ for (crc = i << 24, j = 0; j < 8; j++)
+ crc = (crc << 1) ^ (crc & 0x80000000 ? 0x04c11db7 : 0);
+ crctab[i] = crc;
+ }
+
+ cnt = crc = 0;
+
+ while ((n = read(fd, buf, BUFSIZE)) > 0)
+ {
+ cnt += n;
+
+ for (i = 0; i < (size_t)n; i++)
+ crc = crctab[((crc >> 24) ^ buf[i]) & 0xFF] ^ (crc << 8);
+ }
+
+ if (n < 0)
+ error(fn);
+ else
+ {
+ for (i = cnt; i != 0; i >>= 8)
+ crc = crctab[((crc >> 24) ^ i) & 0xFF] ^ (crc << 8);
+
+ printf("%lu %lu", (unsigned long)~crc, (unsigned long)cnt);
+ if (fd != STDIN_FILENO)
+ printf(" %s", fn);
+ printf("\n");
+ }
+}
+
+
+void error(char *s)
+{
+ fprintf(stderr, "cksum: %s: %s\n", s, strerror(errno));
+ exitstatus = 1;
+}
--- /dev/null
+.TH CMP 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+cmp \- compare two files
+.SH SYNOPSIS
+.B cmp
+[-l|-s] file1 file2
+.SH DESCRIPTION
+Compare two files. If the contents are the same, produce no output and return
+an exit status of 0. If they differ, report the line and byte position of the
+first difference, and return an exit status of 1. An exit status of 2 will be
+returned in the event of any error.
+.SH OPTIONS
+.TP
+-l
+List all differences, not just the first.
+.TP
+-s
+Silent. No output under any circumstances; returns exit status only.
+.P
+Note that options -l and -s are mutually exclusive.
+.SH OPERANDS
+.TP
+file1, file2
+Input files. If none provided, or the filename '-' is passed to cmp, standard
+input will be used. Note that standard input may only be used for one of the
+file inputs.
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/cmp.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * cmp.c - compare two files
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o cmp cmp.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/cmp.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define USAGE "usage: cmp [-l|-s] file1 file2\n"
+#define ELSMUTEXCL "Options -l and -s are mutually exclusive"
+#define EBOTHSTDIN "Input files must be different"
+#define BUFSIZE 4096
+#define SYSERR 1
+#define APPERR 0
+
+static int cmpfiles(int fd1, char *fn1, int fd2, char *fn2);
+static void fatal(int errtype, char *s);
+
+static int optl, opts;
+
+
+int main(int argc, char **argv)
+{
+ extern int opterr, optind;
+ int c, exitstatus = 0;
+ int fd1, fd2;
+ char *fn1, *fn2;
+
+ setlocale(LC_ALL, "");
+ opterr = 0;
+
+ while ((c = getopt(argc, argv, "ls")) != -1)
+ switch (c)
+ {
+ case 'l':
+ optl = 1;
+ break;
+ case 's':
+ opts = 1;
+ break;
+ default:
+ fprintf(stderr, USAGE);
+ exit(2);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (optl && opts)
+ fatal(APPERR, ELSMUTEXCL);
+
+ if (argc != 2)
+ fatal(APPERR, USAGE);
+
+ fn1 = argv[0];
+ if (strcmp(fn1, "-") == 0)
+ fd1 = STDIN_FILENO;
+ else
+ if ((fd1 = open(fn1, O_RDONLY)) == -1)
+ fatal(SYSERR, fn1);
+
+ fn2 = argv[1];
+ if (strcmp(fn2, "-") == 0)
+ fd2 = STDIN_FILENO;
+ else
+ if ((fd2 = open(fn2, O_RDONLY)) == -1)
+ fatal(SYSERR, fn2);
+
+ if (fd1 == STDIN_FILENO && fd2 == STDIN_FILENO)
+ fatal(APPERR, EBOTHSTDIN);
+
+ exitstatus = cmpfiles(fd1, fn1, fd2, fn2);
+
+ if (fd1 != STDIN_FILENO && (close(fd1) == -1))
+ fatal(SYSERR, fn1);
+
+ if (fd2 != STDIN_FILENO && (close(fd2) == -1))
+ fatal(SYSERR, fn2);
+
+ return(exitstatus);
+}
+
+
+int cmpfiles(int fd1, char *fn1, int fd2, char *fn2)
+{
+ unsigned char buf1[BUFSIZE], buf2[BUFSIZE];
+ ssize_t n1, n2, byte = 1, line = 1;
+ int cnt, i, eof = 0, differ = 0, shorter = 0;
+
+ while (! eof)
+ {
+ if ((n1 = read(fd1, buf1, BUFSIZE)) == -1)
+ fatal(SYSERR, fn1);
+
+ if ((n2 = read(fd2, buf2, BUFSIZE)) == -1)
+ fatal(SYSERR, fn2);
+
+ if (n1 != BUFSIZE || n2 != BUFSIZE)
+ {
+ eof = 1;
+ if (n1 != n2)
+ shorter = (n1 < n2) ? 1 : 2;
+ }
+
+ cnt = (n1 < n2) ? n1 : n2;
+ for (i = 0; i < cnt; i++)
+ {
+ if (buf1[i] != buf2[i])
+ {
+ if (! differ && ! optl && ! opts)
+ {
+ printf("%s %s differ: char %d, line %d\n", fn1, fn2, byte, line);
+ return(1); /* only need to report first mismatch */
+ }
+
+ differ = 1;
+
+ if (optl)
+ printf("%d %o %o\n", byte, buf1[i], buf2[i]);
+ }
+
+ byte++;
+ if (buf1[i] == '\n')
+ line++;
+ }
+ }
+
+ if (shorter && (optl || (! opts && ! differ)))
+ {
+ differ = 1;
+ fprintf(stderr, "cmp: EOF on %s\n", (shorter == 1 ? fn1 : fn2));
+ }
+
+ return(differ || shorter);
+}
+
+
+void fatal(int errtype, char *s)
+{
+ if (errtype == SYSERR)
+ fprintf(stderr, "cmp: %s: %s\n", s, strerror(errno));
+ else
+ fprintf(stderr, "cmp: %s\n", s);
+
+ exit(2);
+}
--- /dev/null
+.TH COMM 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+comm \- select or reject lines common to two files
+.SH SYNOPSIS
+.B comm
+[-123] file1 file2
+.SH DESCRIPTION
+Read 'file1' and 'file2', both of which should be ordered in the current
+collating sequence, and produce three text columns as output: lines unique
+to 'file1', lines unique to 'file2', and lines common to both files.
+.SH OPTIONS
+.TP
+-1
+Suppress output of column one (lines unique to 'file1').
+.TP
+-2
+Suppress output of column two (lines unique to 'file2').
+.TP
+-3
+Suppress output of column three (lines common to both files).
+.P
+.SH OPERANDS
+.TP
+file1, file2
+Input files. If none provided, or the filename '-' is passed to comm,
+standard input will be used.
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/comm.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * comm.c - select or reject lines common to two files
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o comm comm.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/comm.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define USAGE "usage: comm [-123] file1 file2\n"
+#define ENOMALLOC "Unable to allocate memory for read buffer"
+#define BUFSIZE 4096
+#define LINESIZE 64
+#define SYSERR 1
+#define APPERR 0
+
+typedef struct { int fd;
+ char *fn;
+ int eof;
+ char buf[BUFSIZE];
+ size_t bufpos;
+ size_t eobuf;
+ char *line;
+ size_t linesz;
+ } FINFO;
+
+static void initfile(FINFO *file, char *fn);
+static void cleanup(FINFO *file);
+static void commfiles(FINFO *file1, FINFO *file2);
+static int getline(FINFO *file);
+static void fillbuf(FINFO *file);
+static void fatal(int errtype, char *s);
+
+static int opt1, opt2, opt3;
+
+
+int main(int argc, char **argv)
+{
+ extern int optind, opterr;
+ int c;
+ FINFO file1, file2;
+
+ setlocale(LC_ALL, "");
+ opterr = 0;
+
+ while ((c = getopt(argc, argv, "123")) != -1)
+ switch (c)
+ {
+ case '1':
+ opt1 = 1;
+ break;
+ case '2':
+ opt2 = 1;
+ break;
+ case '3':
+ opt3 = 1;
+ break;
+ default:
+ fprintf(stderr, USAGE);
+ exit(1);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2)
+ fatal(APPERR, USAGE);
+
+ initfile(&file1, argv[0]);
+ initfile(&file2, argv[1]);
+
+ commfiles(&file1, &file2);
+
+ cleanup(&file1);
+ cleanup(&file2);
+
+ return(0);
+}
+
+
+void initfile(FINFO *file, char *fn)
+{
+ int fd;
+
+ if (strcmp(fn, "-") == 0)
+ fd = STDIN_FILENO;
+ else
+ if ((fd = open(fn, O_RDONLY)) == -1)
+ fatal(SYSERR, fn);
+
+ file->fd = fd;
+ file->fn = fn;
+ file->eof = 0;
+ file->bufpos = 0;
+ file->eobuf = 0;
+ file->linesz = LINESIZE;
+
+ if ((file->line = malloc(file->linesz)) == NULL)
+ fatal(APPERR, ENOMALLOC);
+}
+
+
+void cleanup(FINFO *file)
+{
+ free(file->line);
+
+ if (strcmp(file->fn, "-") != 0 && close(file->fd) == -1)
+ fatal(SYSERR, file->fn);
+}
+
+
+void commfiles(FINFO *file1, FINFO *file2)
+{
+ int cmp;
+
+ if (getline(file1) && getline(file2))
+ while(1)
+ {
+ cmp = strcoll(file1->line, file2->line);
+
+ if (cmp == 0)
+ {
+ if (! opt3)
+ printf("%s%s%s\n", (opt1 ? "" : "\t"), (opt2 ? "" : "\t"), file1->line);
+
+ if ((getline(file1) + getline(file2)) < 2)
+ break;
+ }
+
+ else if (cmp > 0)
+ {
+ if (! opt2)
+ printf("%s%s\n", (opt1 ? "" : "\t"), file2->line);
+
+ if (! getline(file2))
+ break;
+ }
+
+ else /* cmp < 0 */
+ {
+ if (! opt1)
+ printf("%s\n", file1->line);
+
+ if (! getline(file1))
+ break;
+ }
+ }
+
+ while(! file1->eof && ! opt1)
+ {
+ printf("%s\n", file1->line);
+ getline(file1);
+ }
+
+ while(! file2->eof && ! opt2)
+ {
+ printf("%s%s\n", (opt1 ? "" : "\t"), file2->line);
+ getline(file2);
+ }
+}
+
+
+int getline(FINFO *file)
+{
+ int success = 0;
+ size_t i = 0;
+
+ if (! file->eof)
+ {
+ while(1)
+ {
+ if (i == file->linesz)
+ {
+ file->linesz = file->linesz + LINESIZE;
+ if ((file->line = realloc(file->line, file->linesz)) == NULL)
+ fatal(APPERR, ENOMALLOC);
+ }
+
+ if (file->bufpos >= file->eobuf)
+ {
+ fillbuf(file);
+ if (file->eof)
+ {
+ if (i > 0)
+ {
+ file->line[i] = '\0';
+ success = 1;
+ }
+ break;
+ }
+ }
+
+ if (file->buf[file->bufpos] == '\n')
+ {
+ file->bufpos++;
+ file->line[i] = '\0';
+ success = 1;
+ break;
+ }
+ else
+ file->line[i++] = file->buf[file->bufpos++];
+ }
+ }
+
+ return(success);
+}
+
+
+void fillbuf(FINFO *file)
+{
+ ssize_t n;
+
+ if (! file->eof)
+ {
+ if ((n = read(file->fd, file->buf, BUFSIZE)) < 0)
+ fatal(SYSERR, file->fn);
+
+ if (n == 0)
+ file->eof = 1;
+ else
+ {
+ file->bufpos = 0;
+ file->eobuf = n;
+ }
+ }
+}
+
+
+void fatal(int errtype, char *s)
+{
+ if (errtype == SYSERR)
+ fprintf(stderr, "comm: %s: %s\n", s, strerror(errno));
+ else
+ fprintf(stderr, "comm: %s\n", s);
+
+ exit(1);
+}
--- /dev/null
+.TH DIRNAME 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+dirname \- return the directory portion of a pathname
+.SH SYNOPSIS
+.B dirname
+string
+.SH DESCRIPTION
+Return the directory portion of a path/filename string.
+.SH OPTIONS
+.TP
+None
+.SH OPERANDS
+.TP
+string
+Input pathname
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/dirname.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * dirname.c - return the directory portion of a pathname
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o dirname dirname.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/dirname.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+#include <locale.h>
+#include <stdio.h>
+
+#define USAGE "usage: dirname string\n"
+
+
+int main(int argc, char **argv)
+{
+ char *head, *tail;
+
+ setlocale (LC_ALL, "");
+
+ if (argc != 2)
+ {
+ fprintf(stderr, USAGE);
+ return(1);
+ }
+
+ head = tail = argv[1];
+ while (*tail)
+ tail++;
+
+ while (tail > head && tail[-1] == '/')
+ tail--;
+ while (tail > head && tail[-1] != '/')
+ tail--;
+ while (tail > head && tail[-1] == '/')
+ tail--;
+
+ if (head == tail)
+ printf(*head == '/' ? "/\n" : ".\n");
+ else
+ printf("%.*s\n", (tail - head), head);
+
+ return(0);
+}
--- /dev/null
+.TH FALSE 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+false \- return false value
+.SH SYNOPSIS
+.B true
+.SH DESCRIPTION
+Return with a non-zero exit status.
+.SH OPTIONS
+.TP
+None
+.SH OPERANDS
+.TP
+None
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/false.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * false.c - return false value
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o false false.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/false.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+
+int main(void)
+{
+ return(1);
+}
--- /dev/null
+.TH HEAD 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+head \- copy the first part of files
+.SH SYNOPSIS
+.B head
+[-n number] [file ...]
+.SH DESCRIPTION
+Copy the first 'number' lines of the input files to standard output.
+.SH OPTIONS
+.TP
+-n number
+Where 'number' is a positive integer indicating the number of lines to copy.
+If omitted, head will default to copying the first 10 lines of input.
+.SH OPERANDS
+.TP
+file
+Input file(s). If none provided, or the filename '-' is passed to head,
+standard input will be used.
+.SH NOTES
+Prior versions of head allowed '-x' as an option, with 'x' representing
+the number of lines to be copied. The equivalent acceptable syntax is
+now '-n x'.
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/head.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * head.c - copy the first part of files
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o head head.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/head.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define USAGE "usage: head [-n number] [file ...]\n"
+#define BUFSIZE 4096
+
+static long ctol(char *s);
+static void headfile(int fd, char *fn, int lines);
+static void error(char *s);
+
+static int exitstatus;
+
+
+int main(int argc, char **argv)
+{
+ extern int opterr, optind;
+ extern char *optarg;
+ int c, fd, many, first;
+ char *fn;
+ long lines = 10;
+
+ setlocale(LC_ALL, "");
+ opterr = 0;
+
+ while ((c = getopt(argc, argv, "n:")) != -1)
+ switch (c)
+ {
+ case 'n':
+ if (*optarg && (lines = ctol(optarg)) > 0)
+ break;
+ /* else fall through */
+ default:
+ fprintf(stderr, USAGE);
+ exit(1);
+ }
+
+ if (optind >= argc)
+ headfile(STDIN_FILENO, "stdin", lines);
+ else
+ {
+ many = (optind + 1 < argc) ? 1 : 0;
+ first = 1;
+
+ while (optind < argc)
+ {
+ fn = argv[optind++];
+
+ if (many)
+ {
+ if (first)
+ first = 0;
+ else
+ printf("\n");
+ printf("==> %s <==\n", fn);
+ }
+
+ if (strcmp(fn, "-") == 0)
+ headfile(STDIN_FILENO, "stdin", lines);
+ else
+ if ((fd = open(fn, O_RDONLY)) == -1)
+ error(fn);
+ else
+ {
+ headfile(fd, fn, lines);
+ if (close(fd) == -1)
+ error(fn);
+ }
+ }
+ }
+
+ return(exitstatus);
+}
+
+
+long ctol(char *s)
+{
+ int badch = 0;
+ char *c = s;
+
+ /* only copes with non-zero, optionally signed, */
+ /* decimal integers; that's all we need */
+ if (! (isdigit(*c) || *c == '+' || *c == '-'))
+ badch = 1;
+ else
+ for (c++; *c; c++)
+ if (! isdigit(*c))
+ badch = 1;
+
+ return (badch ? 0 : atol(s));
+}
+
+
+void headfile(int fd, char *fn, int lines)
+{
+ unsigned char buf[BUFSIZE], *c;
+ ssize_t n, o;
+
+ while (lines)
+ {
+ if ((n = read(fd, buf, BUFSIZE)) <= 0)
+ break;
+
+ for (c = buf; lines && c < (buf + n); c++)
+ if (*c == '\n')
+ lines--;
+
+ o = lines ? n : c - buf;
+ if (write(STDOUT_FILENO, buf, (size_t)o) != o)
+ {
+ error("stdout");
+ break;
+ }
+ }
+
+ if (n < 0)
+ error(fn);
+}
+
+
+void error(char *s)
+{
+ fprintf(stderr, "head: %s: %s\n", s, strerror(errno));
+ exitstatus = 1;
+}
--- /dev/null
+.TH TAIL 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+tail \- copy the last part of a file
+.SH SYNOPSIS
+.B tail
+[-f] [-c number | -n number] [file]
+.SH DESCRIPTION
+Copy the input file to standard output, starting from a specified location.
+.SH OPTIONS
+.TP
+-f
+Follow the file; keep updating tail's output as the input file grows. Note that
+this option is only available for regular files and FIFOs that are named as
+the 'file' operand, and will be ignored for other inputs (such as unnamed
+pipes).
+.TP
+-c number
+Byte offset of the input file at which output will commence.
+.TP
+-n number
+Line offset of the input file at which output will commence.
+.P
+Byte and line offsets commence at the value 1. If 'number' includes a
+leading '+', the offset is from the start of the input file. If 'number'
+includes a leading '-' or has no prefix, it indicates that the desired
+offset is backwards from the end of the input file.
+.P
+For example, '-n +3' will output the contents of the input file commencing from
+the third line; '-c 20' or '-c -20' starts output twenty bytes prior to the end
+of the input file.
+.P
+For byte offsets, a 'number' value of zero is not permitted. For line offsets,
+the POSIX standard states that the option '-n 0' is valid, but outputs nothing,
+whilst '-n +0' is invalid.
+.P
+Options '-c' and '-n' are mutually exclusive. If neither is specified,
+the default behaviour of tail is to output the last ten lines of the input
+file, as if it had been invoked with the option '-n 10'.
+.SH OPERANDS
+.TP
+file
+Input file. If none provided, or the filename '-' is passed to tail,
+standard input will be used.
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/tail.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * tail.c - copy the last part of a file
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o tail tail.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/tail.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define USAGE "usage: tail [-f] [-c number] [-n number] [file]\n"
+#define NOMALLOC "Unable to allocate memory for read buffer"
+#define NOFOLLOW "tail: Option [-f] ignored; can only follow regular files and FIFOs\n"
+#define BADBYTES "Option [-c] requires non-zero byte offset"
+#define BADLINES "Option [-n] requires integer line offset"
+#define CNMUTEXCL "Options [-c] and [-n] are mutually exclusive"
+#define FVANISH "Followed file has vanished"
+#define FSHRUNK "Followed file has shrunk"
+#define SYSERR 1
+#define APPERR 0
+
+static int isdecint(char *s);
+static void tailfile(int fd, char *fn);
+static void tailbyteoffset(int fd, char *fn, int isregfile, ssize_t len);
+static void taillineoffset(int fd, char *fn, int isregfile, ssize_t len);
+static void copytoeof(int fd, char *fn);
+static void fatal(int errtype, char *s);
+
+static unsigned char* buf;
+static ssize_t bufsize, offset;
+static int optf, optc, optn;
+
+
+int main(int argc, char **argv)
+{
+ extern int opterr, optind;
+ extern char *optarg;
+ int c, fd;
+ char *fn;
+
+ setlocale(LC_ALL, "");
+ opterr = 0;
+
+ /*
+ * try to get a buffer _twice_ the size mandated by the standard as in
+ * later processing we may be paging through the file in _half_ buffer
+ * increments; this way we guarentee POSIX buffer size conformance
+ */
+ bufsize = sysconf(_SC_LINE_MAX) * 20; /* POSIX says [{LINE_MAX)*10] */
+ bufsize = bufsize < 4096 ? 4096 : bufsize;
+
+ if ((buf = malloc(bufsize)) == NULL)
+ fatal(APPERR, NOMALLOC);
+
+ while ((c = getopt(argc, argv, "fc:n:")) != -1)
+ switch (c)
+ {
+ case 'f': /* follow file */
+ optf = 1;
+ break;
+
+ case 'c': /* offset in bytes */
+ optc = 1;
+ offset = 0;
+ if (*optarg && isdecint(optarg))
+ {
+ offset = atol(optarg);
+ offset = isdigit(*optarg) ? -offset : offset;
+ }
+
+ if (offset == 0)
+ fatal(APPERR, BADBYTES);
+ else
+ break;
+
+ case 'n': /* offset in lines */
+ optn = 1;
+ if (*optarg && isdecint(optarg))
+ {
+ offset = atol(optarg);
+ offset = isdigit(*optarg) ? -offset : offset;
+
+ /* the standard says [-n 0] is OK, but [-n +0] isn't &_& */
+ if (offset != 0 || (offset == 0 && *optarg != '+'))
+ break;
+ }
+ fatal(APPERR, BADLINES);
+
+ default:
+ fprintf(stderr, USAGE);
+ exit(1);
+ }
+
+ if (! optc && ! optn) /* if none, set the default options */
+ {
+ optn = 1;
+ offset = -10;
+ }
+
+ if (optc && optn)
+ fatal(APPERR, CNMUTEXCL);
+
+ if (optind >= argc)
+ tailfile(STDIN_FILENO, "stdin");
+ else
+ {
+ fn = argv[optind++];
+
+ if (strcmp(fn, "-") == 0)
+ tailfile(STDIN_FILENO, "stdin");
+ else
+ if ((fd = open(fn, O_RDONLY)) == -1)
+ fatal(SYSERR, fn);
+ else
+ {
+ tailfile(fd, fn);
+ if (close(fd) == -1)
+ fatal(SYSERR, fn);
+ }
+ }
+
+ return(0);
+}
+
+
+int isdecint(char *s)
+{
+ int badch = 0;
+ char *c = s;
+
+ if (! (isdigit(*c) || *c == '+' || *c == '-'))
+ badch = 1;
+ else
+ for (c++; *c; c++)
+ if (! isdigit(*c))
+ badch = 1;
+
+ return (! badch);
+}
+
+
+void tailfile(int fd, char *fn)
+{
+ struct stat sbuf;
+ int isregfile;
+ ssize_t n, len;
+
+ if (fstat(fd, &sbuf) == -1)
+ fatal(SYSERR, fn);
+
+ if (S_ISREG(sbuf.st_mode))
+ {
+ isregfile = 1;
+ len = sbuf.st_size;
+ }
+ else
+ isregfile = len = 0;
+
+ if (offset != 0) /* [-n 0] is permitted; but no point processing that */
+ {
+ if (optc)
+ tailbyteoffset(fd, fn, isregfile, len);
+ else
+ taillineoffset(fd, fn, isregfile, len);
+ }
+
+ if (optf)
+ {
+ if (fd == STDIN_FILENO) /* can't follow; warn then exit no error */
+ {
+ fprintf(stderr, NOFOLLOW);
+ exit(0);
+ }
+
+ while(1) /* follow forever */
+ {
+ sleep(1);
+
+ if (isregfile) /* if we can, be polite to the user */
+ {
+ if (stat(fn, &sbuf) == -1)
+ fatal(APPERR, FVANISH);
+ else if (sbuf.st_size < len)
+ fatal(APPERR, FSHRUNK);
+
+ len = sbuf.st_size;
+ }
+
+ while ((n = read(fd, buf, bufsize)) > 0)
+ if (write(STDOUT_FILENO, buf, n) != n)
+ fatal(SYSERR, "stdout");
+
+ if (n < 0)
+ fatal(SYSERR, fn);
+ }
+ }
+}
+
+
+void tailbyteoffset(int fd, char *fn, int isregfile, ssize_t len)
+{
+ ssize_t n, halfbuf;
+
+ if (isregfile) /* should be seekable, so we'll do so; it's fastest */
+ {
+ if (offset > 0)
+ offset = (offset - 1) > len ? len : offset - 1;
+ else
+ offset = (len + offset) > 0 ? len + offset : 0;
+
+ if (lseek(fd, (off_t)offset, SEEK_SET) == (off_t)-1)
+ fatal(SYSERR, fn);
+
+ copytoeof(fd, fn);
+ }
+
+ else /* possibly non-seekable */
+ {
+ if (offset > 0) /* forwards through file */
+ {
+ offset--;
+
+ while(1)
+ {
+ if ((n = read(fd, buf, bufsize)) < 0)
+ fatal(SYSERR, fn);
+
+ if (n == 0)
+ offset = 0;
+
+ if (offset <= n)
+ break;
+ else
+ offset -= n;
+ }
+
+ if (write(STDOUT_FILENO, buf + offset, n - offset) != n - offset)
+ fatal(SYSERR, "stdout");
+
+ copytoeof(fd, fn);
+ }
+
+ else /* backwards through file; remember that offset is negative */
+ {
+ halfbuf = bufsize / 2;
+
+ if ((n = read(fd, buf, bufsize)) < 0)
+ fatal(SYSERR, fn);
+
+ if (n < bufsize) /* we've got the whole file */
+ {
+ offset = (n + offset) < 0 ? 0 : n + offset;
+ len = n - offset;
+ }
+
+ else /* we haven't got the whole file */
+ {
+ while(1) /* page through the file, half a buffer at a time */
+ {
+ memcpy(buf, buf + halfbuf, halfbuf);
+
+ if ((n = read(fd, buf + halfbuf, halfbuf)) < 0)
+ fatal(SYSERR, fn);
+ else if (n < halfbuf)
+ break;
+ }
+
+ offset = (halfbuf + n + offset) < 0 ? 0 : halfbuf + n + offset;
+ len = halfbuf + n - offset;
+ }
+
+ if (write(STDOUT_FILENO, buf + offset, len) != len)
+ fatal(SYSERR, "stdout");
+ }
+ }
+}
+
+
+void taillineoffset(int fd, char *fn, int isregfile, ssize_t len)
+{
+ ssize_t n, i, halfbuf;
+
+ if (offset > 0) /* forwards through file */
+ {
+ offset--;
+
+ while(1)
+ {
+ if ((n = read(fd, buf, bufsize)) < 0)
+ fatal(SYSERR, fn);
+
+ if (n == 0)
+ {
+ offset = 0;
+ break;
+ }
+
+ for (i = 0; i < n && offset > 0; i++)
+ if (buf[i] == '\n')
+ offset--;
+
+ if (offset == 0)
+ {
+ offset = i;
+ break;
+ }
+ }
+
+ if (write(STDOUT_FILENO, buf + offset, n - offset) != n - offset)
+ fatal(SYSERR, "stdout");
+
+ copytoeof(fd, fn);
+ }
+
+ else /* backwards through file; remember that offset is negative */
+ {
+ if (isregfile && len > 0) /* should be seekable, so we'll do so */
+ {
+ n = (len - bufsize) < 0 ? 0 : len - bufsize;
+
+ if (lseek(fd, (off_t)n, SEEK_SET) == (off_t)-1)
+ fatal(SYSERR, fn);
+
+ if ((n = read(fd, buf, bufsize)) < 0)
+ fatal(SYSERR, fn);
+
+ if (buf[n-1] == '\n')
+ offset--;
+
+ for (i = n - 1; i >= 0 && offset < 0; i--)
+ if (buf[i] == '\n')
+ offset++;
+
+ if (offset == 0)
+ offset = i + 2;
+ else
+ offset = 0;
+
+ len = n - offset;
+
+ if (write(STDOUT_FILENO, buf + offset, len) != len)
+ fatal(SYSERR, "stdout");
+ }
+
+ else
+ {
+ halfbuf = bufsize / 2;
+
+ if ((n = read(fd, buf, bufsize)) < 0)
+ fatal(SYSERR, fn);
+
+ if (n < bufsize) /* we've got the whole file */
+ {
+ if (n == 0)
+ offset = 0;
+ else
+ {
+ if (buf[n-1] == '\n')
+ offset--;
+
+ for (i = n - 1; i >= 0 && offset < 0; i--)
+ if (buf[i] == '\n')
+ offset++;
+
+ if (offset == 0)
+ offset = i + 2;
+ else
+ offset = 0;
+ }
+
+ len = n - offset;
+ }
+
+ else /* we haven't got the whole file */
+ {
+ while(1) /* page through the file, half a buffer at a time */
+ {
+ memcpy(buf, buf + halfbuf, halfbuf);
+
+ if ((n = read(fd, buf + halfbuf, halfbuf)) < 0)
+ fatal(SYSERR, fn);
+ else if (n < halfbuf)
+ break;
+ }
+
+ if (buf[halfbuf+n-1] == '\n')
+ offset--;
+
+ for (i = halfbuf + n - 1; i >= 0 && offset < 0; i--)
+ if (buf[i] == '\n')
+ offset++;
+
+ if (offset == 0)
+ offset = i + 2;
+ else
+ offset = 0;
+
+ len = halfbuf + n - offset;
+ }
+
+ if (write(STDOUT_FILENO, buf + offset, len) != len)
+ fatal(SYSERR, "stdout");
+ }
+ }
+}
+
+
+void copytoeof(int fd, char *fn)
+{
+ ssize_t n;
+
+ while ((n = read(fd, buf, bufsize)) > 0)
+ if (write(STDOUT_FILENO, buf, n) != n)
+ fatal(SYSERR, "stdout");
+
+ if (n < 0)
+ fatal(SYSERR, fn);
+}
+
+
+void fatal(int errtype, char *s)
+{
+ if (errtype == SYSERR)
+ fprintf(stderr, "tail: %s: %s\n", s, strerror(errno));
+ else
+ fprintf(stderr, "tail: %s\n", s);
+
+ exit(1);
+}
--- /dev/null
+.TH TEE 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+tee \- duplicate standard input
+.SH SYNOPSIS
+.B tee
+[-ai] [file ...]
+.SH DESCRIPTION
+Copy standard input to standard output and any other named files.
+.SH OPTIONS
+.TP
+-a
+Append output to existing files rather than overwriting them.
+.TP
+-i
+Ignore the SIGINT signal.
+.SH OPERANDS
+.TP
+file
+File(s) to duplicate standard input into.
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/tee.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * tee.c - duplicate standard input
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o tee tee.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/tee.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define USAGE "usage: tee [-ai] [file ...]\n"
+#define AMBIGOPT "tee: Ambiguous [-]; operand or bad option?\n"
+#define FLIMIT "tee: Maximum of %d output files exceeded\n"
+#define BUFSIZE 4096
+#define MAXFILES 13
+
+static void error(char *s);
+
+static int exitstatus;
+
+
+int main(int argc, char **argv)
+{
+ extern int opterr, optind;
+ int c, i;
+ unsigned char buf[BUFSIZE];
+ ssize_t n;
+ int slot, fdfn[MAXFILES + 1][2], mode = O_WRONLY | O_CREAT | O_TRUNC;
+
+ setlocale(LC_ALL, "");
+ opterr = 0;
+
+ while ((c = getopt(argc, argv, "ai")) != -1)
+ switch (c)
+ {
+ case 'a': /* append to rather than overwrite file(s) */
+ mode = O_WRONLY | O_CREAT | O_APPEND;
+ break;
+
+ case 'i': /* ignore the SIGINT signal */
+ signal(SIGINT, SIG_IGN);
+ break;
+
+ default:
+ fprintf(stderr, USAGE);
+ return(1);
+ }
+
+ i = optind;
+ fdfn[0][0] = STDOUT_FILENO;
+
+ for (slot = 1; i < argc ; i++)
+ {
+ if (slot > MAXFILES)
+ fprintf(stderr, FLIMIT, MAXFILES);
+ else
+ {
+ if ((fdfn[slot][0] = open(argv[i], mode, 0666)) == -1)
+ error(argv[i]);
+ else
+ fdfn[slot++][1] = i;
+ }
+ }
+
+ while ((n = read(STDIN_FILENO, buf, BUFSIZE)) > 0)
+ {
+ for (i = 0; i < slot; i++)
+ if (write(fdfn[i][0], buf, (size_t)n) != n)
+ error(argv[fdfn[i][1]]);
+ }
+
+ if (n < 0)
+ error("stdin");
+
+ for (i = 1; i < slot; i++)
+ if (close(fdfn[i][0]) == -1)
+ error(argv[fdfn[i][1]]);
+
+ return(exitstatus);
+}
+
+
+void error(char *s)
+{
+ fprintf(stderr, "tee: %s: %s\n", s, strerror(errno));
+ exitstatus = 1;
+}
--- /dev/null
+.TH TRUE 1 "2008-1.01" "pdcore utilities" "User Commands"
+.SH NAME
+true \- return true value
+.SH SYNOPSIS
+.B true
+.SH DESCRIPTION
+Return with an exit status of zero.
+.SH OPTIONS
+.TP
+None
+.SH OPERANDS
+.TP
+None
+.SH "AUTHORITATIVE DOCUMENTATION"
+<http://www.opengroup.org/onlinepubs/9699919799/utilities/true.html>
+.SH VERSION AND COMPLIANCE
+Utility version 1.01
+.P
+Functional compliance with POSIX:2008 (IEEE Std 1003.1-2008;
+Shell and Utilities, Base Specifications Issue 7).
+.SH UNLICENSE
+This is free and unencumbered software released into the public domain,
+provided "as is", without warranty of any kind, express or implied. See the
+file UNLICENSE and the website <http://unlicense.org> for further details.
--- /dev/null
+/*
+ * true.c - return true value
+ *
+ * Version: 2008-1.01
+ * Build: c89 -o true true.c
+ * Source: <http://pdcore.sourceforge.net/>
+ * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/true.html>
+ *
+ * This is free and unencumbered software released into the public domain,
+ * provided "as is", without warranty of any kind, express or implied. See the
+ * file UNLICENSE and the website <http://unlicense.org> for further details.
+ */
+
+
+#define _POSIX_SOURCE
+
+
+int main(void)
+{
+ return(0);
+}