Initial Spring 2016 commit.

This commit is contained in:
Geoffrey Challen
2015-12-23 00:50:04 +00:00
commit cafa9f5690
732 changed files with 92195 additions and 0 deletions

10
userland/bin/Makefile Normal file
View File

@@ -0,0 +1,10 @@
#
# Makefile for src/bin (sources for programs installed in /bin)
#
TOP=../..
.include "$(TOP)/mk/os161.config.mk"
SUBDIRS=true false sync mkdir rmdir pwd cat cp ln mv rm ls sh tac
.include "$(TOP)/mk/os161.subdir.mk"

12
userland/bin/cat/Makefile Normal file
View File

@@ -0,0 +1,12 @@
# Makefile for cat
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=cat
SRCS=cat.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

120
userland/bin/cat/cat.c Normal file
View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <string.h>
#include <err.h>
/*
* cat - concatenate and print
* Usage: cat [files]
*/
/* Print a file that's already been opened. */
static
void
docat(const char *name, int fd)
{
char buf[1024];
int len, wr, wrtot;
/*
* As long as we get more than zero bytes, we haven't hit EOF.
* Zero means EOF. Less than zero means an error occurred.
* We may read less than we asked for, though, in various cases
* for various reasons.
*/
while ((len = read(fd, buf, sizeof(buf)))>0) {
/*
* Likewise, we may actually write less than we attempted
* to. So loop until we're done.
*/
wrtot = 0;
while (wrtot < len) {
wr = write(STDOUT_FILENO, buf+wrtot, len-wrtot);
if (wr<0) {
err(1, "stdout");
}
wrtot += wr;
}
}
/*
* If we got a read error, print it and exit.
*/
if (len<0) {
err(1, "%s", name);
}
}
/* Print a file by name. */
static
void
cat(const char *file)
{
int fd;
/*
* "-" means print stdin.
*/
if (!strcmp(file, "-")) {
docat("stdin", STDIN_FILENO);
return;
}
/*
* Open the file, print it, and close it.
* Bail out if we can't open it.
*/
fd = open(file, O_RDONLY);
if (fd<0) {
err(1, "%s", file);
}
docat(file, fd);
close(fd);
}
int
main(int argc, char *argv[])
{
if (argc==1) {
/* No args - just do stdin */
docat("stdin", STDIN_FILENO);
}
else {
/* Print all the files specified on the command line. */
int i;
for (i=1; i<argc; i++) {
cat(argv[i]);
}
}
return 0;
}

12
userland/bin/cp/Makefile Normal file
View File

@@ -0,0 +1,12 @@
# Makefile for cp
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=cp
SRCS=cp.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

113
userland/bin/cp/cp.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <err.h>
/*
* cp - copy a file.
* Usage: cp oldfile newfile
*/
/* Copy one file to another. */
static
void
copy(const char *from, const char *to)
{
int fromfd;
int tofd;
char buf[1024];
int len, wr, wrtot;
/*
* Open the files, and give up if they won't open
*/
fromfd = open(from, O_RDONLY);
if (fromfd<0) {
err(1, "%s", from);
}
tofd = open(to, O_WRONLY|O_CREAT|O_TRUNC);
if (tofd<0) {
err(1, "%s", to);
}
/*
* As long as we get more than zero bytes, we haven't hit EOF.
* Zero means EOF. Less than zero means an error occurred.
* We may read less than we asked for, though, in various cases
* for various reasons.
*/
while ((len = read(fromfd, buf, sizeof(buf)))>0) {
/*
* Likewise, we may actually write less than we attempted
* to. So loop until we're done.
*/
wrtot = 0;
while (wrtot < len) {
wr = write(tofd, buf+wrtot, len-wrtot);
if (wr<0) {
err(1, "%s", to);
}
wrtot += wr;
}
}
/*
* If we got a read error, print it and exit.
*/
if (len<0) {
err(1, "%s", from);
}
if (close(fromfd) < 0) {
err(1, "%s: close", from);
}
if (close(tofd) < 0) {
err(1, "%s: close", to);
}
}
int
main(int argc, char *argv[])
{
/*
* Just do it.
*
* We don't allow the Unix model where you can do
* cp file1 file2 file3 destination-directory
*
* although this would be pretty easy to add.
*/
if (argc!=3) {
errx(1, "Usage: cp OLDFILE NEWFILE");
}
copy(argv[1], argv[2]);
return 0;
}

View File

@@ -0,0 +1,12 @@
# Makefile for false
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=false
SRCS=false.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <stdlib.h>
/*
* false - fail.
*
* "All software sucks. Ok, so maybe /bin/true doesn't. But /bin/false
* sure does - it fails all the time."
*/
int
main(void)
{
/* Just exit with a failure code. */
exit(1);
}

12
userland/bin/ln/Makefile Normal file
View File

@@ -0,0 +1,12 @@
# Makefile for ln
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=ln
SRCS=ln.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

93
userland/bin/ln/ln.c Normal file
View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
/*
* ln - hardlink or symlink files
*
* Usage: ln oldfile newfile
* ln -s symlinkcontents symlinkfile
*/
/*
* Create a symlink with filename PATH that contains text TEXT.
* When fed to ls -l, this produces something that looks like
*
* lrwxrwxrwx [stuff] PATH -> TEXT
*/
static
void
dosymlink(const char *text, const char *path)
{
if (symlink(text, path)) {
err(1, "%s", path);
}
}
/*
* Create a hard link such that NEWFILE names the same file as
* OLDFILE. Since it's a hard link, the two names for the file
* are equal; both are the "real" file.
*/
static
void
dohardlink(const char *oldfile, const char *newfile)
{
if (link(oldfile, newfile)) {
err(1, "%s or %s", oldfile, newfile);
exit(1);
}
}
int
main(int argc, char *argv[])
{
/*
* Just do whatever was asked for.
*
* We don't allow the Unix model where you can do
* ln [-s] file1 file2 file3 destination-directory
*/
if (argc==4 && !strcmp(argv[1], "-s")) {
dosymlink(argv[2], argv[3]);
}
else if (argc==3) {
dohardlink(argv[1], argv[2]);
}
else {
warnx("Usage: ln oldfile newfile");
errx(1, " ln -s symlinkcontents symlinkfile\n");
}
return 0;
}

12
userland/bin/ls/Makefile Normal file
View File

@@ -0,0 +1,12 @@
# Makefile for ls
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=ls
SRCS=ls.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

345
userland/bin/ls/ls.c Normal file
View File

@@ -0,0 +1,345 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <err.h>
/*
* ls - list files.
* Usage: ls [-adlRs] [files]
* -a Show files whose names begin with a dot.
* -d Don't list contents of directories specified on the command line.
* -l Long format listing.
* -R Recurse into subdirectories found.
* -s (with -l) Show block counts.
*/
/* Flags for which options we're using. */
static int aopt=0;
static int dopt=0;
static int lopt=0;
static int Ropt=0;
static int sopt=0;
/* Process an option character. */
static
void
option(int ch)
{
switch (ch) {
case 'a': aopt=1; break;
case 'd': dopt=1; break;
case 'l': lopt=1; break;
case 'R': Ropt=1; break;
case 's': sopt=1; break;
default:
errx(1, "Unknown option -%c", ch);
}
}
/*
* Utility function to find the non-directory part of a pathname.
*/
static
const char *
basename(const char *path)
{
const char *s;
s = strrchr(path, '/');
if (s) {
return s+1;
}
return path;
}
/*
* Utility function to check if a name refers to a directory.
*/
static
int
isdir(const char *path)
{
struct stat buf;
int fd;
/* Assume stat() may not be implemented; use fstat */
fd = open(path, O_RDONLY);
if (fd<0) {
err(1, "%s", path);
}
if (fstat(fd, &buf)<0) {
err(1, "%s: fstat", path);
}
close(fd);
return S_ISDIR(buf.st_mode);
}
/*
* When listing one of several subdirectories, show the name of the
* directory.
*/
static
void
printheader(const char *file)
{
/* No blank line before the first header */
static int first=1;
if (first) {
first = 0;
}
else {
printf("\n");
}
printf("%s:\n", file);
}
/*
* Show a single file.
* We don't do the neat multicolumn listing that Unix ls does.
*/
static
void
print(const char *path)
{
struct stat statbuf;
const char *file;
int typech;
if (lopt || sopt) {
int fd;
fd = open(path, O_RDONLY);
if (fd<0) {
err(1, "%s", path);
}
if (fstat(fd, &statbuf)<0) {
err(1, "%s: fstat", path);
}
close(fd);
}
file = basename(path);
if (sopt) {
printf("%3d ", statbuf.st_blocks);
}
if (lopt) {
if (S_ISREG(statbuf.st_mode)) {
typech = '-';
}
else if (S_ISDIR(statbuf.st_mode)) {
typech = 'd';
}
else if (S_ISLNK(statbuf.st_mode)) {
typech = 'l';
}
else if (S_ISCHR(statbuf.st_mode)) {
typech = 'c';
}
else if (S_ISBLK(statbuf.st_mode)) {
typech = 'b';
}
else {
typech = '?';
}
printf("%crwx------ %2d root %-8llu",
typech,
statbuf.st_nlink,
statbuf.st_size);
}
printf("%s\n", file);
}
/*
* List a directory.
*/
static
void
listdir(const char *path, int showheader)
{
int fd;
char buf[1024];
char newpath[1024];
ssize_t len;
if (showheader) {
printheader(path);
}
/*
* Open it.
*/
fd = open(path, O_RDONLY);
if (fd<0) {
err(1, "%s", path);
}
/*
* List the directory.
*/
while ((len = getdirentry(fd, buf, sizeof(buf)-1)) > 0) {
buf[len] = 0;
/* Assemble the full name of the new item */
snprintf(newpath, sizeof(newpath), "%s/%s", path, buf);
if (aopt || buf[0]!='.') {
/* Print it */
print(newpath);
}
}
if (len<0) {
err(1, "%s: getdirentry", path);
}
/* Done */
close(fd);
}
static
void
recursedir(const char *path)
{
int fd;
char buf[1024];
char newpath[1024];
int len;
/*
* Open it.
*/
fd = open(path, O_RDONLY);
if (fd<0) {
err(1, "%s", path);
}
/*
* List the directory.
*/
while ((len = getdirentry(fd, buf, sizeof(buf)-1)) > 0) {
buf[len] = 0;
/* Assemble the full name of the new item */
snprintf(newpath, sizeof(newpath), "%s/%s", path, buf);
if (!aopt && buf[0]=='.') {
/* skip this one */
continue;
}
if (!strcmp(buf, ".") || !strcmp(buf, "..")) {
/* always skip these */
continue;
}
if (!isdir(newpath)) {
continue;
}
listdir(newpath, 1 /*showheader*/);
if (Ropt) {
recursedir(newpath);
}
}
if (len<0) {
err(1, "%s", path);
}
close(fd);
}
static
void
listitem(const char *path, int showheader)
{
if (!dopt && isdir(path)) {
listdir(path, showheader || Ropt);
if (Ropt) {
recursedir(path);
}
}
else {
print(path);
}
}
int
main(int argc, char *argv[])
{
int i,j, items=0;
/*
* Go through the arguments and count how many non-option args.
*/
for (i=1; i<argc; i++) {
if (argv[i][0]!='-') {
items++;
}
}
/*
* Now go through the options for real, processing them.
*/
for (i=1; i<argc; i++) {
if (argv[i][0]=='-') {
/*
* This word is an option.
* Process all the option characters in it.
*/
for (j=1; argv[i][j]; j++) {
option(argv[i][j]);
}
}
else {
/*
* This word isn't an option; list it.
*/
listitem(argv[i], items>1);
}
}
/*
* If no filenames were specified to list, list the current
* directory.
*/
if (items==0) {
listitem(".", 0);
}
return 0;
}

View File

@@ -0,0 +1,12 @@
# Makefile for mkdir
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=mkdir
SRCS=mkdir.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <err.h>
/*
* mkdir - create a directory.
* Usage: mkdir DIRECTORY
*
* Just calls the mkdir() system call.
*/
int
main(int argc, char *argv[])
{
if (argc!=2) {
errx(1, "Usage: mkdir DIRECTORY");
}
if (mkdir(argv[1], 0775)) {
err(1, "%s", argv[1]);
}
return 0;
}

12
userland/bin/mv/Makefile Normal file
View File

@@ -0,0 +1,12 @@
# Makefile for mv
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=mv
SRCS=mv.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

64
userland/bin/mv/mv.c Normal file
View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <err.h>
/*
* mv - move (rename) files.
* Usage: mv oldfile newfile
*
* Just calls rename() on them. If it fails, we don't attempt to
* figure out which filename was wrong or what happened.
*
* In certain circumstances, Unix mv will fall back to copying and
* deleting the old copy. We don't do that.
*
* We also don't allow the Unix form of
* mv file1 file2 file3 destination-dir
*/
static
void
dorename(const char *oldfile, const char *newfile)
{
if (rename(oldfile, newfile)) {
err(1, "%s or %s", oldfile, newfile);
}
}
int
main(int argc, char *argv[])
{
if (argc!=3) {
errx(1, "Usage: mv oldfile newfile");
}
dorename(argv[1], argv[2]);
return 0;
}

12
userland/bin/pwd/Makefile Normal file
View File

@@ -0,0 +1,12 @@
# Makefile for pwd
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=pwd
SRCS=pwd.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

55
userland/bin/pwd/pwd.c Normal file
View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <err.h>
#include <limits.h>
/*
* pwd - print working directory.
* Usage: pwd
*
* Just uses the getcwd library call (which in turn uses the __getcwd
* system call.)
*/
int
main(void)
{
char buf[PATH_MAX+1], *p;
p = getcwd(buf, sizeof(buf));
if (p == NULL) {
err(1, ".");
}
printf("%s\n", buf);
return 0;
}

12
userland/bin/rm/Makefile Normal file
View File

@@ -0,0 +1,12 @@
# Makefile for rm
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=rm
SRCS=rm.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

64
userland/bin/rm/rm.c Normal file
View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <err.h>
/*
* rm - remove (delete) files
* Usage: rm file...
*/
/* Delete a single file. */
static
void
doremove(const char *file)
{
if (remove(file)) {
err(1, "%s", file);
}
}
int
main(int argc, char *argv[])
{
int i;
if (argc<2) {
/* Must have at least one file. */
errx(1, "Usage: rm FILES");
}
/* Just delete everything on the command line. */
for (i=1; i<argc; i++) {
doremove(argv[i]);
}
return 0;
}

View File

@@ -0,0 +1,12 @@
# Makefile for rmdir
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=rmdir
SRCS=rmdir.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <err.h>
/*
* rmdir - remove a directory
* Usage: rmdir DIRECTORY
*
* Just calls the rmdir() system call.
*/
int
main(int argc, char *argv[])
{
if (argc!=2) {
errx(1, "Usage: rmdir DIRECTORY");
}
if (rmdir(argv[1])) {
err(1, "%s", argv[1]);
}
return 0;
}

13
userland/bin/sh/Makefile Normal file
View File

@@ -0,0 +1,13 @@
# Makefile for sh
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=sh
SRCS=sh.c
BINDIR=/bin
HOSTBINDIR=/hostbin
.include "$(TOP)/mk/os161.prog.mk"
#.include "$(TOP)/mk/os161.hostprog.mk"

591
userland/bin/sh/sh.c Normal file
View File

@@ -0,0 +1,591 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* sh - shell
*
* Usage:
* sh
* sh -c command
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <err.h>
#ifdef HOST
#include "hostcompat.h"
#endif
#ifndef NARG_MAX
/* no NARG_MAX on most unixes */
#define NARG_MAX 1024
#endif
/* avoid making this unreasonably large; causes problems under dumbvm */
#define CMDLINE_MAX 4096
/* struct to (portably) hold exit info */
struct exitinfo {
unsigned val:8,
signaled:1,
stopped:1,
coredump:1;
};
/* set to nonzero if __time syscall seems to work */
static int timing = 0;
/* array of backgrounded jobs (allows "foregrounding") */
#define MAXBG 128
static pid_t bgpids[MAXBG];
/*
* can_bg
* just checks for an open slot.
*/
static
int
can_bg(void)
{
int i;
for (i = 0; i < MAXBG; i++) {
if (bgpids[i] == 0) {
return 1;
}
}
return 0;
}
/*
* remember_bg
* sticks the pid in an open slot in the background array. note the assert --
* better check can_bg before calling this.
*/
static
void
remember_bg(pid_t pid)
{
int i;
for (i = 0; i < MAXBG; i++) {
if (bgpids[i] == 0) {
bgpids[i] = pid;
return;
}
}
assert(0);
}
/*
* constructor for exitinfo
*/
static
void
exitinfo_exit(struct exitinfo *ei, int code)
{
ei->val = code;
ei->signaled = 0;
ei->stopped = 0;
ei->coredump = 0;
}
/*
* readstatus
* unpack results from wait
*/
static
void
readstatus(int status, struct exitinfo *ei)
{
if (WIFEXITED(status)) {
ei->val = WEXITSTATUS(status);
ei->signaled = 0;
ei->stopped = 0;
ei->coredump = 0;
}
else if (WIFSIGNALED(status) && WCOREDUMP(status)) {
ei->val = WTERMSIG(status);
ei->signaled = 1;
ei->stopped = 0;
ei->coredump = 1;
}
else if (WIFSIGNALED(status)) {
ei->val = WTERMSIG(status);
ei->signaled = 1;
ei->stopped = 0;
ei->coredump = 0;
}
else if (WIFSTOPPED(status)) {
ei->val = WSTOPSIG(status);
ei->signaled = 0;
ei->stopped = 1;
ei->coredump = 0;
}
else {
printf("Invalid status code %d", status);
ei->val = status;
ei->signaled = 0;
ei->stopped = 0;
ei->coredump = 0;
}
}
/*
* printstatus
* print results from wait
*/
static
void
printstatus(const struct exitinfo *ei, int printexitzero)
{
if (ei->signaled && ei->coredump) {
printf("Signal %d (core dumped)\n", ei->val);
}
else if (ei->signaled) {
printf("Signal %d\n", ei->val);
}
else if (ei->stopped) {
printf("Stopped on signal %d\n", ei->val);
}
else if (printexitzero || ei->val != 0) {
printf("Exit %d\n", ei->val);
}
}
/*
* dowait
* just does a waitpid.
*/
static
void
dowait(pid_t pid)
{
struct exitinfo ei;
int status;
if (waitpid(pid, &status, 0) < 0) {
warn("pid %d", pid);
}
else {
printf("pid %d: ", pid);
readstatus(status, &ei);
printstatus(&ei, 1);
}
}
#ifdef WNOHANG
/*
* dowaitpoll
* like dowait, but uses WNOHANG. returns true if we got something.
*/
static
int
dowaitpoll(pid_t pid)
{
struct exitinfo ei;
pid_t foundpid;
int status;
foundpid = waitpid(pid, &status, WNOHANG);
if (foundpid < 0) {
warn("pid %d", pid);
}
else if (foundpid != 0) {
printf("pid %d: ", pid);
readstatus(status, &ei);
printstatus(&ei, 1);
return 1;
}
return 0;
}
/*
* waitpoll
* poll all background jobs for having exited.
*/
static
void
waitpoll(void)
{
int i;
for (i=0; i < MAXBG; i++) {
if (bgpids[i] != 0) {
if (dowaitpoll(bgpids[i])) {
bgpids[i] = 0;
}
}
}
}
#endif /* WNOHANG */
/*
* wait
* allows the user to "foreground" a process by waiting on it. without ps to
* know the pids, this is a little tough to use with an arg, but without an
* arg it will wait for all the background jobs.
*/
static
void
cmd_wait(int ac, char *av[], struct exitinfo *ei)
{
int i;
pid_t pid;
if (ac == 2) {
pid = atoi(av[1]);
dowait(pid);
for (i = 0; i < MAXBG; i++) {
if (bgpids[i]==pid) {
bgpids[i] = 0;
}
}
exitinfo_exit(ei, 0);
return;
}
else if (ac == 1) {
for (i=0; i < MAXBG; i++) {
if (bgpids[i] != 0) {
dowait(bgpids[i]);
bgpids[i] = 0;
}
}
exitinfo_exit(ei, 0);
return;
}
printf("Usage: wait [pid]\n");
exitinfo_exit(ei, 1);
}
/*
* chdir
* just an interface to the system call. no concept of home directory, so
* require the directory.
*/
static
void
cmd_chdir(int ac, char *av[], struct exitinfo *ei)
{
if (ac == 2) {
if (chdir(av[1])) {
warn("chdir: %s", av[1]);
exitinfo_exit(ei, 1);
return;
}
exitinfo_exit(ei, 0);
return;
}
printf("Usage: chdir dir\n");
exitinfo_exit(ei, 1);
}
/*
* exit
* pretty simple. allow the user to choose the exit code if they want,
* otherwise default to 0 (success).
*/
static
void
cmd_exit(int ac, char *av[], struct exitinfo *ei)
{
int code;
if (ac == 1) {
code = 0;
}
else if (ac == 2) {
code = atoi(av[1]);
}
else {
printf("Usage: exit [code]\n");
exitinfo_exit(ei, 1);
return;
}
exit(code);
}
/*
* a struct of the builtins associates the builtin name with the function that
* executes it. they must all take an argc and argv.
*/
static struct {
const char *name;
void (*func)(int, char **, struct exitinfo *);
} builtins[] = {
{ "cd", cmd_chdir },
{ "chdir", cmd_chdir },
{ "exit", cmd_exit },
{ "wait", cmd_wait },
{ NULL, NULL }
};
/*
* docommand
* tokenizes the command line using strtok. if there aren't any commands,
* simply returns. checks to see if it's a builtin, running it if it is.
* otherwise, it's a standard command. check for the '&', try to background
* the job if possible, otherwise just run it and wait on it.
*/
static
void
docommand(char *buf, struct exitinfo *ei)
{
char *args[NARG_MAX + 1];
int nargs, i;
char *s;
pid_t pid;
int status;
int bg=0;
time_t startsecs, endsecs;
unsigned long startnsecs, endnsecs;
nargs = 0;
for (s = strtok(buf, " \t\r\n"); s; s = strtok(NULL, " \t\r\n")) {
if (nargs >= NARG_MAX) {
printf("%s: Too many arguments "
"(exceeds system limit)\n",
args[0]);
exitinfo_exit(ei, 1);
return;
}
args[nargs++] = s;
}
args[nargs] = NULL;
if (nargs==0) {
/* empty line */
exitinfo_exit(ei, 0);
return;
}
for (i=0; builtins[i].name; i++) {
if (!strcmp(builtins[i].name, args[0])) {
builtins[i].func(nargs, args, ei);
return;
}
}
/* Not a builtin; run it */
if (nargs > 0 && !strcmp(args[nargs-1], "&")) {
/* background */
if (!can_bg()) {
printf("%s: Too many background jobs; wait for "
"some to finish before starting more\n",
args[0]);
exitinfo_exit(ei, 1);
return;
}
nargs--;
args[nargs] = NULL;
bg = 1;
}
if (timing) {
__time(&startsecs, &startnsecs);
}
pid = fork();
switch (pid) {
case -1:
/* error */
warn("fork");
exitinfo_exit(ei, 255);
return;
case 0:
/* child */
execvp(args[0], args);
warn("%s", args[0]);
/*
* Use _exit() instead of exit() in the child
* process to avoid calling atexit() functions,
* which would cause hostcompat (if present) to
* reset the tty state and mess up our input
* handling.
*/
_exit(1);
default:
break;
}
/* parent */
if (bg) {
/* background this command */
remember_bg(pid);
printf("[%d] %s ... &\n", pid, args[0]);
exitinfo_exit(ei, 0);
return;
}
if (waitpid(pid, &status, 0) < 0) {
warn("waitpid");
exitinfo_exit(ei, 255);
}
else {
readstatus(status, ei);
}
if (timing) {
__time(&endsecs, &endnsecs);
if (endnsecs < startnsecs) {
endnsecs += 1000000000;
endsecs--;
}
endnsecs -= startnsecs;
endsecs -= startsecs;
warnx("subprocess time: %lu.%09lu seconds",
(unsigned long) endsecs, (unsigned long) endnsecs);
}
}
/*
* getcmd
* pulls valid characters off the console, filling the buffer.
* backspace deletes a character, simply by moving the position back.
* a newline or carriage return breaks the loop, which terminates
* the string and returns.
*
* if there's an invalid character or a backspace when there's nothing
* in the buffer, putchars an alert (bell).
*/
static
void
getcmd(char *buf, size_t len)
{
size_t pos = 0;
int done=0, ch;
/*
* In the absence of a <ctype.h>, assume input is 7-bit ASCII.
*/
while (!done) {
ch = getchar();
if ((ch == '\b' || ch == 127) && pos > 0) {
putchar('\b');
putchar(' ');
putchar('\b');
pos--;
}
else if (ch == '\r' || ch == '\n') {
putchar('\r');
putchar('\n');
done = 1;
}
else if (ch >= 32 && ch < 127 && pos < len-1) {
buf[pos++] = ch;
putchar(ch);
}
else {
/* alert (bell) character */
putchar('\a');
}
}
buf[pos] = 0;
}
/*
* interactive
* runs the interactive shell. basically, just infinitely loops, grabbing
* commands and running them (and printing the exit status if it's not
* success.)
*/
static
void
interactive(void)
{
char buf[CMDLINE_MAX];
struct exitinfo ei;
while (1) {
printf("OS/161$ ");
getcmd(buf, sizeof(buf));
docommand(buf, &ei);
printstatus(&ei, 0);
#ifdef WNOHANG
waitpoll();
#endif
}
}
static
void
check_timing(void)
{
time_t secs;
unsigned long nsecs;
if (__time(&secs, &nsecs) != -1) {
timing = 1;
warnx("Timing enabled.");
}
}
/*
* main
* if there are no arguments, run interactively, otherwise, run a program
* from within the shell, but immediately exit.
*/
int
main(int argc, char *argv[])
{
#ifdef HOST
hostcompat_init(argc, argv);
#endif
check_timing();
/*
* Allow argc to be 0 in case we're running on a broken kernel,
* or one that doesn't set argv when starting the first shell.
*/
if (argc == 0 || argc == 1) {
interactive();
}
else if (argc == 3 && !strcmp(argv[1], "-c")) {
struct exitinfo ei;
docommand(argv[2], &ei);
printstatus(&ei, 0);
if (ei.signaled || ei.stopped || ei.val != 0) {
exit(1);
}
}
else {
errx(1, "Usage: sh [-c command]");
}
return 0;
}

View File

@@ -0,0 +1,12 @@
# Makefile for sync
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=sync
SRCS=sync.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

43
userland/bin/sync/sync.c Normal file
View File

@@ -0,0 +1,43 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
/*
* sync - force kernel buffers (write-back disk cache) to disk.
*
* Just calls the sync() system call.
*/
int
main(void)
{
sync();
return 0;
}

12
userland/bin/tac/Makefile Normal file
View File

@@ -0,0 +1,12 @@
# Makefile for tac
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=tac
SRCS=tac.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

294
userland/bin/tac/tac.c Normal file
View File

@@ -0,0 +1,294 @@
/*
* Copyright (c) 2014
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* tac - print file backwards line by line (reverse cat)
* usage: tac [files]
*
* This implementation copies the input to a scratch file, using a
* second scratch file to keep notes, and then prints the scratch file
* backwards. This is inefficient, but has the side effect of testing
* the behavior of scratch files that have been unlinked.
*
* Note that if the remove system call isn't implemented, unlinking
* the scratch files will fail and the scratch files will get left
* behind. To avoid unnecessary noise (e.g. on emufs) we won't
* complain about this.
*
* This program uses these system calls:
* getpid open read write lseek close remove _exit
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <err.h>
struct indexentry {
off_t pos;
off_t len;
};
static int datafd = -1, indexfd = -1;
static char dataname[64], indexname[64];
static char buf[4096];
////////////////////////////////////////////////////////////
// string ops
/* this is standard and should go into libc */
static
void *
memchr(const void *buf, int ch, size_t buflen)
{
const unsigned char *ubuf = buf;
size_t i;
for (i=0; i<buflen; i++) {
if (ubuf[i] == ch) {
/* this must launder const */
return (void *)(ubuf + i);
}
}
return NULL;
}
////////////////////////////////////////////////////////////
// syscall wrappers
static
size_t
doread(int fd, const char *name, void *buf, size_t len)
{
ssize_t r;
r = read(fd, buf, len);
if (r == -1) {
err(1, "%s: read", name);
}
return (size_t)r;
}
static
void
dowrite(int fd, const char *name, const void *buf, size_t len)
{
ssize_t r;
r = write(fd, buf, len);
if (r == -1) {
err(1, "%s: write", name);
}
else if ((size_t)r != len) {
errx(1, "%s: write: Unexpected short count %zd of %zu",
r, len);
}
}
static
off_t
dolseek(int fd, const char *name, off_t pos, int whence)
{
off_t ret;
ret = lseek(fd, pos, whence);
if (ret == -1) {
err(1, "%s: lseek", name);
}
return ret;
}
////////////////////////////////////////////////////////////
// file I/O
static
void
readfile(const char *name)
{
int fd, closefd;
struct indexentry x;
size_t len, remaining, here;
const char *s, *t;
if (name == NULL || !strcmp(name, "-")) {
fd = STDIN_FILENO;
closefd = -1;
}
else {
fd = open(name, O_RDONLY);
if (fd < 0) {
err(1, "%s", name);
}
closefd = fd;
}
x.pos = 0;
x.len = 0;
while (1) {
len = doread(fd, name, buf, sizeof(buf));
if (len == 0) {
break;
}
remaining = len;
for (s = buf; s != NULL; s = t) {
t = memchr(s, '\n', remaining);
if (t != NULL) {
t++;
here = (t - s);
x.len += here;
remaining -= here;
dowrite(indexfd, indexname, &x, sizeof(x));
x.pos += x.len;
x.len = 0;
}
else {
x.len += remaining;
}
}
dowrite(datafd, dataname, buf, len);
}
if (x.len > 0) {
dowrite(indexfd, indexname, &x, sizeof(x));
}
if (closefd != -1) {
close(closefd);
}
}
static
void
dumpdata(void)
{
struct indexentry x;
off_t indexsize, pos, done;
size_t amount, len;
indexsize = dolseek(indexfd, indexname, 0, SEEK_CUR);
pos = indexsize;
while (1) {
pos -= sizeof(x);
if (pos == 0) {
break;
}
assert(pos >= 0);
dolseek(indexfd, indexname, pos, SEEK_SET);
len = doread(indexfd, indexname, &x, sizeof(x));
if (len != sizeof(x)) {
errx(1, "%s: read: Unexpected EOF", indexname);
}
dolseek(datafd, dataname, x.pos, SEEK_SET);
for (done = 0; done < x.len; done += amount) {
amount = sizeof(buf);
if ((off_t)amount > x.len - done) {
amount = x.len - done;
}
len = doread(datafd, dataname, buf, amount);
if (len != amount) {
errx(1, "%s: read: Unexpected short count"
" %zu of %zu", dataname, len, amount);
}
dowrite(STDOUT_FILENO, "stdout", buf, len);
}
}
}
////////////////////////////////////////////////////////////
// main
static
int
openscratch(const char *name, int flags, mode_t mode)
{
int fd;
fd = open(name, flags, mode);
if (fd < 0) {
err(1, "%s", name);
}
if (remove(name) < 0) {
if (errno != ENOSYS) {
err(1, "%s: remove", name);
}
}
return fd;
}
static
void
openfiles(void)
{
pid_t pid;
pid = getpid();
snprintf(dataname, sizeof(dataname), ".tmp.tacdata.%d", (int)pid);
datafd = openscratch(dataname, O_RDWR|O_CREAT|O_TRUNC, 0664);
snprintf(indexname, sizeof(indexname), ".tmp.tacindex.%d", (int)pid);
indexfd = openscratch(indexname, O_RDWR|O_CREAT|O_TRUNC, 0664);
}
static
void
closefiles(void)
{
close(datafd);
close(indexfd);
indexfd = datafd = -1;
}
int
main(int argc, char *argv[])
{
int i;
openfiles();
if (argc > 1) {
for (i=1; i<argc; i++) {
readfile(argv[i]);
}
}
else {
readfile(NULL);
}
dumpdata();
closefiles();
return 0;
}

View File

@@ -0,0 +1,12 @@
# Makefile for true
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=true
SRCS=true.c
BINDIR=/bin
.include "$(TOP)/mk/os161.prog.mk"

42
userland/bin/true/true.c Normal file
View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
* The President and Fellows of Harvard College.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <stdlib.h>
/*
* true - succeed.
*/
int
main(void)
{
/* Just exit with success. */
exit(0);
}