Initial commit

This commit is contained in:
Trevor Vallender 2024-01-20 14:39:54 +00:00
commit 129a4ecbc9
228 changed files with 18680 additions and 0 deletions

6
README.md Normal file
View File

@ -0,0 +1,6 @@
# Books
Code from programming books I work through—both sample code from the books and code
I write myself.
## Advanced Programming in the UNIX environment

BIN
apitue/01/simple_shell Executable file

Binary file not shown.

44
apitue/01/simple_shell.c Normal file
View File

@ -0,0 +1,44 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
char * get_input(char *buffer, size_t buflen) {
printf("$$ ");
return fgets(buffer, buflen, stdin);
}
int main(int argc, char **argv) {
char buf[BUFSIZ];
pid_t pid;
int status;
// Cast to void to prevent compiler warning
(void)argc;
(void)argv;
while(get_input(buf, sizeof(buf))) {
buf[strlen(buf) - 1] = '\0';
if ((pid = fork()) == -1) {
fprintf(stderr, "SHELL: Cant fork: %s\n", strerror(errno));
continue;
} else if (pid == 0) {
execlp(buf, buf, (char *)0);
fprintf(stderr, "SHELL: Cant exec %s: %s\n", buf, strerror(errno));
exit(EX_UNAVAILABLE);
}
// Parent waits
if ((pid = waitpid(pid, &status, 0)) < 0) {
fprintf(stderr, "SHELL: waitpid error: %s\n", strerror(errno));
}
}
exit(EX_OK);
}

View File

@ -0,0 +1,26 @@
# This file is part of the sample code and exercises
# used by the class "Advanced Programming in the UNIX
# Environment" taught by Jan Schaumann
# <jschauma@netmeister.org> at Stevens Institute of
# Technology.
#
# This file is in the public domain.
#
# You don't have to, but if you feel like
# acknowledging where you got this code, you may
# reference me by name, email address, or point
# people to the course website:
# https://stevens.netmeister.org/631/
#! /bin/sh
set -eu
umask 022
for set in gnusrc sharesrc src syssrc; do
echo "Fetching ${set}..."
ftp -V ftp.netbsd.org:/pub/NetBSD/NetBSD-9.3/source/sets/${set}.tgz
echo "Extracting ${set}..."
su root -c "tar zxf ${set}.tgz -C /"
rm -f "${set}.tgz"
done

View File

@ -0,0 +1,26 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
/* cast to void to suppress compiler warnings about unused variables */
(void)argc;
(void)argv;
printf("Hello, World!\n");
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,28 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* This trivial program simply prints out its own PID and exits.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main() {
printf("Our process id is %d.\n", getpid());
return(EXIT_SUCCESS);
}

View File

@ -0,0 +1,57 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* Stripped down version of 'cat', using unbuffered I/O.
* ./simple-cat < simple-cat.c
*
* Guess what, this is also a primitive version of 'cp':
* ./simple-cat <simple-cat.c >simple-cat.copy
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef BUFFSIZE
#define BUFFSIZE 32768
#endif
int
main(int argc, char **argv) {
int n;
char buf[BUFFSIZE];
/* cast to void to silence compiler warnings */
(void)argc;
(void)argv;
while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0) {
if (write(STDOUT_FILENO, buf, n) != n) {
fprintf(stderr, "Unable to write: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
}
if (n < 0) {
fprintf(stderr, "Unable to read: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
return(EXIT_SUCCESS);
}

View File

@ -0,0 +1,51 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* Stripped down version of 'cat', buffered version.
* Guess what, this is also a primitive version of 'cp':
* ./simple-cat <simple-cat.c >simple-cat.copy
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
main(int argc, char **argv) {
int c;
/* cast to void to silence compiler warnings */
(void)argc;
(void)argv;
while ((c = getc(stdin)) != EOF) {
if (putc(c, stdout) == EOF) {
fprintf(stderr, "Unable to write: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
}
if (ferror(stdin)) {
fprintf(stderr, "Unable to read: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
return(EXIT_SUCCESS);
}

View File

@ -0,0 +1,53 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* simple-ls.c
* Extremely low-power ls clone.
* ./simple-ls .
*/
#include <sys/types.h>
#include <errno.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char **argv) {
DIR *dp;
struct dirent *dirp;
if (argc != 2) {
fprintf(stderr, "usage: %s dir_name\n", argv[0]);
exit(EXIT_FAILURE);
}
if ((dp = opendir(argv[1])) == NULL) {
fprintf(stderr, "Unable to open '%s': %s\n",
argv[1], strerror(errno));
exit(EXIT_FAILURE);
}
while ((dirp = readdir(dp)) != NULL) {
printf("%s\n", dirp->d_name);
}
(void)closedir(dp);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,76 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* World's simplest shell.
* Loops, reads input and tries to execute it.
* Note: no tokenization, can be ^C'd, but does look at PATH
*
* ./simple-shell
* $$ ls
* $$ ls -l # error
* $$ ^C
*
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
char *
getinput(char *buffer, size_t buflen) {
printf("$$ ");
return fgets(buffer, buflen, stdin);
}
int
main(int argc, char **argv) {
char buf[BUFSIZ];
pid_t pid;
int status;
/* cast to void to silence compiler warnings */
(void)argc;
(void)argv;
while (getinput(buf, sizeof(buf))) {
buf[strlen(buf) - 1] = '\0';
if((pid=fork()) == -1) {
fprintf(stderr, "shell: can't fork: %s\n",
strerror(errno));
continue;
} else if (pid == 0) { /* child */
execlp(buf, buf, (char *)0);
fprintf(stderr, "shell: couldn't exec %s: %s\n", buf,
strerror(errno));
exit(EX_UNAVAILABLE);
}
/* parent waits */
if ((pid=waitpid(pid, &status, 0)) < 0) {
fprintf(stderr, "shell: waitpid error: %s\n",
strerror(errno));
}
}
exit(EX_OK);
}

View File

@ -0,0 +1,83 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* World's 2nd simplest shell
* Same as simple-shell.c, but with a SIGINT signal handler.
* Feed EOF (^D) to exit.
*
* Also illustrates forward declaration of a function prototype.
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
char *
getinput(char *buffer, size_t buflen) {
printf("$$ ");
return fgets(buffer, buflen, stdin);
}
void
sig_int(int signo) {
printf("\nCaught SIGINT (Signal #%d)!\n$$ ", signo);
(void)fflush(stdout);
}
int
main(int argc, char **argv) {
char buf[BUFSIZ];
pid_t pid;
int status;
/* cast to void to silence compiler warnings */
(void)argc;
(void)argv;
if (signal(SIGINT, sig_int) == SIG_ERR) {
fprintf(stderr, "signal error: %s\n", strerror(errno));
exit(1);
}
while (getinput(buf, sizeof(buf))) {
buf[strlen(buf) - 1] = '\0';
if((pid=fork()) == -1) {
fprintf(stderr, "shell: can't fork: %s\n",
strerror(errno));
continue;
} else if (pid == 0) { /* child */
execlp(buf, buf, (char *)0);
fprintf(stderr, "shell: couldn't exec %s: %s\n", buf,
strerror(errno));
exit(EX_UNAVAILABLE);
}
/* parent waits */
if ((pid=waitpid(pid, &status, 0)) < 0) {
fprintf(stderr, "shell: waitpid error: %s\n",
strerror(errno));
}
}
exit(EX_OK);
}

View File

@ -0,0 +1,21 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
#include <stdio.h>
int
main() {
printf("Welcome to CS631 Advanced Programming in the UNIX Environment, %s!\n", getlogin())
}

View File

@ -0,0 +1,39 @@
catio: tmpfiles simple-cat.c
@i=0; for n in 3145728 1048576 32768 16384 4096 1024 256 128 64 1; do \
echo "BUFFSIZE = $$n"; \
cc -Wall -DBUFFSIZE=$$n simple-cat.c; \
i=$$(( $$i + 1 )); \
for j in $$(jot 5); do \
time ./a.out <tmp/file$$i >tmp/out; \
done; \
echo; \
echo; \
done;
clean:
rm -fr tmp
tmpfiles: tmp/file9
tmp/file9:
@mkdir -p tmp
@for n in $$(jot 10); do \
echo "Creating file number $$n..."; \
dd if=/dev/urandom of=tmp/file$$n bs=$$(( 1024 * 1024 )) count=100 2>/dev/null;\
done;
sync: tmpfiles scat
time ./scat <tmp/file9 >out
scat: sync-cat.c
cc -Wall sync-cat.c -o scat
async: tmpfiles ascat
time ./ascat <tmp/file9 >out
ascat: async-cat.c
cc -Wall $? -o $@
async-cat.c: sync-cat.c
sed -e 's|\(.*O_SYNC.*\)|//\1|' sync-cat.c > async-cat.c

View File

@ -0,0 +1,49 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/* A simple program to show what arguments were passed to a program. This
* can be used to illustrate how different shells expand arguments
* differently.
*
* See also:
* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
* https://wpollock.com/ShScript/CmdLineProcessing.htm
*
* Examples:
* ./a.out
* ./a.out *.c
* ./a.out *.none
* ./a.out *.[1c]
* ./a.out "*.c"
* ./a.out $USER
* ./a.out "$(echo *.1)"
* ./a.out {foo,bar,baz}.whatever
* ./a.out {1..5}
* ./a.out {1..5}{a..f}
*/
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv) {
int i;
for (i=0; i<argc; i++) {
printf("%s\n", argv[i]);
}
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,56 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* This program illustrates that you an close the default
* standard I/O filedescriptors. To reopen, you then need
* to explicitly open the terminal device and dup(2) the
* descriptor onto it.
*/
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
main() {
int fd;
if ((fd = open("/dev/tty", O_WRONLY)) < 0) {
err(EXIT_FAILURE, "Unable to open /dev/tty");
/* NOTREACHED */
}
(void)printf("Opened /dev/tty on fd#%d.\n", fd);
(void)printf("Closing STDERR_FILENO...\n");
(void)close(STDERR_FILENO);
(void)fprintf(stderr, "This message will not be shown.\n");
if (dup2(fd, STDERR_FILENO) < 0) {
/* stderr is still closed */
(void)fprintf(stdout, "Unable to dup2: %s\n", strerror(errno));
exit(EXIT_FAILURE);
/* NOTREACHED */
}
(void)fprintf(stderr, "Error messages back to normal.\n");
(void)close(fd);
return EXIT_SUCCESS;
}

249
apitue/sample-code/02/dump Normal file
View File

@ -0,0 +1,249 @@
173 1 ktrace EMUL "netbsd"
173 1 ktrace CALL execve(0x7f7fff6c5140,0x7f7fff6c5648,0x7f7fff6c5658)
173 1 ktrace NAMI "/home/jschauma/bin/ls"
173 1 ktrace RET execve -1 errno 2 No such file or directory
173 1 ktrace CALL execve(0x7f7fff6c5140,0x7f7fff6c5648,0x7f7fff6c5658)
173 1 ktrace NAMI "/bin/ls"
173 1 ktrace NAMI "/libexec/ld.elf_so"
173 1 ls EMUL "netbsd"
173 1 ls RET execve JUSTRETURN
173 1 ls CALL mmap(0,0x8000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597951066112/0x7981b26a8000
173 1 ls CALL open(0x7f7e4ae0d39f,0,0x7f7e4b012768)
173 1 ls NAMI "/etc/ld.so.conf"
173 1 ls RET open -1 errno 2 No such file or directory
173 1 ls CALL open(0x7f7fff4c7e68,0,1)
173 1 ls NAMI "/lib/libutil.so.7"
173 1 ls RET open 3
173 1 ls CALL __fstat50(3,0x7f7fff4c7d68)
173 1 ls RET __fstat50 0
173 1 ls CALL mmap(0,0x1000,PROT_READ,0x1<SHARED,FILE,ALIGN=NONE>,3,0,0)
173 1 ls RET mmap 133597951062016/0x7981b26a7000
173 1 ls CALL munmap(0x7981b26a7000,0x1000)
173 1 ls RET munmap 0
173 1 ls CALL mmap(0,0x21d000,PROT_READ|PROT_EXEC,0x15000002<PRIVATE,FILE,ALIGN=2MB>,3,0,0)
173 1 ls RET mmap 133597948280832/0x7981b2400000
173 1 ls CALL mmap(0x7981b2617000,0x4000,PROT_READ|PROT_WRITE,0x12<PRIVATE,FIXED,FILE,ALIGN=NONE>,3,0,0x17000)
173 1 ls RET mmap 133597950472192/0x7981b2617000
173 1 ls CALL mmap(0x7981b261b000,0x2000,PROT_READ|PROT_WRITE,0x1012<PRIVATE,FIXED,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950488576/0x7981b261b000
173 1 ls CALL mprotect(0x7981b2417000,0x200000,PROT_NONE)
173 1 ls RET mprotect 0
173 1 ls CALL close(3)
173 1 ls RET close 0
173 1 ls CALL open(0x7f7fff4c7e68,0,7)
173 1 ls NAMI "/lib/libc.so.12"
173 1 ls RET open 3
173 1 ls CALL __fstat50(3,0x7f7fff4c7d68)
173 1 ls RET __fstat50 0
173 1 ls CALL mmap(0,0x1000,PROT_READ,0x1<SHARED,FILE,ALIGN=NONE>,3,0,0)
173 1 ls RET mmap 133597951062016/0x7981b26a7000
173 1 ls CALL munmap(0x7981b26a7000,0x1000)
173 1 ls RET munmap 0
173 1 ls CALL mmap(0,0x5e2000,PROT_READ|PROT_EXEC,0x15000002<PRIVATE,FILE,ALIGN=2MB>,3,0,0)
173 1 ls RET mmap 133597941989376/0x7981b1e00000
173 1 ls CALL mmap(0x7981b21ae000,0x12000,PROT_READ|PROT_WRITE,0x12<PRIVATE,FIXED,FILE,ALIGN=NONE>,3,0,0x1ae000)
173 1 ls RET mmap 133597945847808/0x7981b21ae000
173 1 ls CALL mmap(0x7981b21c0000,0x222000,PROT_READ|PROT_WRITE,0x1012<PRIVATE,FIXED,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597945921536/0x7981b21c0000
173 1 ls CALL mprotect(0x7981b1faf000,0x1ff000,PROT_NONE)
173 1 ls RET mprotect 0
173 1 ls CALL close(3)
173 1 ls RET close 0
173 1 ls CALL mprotect(0x7981b2617000,0x2000,PROT_READ)
173 1 ls RET mprotect 0
173 1 ls CALL mprotect(0x7981b21ae000,0xc000,PROT_READ)
173 1 ls RET mprotect 0
173 1 ls CALL mprotect(0x45605000,0x1000,PROT_READ)
173 1 ls RET mprotect 0
173 1 ls CALL _lwp_setprivate(0x7981b26ae850)
173 1 ls RET _lwp_setprivate 0
173 1 ls CALL _lwp_self
173 1 ls RET _lwp_self 1
173 1 ls CALL __sigprocmask14(1,0x7f7fff4c8560,0x7f7fff4c85e0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL __sigprocmask14(3,0x7f7fff4c85e0,0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL readlink(0x7981b1f75420,0x7f7fff4c8040,0x400)
173 1 ls NAMI "/etc/malloc.conf"
173 1 ls RET readlink -1 errno 2 No such file or directory
173 1 ls CALL issetugid
173 1 ls RET issetugid 0
173 1 ls CALL __sysctl(0x7f7fff4c83d8,2,0x7981b21d16a0,0x7f7fff4c83d0,0,0)
173 1 ls RET __sysctl 0
173 1 ls CALL mmap(0,0x1000,PROT_NONE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597951062016/0x7981b26a7000
173 1 ls CALL madvise(0x7981b26a7000,0x1000,6)
173 1 ls RET madvise 0
173 1 ls CALL munmap(0x7981b26a7000,0x1000)
173 1 ls RET munmap 0
173 1 ls CALL mmap(0,0x200000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597939892224/0x7981b1c00000
173 1 ls CALL __clock_gettime50(3,0x7f7fff4c83d0)
173 1 ls RET __clock_gettime50 0
173 1 ls CALL __clock_gettime50(3,0x7f7fff4c83d0)
173 1 ls RET __clock_gettime50 0
173 1 ls CALL __clock_gettime50(3,0x7f7fff4c83f0)
173 1 ls RET __clock_gettime50 0
173 1 ls CALL mmap(0,0x8000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597951033344/0x7981b26a0000
173 1 ls CALL mmap(0,0x400000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597935697920/0x7981b1800000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597951029248/0x7981b269f000
173 1 ls CALL __sysctl(0x7f7fff4c8470,2,0x7f7fff4c8450,0x7f7fff4c8448,0,0)
173 1 ls RET __sysctl 0
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597951025152/0x7981b269e000
173 1 ls CALL __sysctl(0x7981b1f7b720,2,0x7981b21d0680,0x7f7fff4c84a8,0,0)
173 1 ls RET __sysctl 0
173 1 ls CALL _lwp_self
173 1 ls RET _lwp_self 1
173 1 ls CALL __sigprocmask14(1,0x7f7fff4c84b0,0x7f7fff4c85e0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL __sigprocmask14(3,0x7f7fff4c85e0,0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL _lwp_self
173 1 ls RET _lwp_self 1
173 1 ls CALL __sigprocmask14(1,0x7f7fff4c84b0,0x7f7fff4c85e0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL __sigprocmask14(3,0x7f7fff4c85e0,0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL issetugid
173 1 ls RET issetugid 0
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597951021056/0x7981b269d000
173 1 ls CALL ioctl(1,TIOCGETA,0x7f7fff4c8580)
173 1 ls GIO fd 1 read 44 bytes
"\^B+\0\0\a\0\0\0\0K\0\0\M-K\^E\0 \^D\M^?\M^?\^?\^W\^U\^R\M^?\^C\^\\^Z\
\^Y\^Q\^S\^V\^O\^A\0\^T\M^?\M^@%\0\0\M^@%\0\0"
173 1 ls RET ioctl 0
173 1 ls CALL ioctl(1,TIOCGWINSZ,0x7f7fff4c85d8)
173 1 ls GIO fd 1 read 8 bytes
"\^X\0P\0p\^C\^P\^B"
173 1 ls RET ioctl 0
173 1 ls CALL getuid
173 1 ls RET getuid 1000/0x3e8, 1000/0x3e8
173 1 ls CALL mmap(0,0x5000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597951000576/0x7981b2698000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950996480/0x7981b2697000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950992384/0x7981b2696000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950988288/0x7981b2695000
173 1 ls CALL __stat50(0x7981b269d0f0,0x7f7fff4c8470)
173 1 ls NAMI "."
173 1 ls RET __stat50 0
173 1 ls CALL open(0x7981b1f7877e,0x400000,0)
173 1 ls NAMI "."
173 1 ls RET open 3
173 1 ls CALL fchdir(3)
173 1 ls RET fchdir 0
173 1 ls CALL open(0x7981b1f7877e,0x400000,0)
173 1 ls NAMI "."
173 1 ls RET open 4
173 1 ls CALL open(0x7981b2697000,0x600004,0)
173 1 ls NAMI "."
173 1 ls RET open 5
173 1 ls CALL fstatvfs1(5,0x7f7fff4c7b80,2)
173 1 ls RET fstatvfs1 0
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950984192/0x7981b2694000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950980096/0x7981b2693000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950976000/0x7981b2692000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950971904/0x7981b2691000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950967808/0x7981b2690000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950963712/0x7981b268f000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950959616/0x7981b268e000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950955520/0x7981b268d000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950951424/0x7981b268c000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950947328/0x7981b268b000
173 1 ls CALL mmap(0,0x1000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950943232/0x7981b268a000
173 1 ls CALL lseek(5,0,0,1)
173 1 ls RET lseek 0
173 1 ls CALL __getdents30(5,0x7981b2694000,0x1000)
173 1 ls GIO fd 5 read 408 bytes
"\^O0\^V\0\0\0\0\0\^P\0\^A\0\^D.\0\0\v0\^V\0\0\0\0\0\^P\0\^B\0\^D..\0\
\M^Q0\^V\0\0\0\0\0\^X\0\^E\0\bfds.c\0\0\0\0\0\0\M^R0\^V\0\0\0\0\0\^X\0\
\^F\0\bhole.c\0\0\0\0\0\M^S0\^V\0\0\0\0\0\^X\0\b\0\bMakefile\0\0\0\M^T\
0\^V\0\0\0\0\0\^X\0\n\0\bsync-cat.c\0\M^U0\^V\0\0\0\0\0\^X\0\^F\0\brwe\
x.c\0\0\0\0\0\M^V0\^V\0\0\0\0\0\^X\0\a\0\bredir.c\0\0\0\0\M^W0\^V\0\0\
\0\0\0\^X\0\a\0\blseek.c\0\0\0\0\M^X0\^V\0\0\0\0\0 \0\f\0\bsimple-cat.\
c\0\0\0\0\0\0\0\M^Y0\^V\0\0\0\0\0\^X\0\^F\0\bargv.c\0\0\0\0\0\M^Z0\^V\
\0\0\0\0\0\^X\0\b\0\bopenex.c\0\0\0\M^[0\^V\0\0\0\0\0\^X\0 \0\bop\
enfds.c\0\0\M^\0\^V\0\0\0\0\0\^X\0 \0\bopenmax.c\0\0\M-C0\^V\0\0\
\0\0\0\^X\0\^E\0\ba.out\0\0\0\0\0\0\M-f0\^V\0\0\0\0\0 \0\^N\0\blseek-t\
o-end.c\0\0\0\0\0\M-b0\^V\0\0\0\0\0\^X\0\n\0\bktrace.out\0"
173 1 ls RET __getdents30 408/0x198
173 1 ls CALL mmap(0,0x5000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950922752/0x7981b2685000
173 1 ls CALL lseek(5,0,0,1)
173 1 ls RET lseek 512/0x200
173 1 ls CALL __getdents30(5,0x7981b2694000,0x1000)
173 1 ls GIO fd 5 read 0 bytes
""
173 1 ls RET __getdents30 0
173 1 ls CALL close(5)
173 1 ls RET close 0
173 1 ls CALL mmap(0,0x7000,PROT_READ|PROT_WRITE,0x1002<PRIVATE,ANONYMOUS,ALIGN=NONE>,0xffffffff,0,0)
173 1 ls RET mmap 133597950894080/0x7981b267e000
173 1 ls CALL fchdir(4)
173 1 ls RET fchdir 0
173 1 ls CALL close(4)
173 1 ls RET close 0
173 1 ls CALL __fstat50(1,0x7f7fff4c7fb0)
173 1 ls RET __fstat50 0
173 1 ls CALL ioctl(1,TIOCGETA,0x7f7fff4c8020)
173 1 ls GIO fd 1 read 44 bytes
"\^B+\0\0\a\0\0\0\0K\0\0\M-K\^E\0 \^D\M^?\M^?\^?\^W\^U\^R\M^?\^C\^\\^Z\
\^Y\^Q\^S\^V\^O\^A\0\^T\M^?\M^@%\0\0\M^@%\0\0"
173 1 ls RET ioctl 0
173 1 ls CALL write(1,0x7981b2694000,0x47)
173 1 ls GIO fd 1 wrote 71 bytes
"Makefile fds.c lseek-to-end.c openfds.c rwex.c\
\n"
173 1 ls RET write 71/0x47
173 1 ls CALL write(1,0x7981b2694000,0x4d)
173 1 ls GIO fd 1 wrote 77 bytes
"a.out hole.c lseek.c openmax.c simple\
-cat.c\n"
173 1 ls RET write 77/0x4d
173 1 ls CALL write(1,0x7981b2694000,0x4b)
173 1 ls GIO fd 1 wrote 75 bytes
"argv.c ktrace.out openex.c redir.c sync-c\
at.c\n"
173 1 ls RET write 75/0x4b
173 1 ls CALL fchdir(3)
173 1 ls RET fchdir 0
173 1 ls CALL close(3)
173 1 ls RET close 0
173 1 ls CALL _lwp_self
173 1 ls RET _lwp_self 1
173 1 ls CALL __sigprocmask14(1,0x7f7fff4c8570,0x7f7fff4c85b0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL __sigprocmask14(3,0x7f7fff4c85b0,0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL _lwp_self
173 1 ls RET _lwp_self 1
173 1 ls CALL __sigprocmask14(1,0x7f7fff4c84c0,0x7f7fff4c85b0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL __sigprocmask14(3,0x7f7fff4c85b0,0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL _lwp_self
173 1 ls RET _lwp_self 1
173 1 ls CALL __sigprocmask14(1,0x7f7fff4c84c0,0x7f7fff4c85b0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL __sigprocmask14(3,0x7f7fff4c85b0,0)
173 1 ls RET __sigprocmask14 0
173 1 ls CALL exit(0)

View File

@ -0,0 +1,85 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* A program to show the value of some file
* descriptors.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int
main() {
int fd1, fd2, fd3;
FILE *f;
printf("STDIN_FILENO: %d\n", STDIN_FILENO);
printf("stdin: %d\n", fileno(stdin));
printf("STDOUT_FILENO: %d\n", STDOUT_FILENO);
printf("stdout: %d\n", fileno(stdout));
printf("STDERR_FILENO: %d\n", STDERR_FILENO);
printf("stderr: %d\n", fileno(stderr));
printf("\nOpening /dev/zero...\n");
if ((fd1 = open("/dev/zero", O_RDONLY)) < 0) {
fprintf(stderr, "Unable to open /dev/zero: %s\n", strerror(errno));
} else {
printf("fd1: %d\n", fd1);
}
printf("\nOpening /dev/zero a second time...\n");
if ((fd2 = open("/dev/zero", O_RDONLY)) < 0) {
fprintf(stderr, "Unable to open /dev/zero: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("fd2: %d\n", fd2);
printf("\nNow closing fd1, but keeping fd2 open..\n");
(void)close(fd1);
printf("\nOpening /dev/zero a third time...\n");
if ((fd3 = open("/dev/zero", O_RDONLY)) < 0) {
fprintf(stderr, "Unable to open /dev/zero: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("fd3: %d\n", fd3);
printf("\nNow closing fd2 and fd3.\n");
(void)close(fd2);
(void)close(fd3);
printf("Now opening /dev/zero as a stream.\n");
if ((f = fopen("/dev/zero", "r")) == NULL) {
fprintf(stderr, "Unable to open /dev/zero: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("f: %d\n", fileno(f));
(void)fclose(f);
(void)close(STDERR_FILENO);
printf("\nOpening /dev/stderr after closing STDERR...\n");
if ((fd3 = open("/dev/stderr", O_RDONLY)) < 0) {
fprintf(stdout, "Unable to open /dev/stderr: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("stderr is now: %d\n", fd3);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,64 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* This simple program creates a file with a hole in it, a so-called
* sparse file. Use hexdump(1) or od(1) to verify that there is no data
* in between the two strings; then copy the file to to another and
* observe that the kernel supplied zeros to fill the hole.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char buf1[] = "abcdefghij";
char buf2[] = "ABCDEFGHIJ";
#define BIGNUM 10240000
int
main(void) {
int fd;
if ((fd = creat("file.hole", S_IRUSR | S_IWUSR)) < 0) {
perror("creat error");
return EXIT_FAILURE;
}
if (write(fd, buf1, strlen(buf1)) != sizeof(buf1) - 1) {
perror("error writing buf1");
return EXIT_FAILURE;
}
if (lseek(fd, BIGNUM, SEEK_CUR) == -1) {
perror("lseek error");
return EXIT_FAILURE;
}
if (write(fd, buf2, strlen(buf2)) != sizeof(buf2) - 1) {
perror("error writing buf2");
return EXIT_FAILURE;
}
sleep(30);
(void)close(fd);
return EXIT_SUCCESS;
}

Binary file not shown.

View File

@ -0,0 +1,73 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* This program creates a new file, writes ten bytes to it
* and then seeks to the end of the file. Where do we end up?
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define DATA "0123456789"
void
printOffset(int fd, int whence) {
off_t off;
if ((off = lseek(fd, 0, whence)) == -1) {
err(EXIT_FAILURE, "Unable to lseek");
/* NOTREACHED */
}
(void)printf("Offset: %d\n", (int)off);
}
int
main(void) {
int fd;
int len;
if ((fd = open("f", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1) {
err(EXIT_FAILURE, "Unable create file 'f'");
/* NOTREACHED */
}
printOffset(fd, SEEK_CUR);
len = sizeof(DATA) - 1;
if (write(fd, DATA, len) != len) {
err(EXIT_FAILURE, "Unable write");
/* NOTREACHED */
}
printOffset(fd, SEEK_CUR);
printOffset(fd, SEEK_END);
(void)close(fd);
if (unlink("f") < 0) {
err(EXIT_FAILURE, "Unable to unlink 'f'");
/* NOTREACHED */
}
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,35 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* This trivial program verifies whether or not STDIN is seekable. Test
* on a regular file, on a pipe or a fifo.
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(void) {
if (lseek(STDIN_FILENO, 0, SEEK_CUR) == -1 )
printf("cannot seek\n");
else
printf("seek OK\n");
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,162 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* This program illustrates the usefulness of openat(2) to avoid
* certain race conditions:
*
* Assume that you want to open the files "file1" and "file2" found
* in the directory "../dir". You might start out using
*
* fd1 = open("../dir/file1", ...)
* fd2 = open("../dir/file2", ...)
*
* However, in between these two calls, another process might have
* renamed the directory "../dir" to "../dir2", then created "../dir"
* and placed a different file named "file2" into it. Your program
* now has opened two files from two different directories.
*
* With openat(2), you could guarantee that the call to open "file2"
* will use the same directory as the call to open "file1":
*
* dfd = open("../dir/", O_DIRECTORY ...)
* fd1 = openat(dfd, "file1", ...)
* fd2 = openat(dfd, "file2", ...)
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void
readData(int fd) {
int n;
char buf[BUFSIZ];
bzero(buf, BUFSIZ);
if ((n = read(fd, buf, BUFSIZ)) == -1) {
(void)fprintf(stderr, "Unable to read data from fd %d: %s\n",
fd, strerror(errno));
exit(EXIT_FAILURE);
}
(void)printf("Read data: %s", buf);
}
void
readFileUsingOpenat(const int dfd, const char *f) {
int fd;
(void)printf("Opening '%s' using openat(2)...\n", f);
if ((fd = openat(dfd, f, O_RDONLY)) == -1) {
(void)fprintf(stderr, "Unable to open '%s': %s\n",
f, strerror(errno));
exit(EXIT_FAILURE);
}
readData(fd);
}
void
readFileUsingOpen(const char *f) {
int fd;
(void)printf("Opening '%s'...\n", f);
if ((fd = open(f, O_RDONLY)) == -1) {
(void)fprintf(stderr, "Unable to open '%s': %s\n",
f, strerror(errno));
exit(EXIT_FAILURE);
}
readData(fd);
}
void
reset() {
system("rm -fr ../dir");
system("mv ../dir2 ../dir");
}
void
makeFiles() {
}
void
setup() {
/* Trivial setup via system(3) because we're lazy. */
system("mkdir -p ./t ./dir");
system("echo file1 > ./dir/file1");
system("echo file2 > ./dir/file2");
if (chdir("./t") < 0) {
(void)fprintf(stderr, "Unable to cd to './t': %s\n", strerror(errno));
exit(EXIT_FAILURE);
/* NOTREACHED */
}
}
void
simulateRaceCondition() {
(void)printf("Simulating race condition by renaming '../dir'...\n");
system("mv ../dir ../dir2");
system("mkdir ../dir");
system("echo notfile2 > ../dir/file2");
}
void
cleanup() {
if (chdir("..") < 0) {
(void)fprintf(stderr, "Unable to register exit handler: %s\n",
strerror(errno));
} else {
system("rm -fr t dir dir2");
}
}
int
main() {
if (atexit(cleanup) < 0) {
(void)fprintf(stderr, "Unable to register exit handler: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
setup();
readFileUsingOpen("../dir/file1");
simulateRaceCondition();
readFileUsingOpen("../dir/file2");
reset();
(void)printf("\nLet's try again...\n\n");
int dfd;
if ((dfd = open("../dir", O_RDONLY | O_DIRECTORY)) == -1) {
(void)fprintf(stderr, "Unable to open directory '../dir': %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
readFileUsingOpenat(dfd, "file1");
simulateRaceCondition();
readFileUsingOpenat(dfd, "file2");
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,170 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann
* <jschauma@netmeister.org> at Stevens Institute of
* Technology.
*
* This file is in the public domain.
*
* You don't have to, but if you feel like
* acknowledging where you got this code, you may
* reference me by name, email address, or point
* people to the course website:
* https://stevens.netmeister.org/631/
*/
/*
* This trivial program illustrates how to open files. We present the
* following use cases:
*
* - create a non-existent file
* - "create" an existing file
* - fail to create an existing file
* - open an existing file
* - fail to open a non-existing file
* - truncate an existing file
*/
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef SLEEP
#define SLEEP 10
#endif
void
createFile() {
int fd;
printf("Checking if './newfile' exists...\n");
system("ls -l ./newfile");
printf("Trying to create './newfile' with O_RDONLY | O_CREAT...\n");
if ((fd = open("./newfile", O_RDONLY | O_CREAT,
S_IRUSR | S_IWUSR)) == -1) {
fprintf(stderr, "Unable to create './newfile': %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
printf("'./newfile' created. File descriptor is: %d\n", fd);
/* We are leaking a file descriptor here to illustrate that they
* are increasing as we open more files. Normally, we would call
* close(2) whenever we're done using the decriptor. */
}
void
failExclFileCreation() {
int fd;
printf("Checking if './newfile' exists...\n");
system("ls -l ./newfile");
printf("Trying to create './newfile' with O_RDONLY | O_CREAT | O_EXCL...\n");
if ((fd = open("./newfile", O_RDONLY | O_CREAT | O_EXCL,
S_IRUSR | S_IWUSR)) == -1) {
fprintf(stderr, "Unable to create './newfile': %s\n",
strerror(errno));
}
/* We expect this to fail! */
if (close(fd) == -1) {
fprintf(stderr, "Closing failed: %s\n", strerror(errno));
}
}
void
failOpenNonexistingFile() {
int fd;
printf("Trying to open (non-existant) './nosuchfile' with O_RDONLY...\n");
if ((fd = open("./nosuchfile", O_RDONLY)) == -1) {
fprintf(stderr, "Unable to open './nosuchfile': %s\n",
strerror(errno));
}
/* We know this is going to fail, but no need to complain. */
(void)close(fd);
}
void
openFile() {
int fd;
printf("Trying to open './openex.c' with O_RDONLY...\n");
if ((fd = open("./openex.c", O_RDONLY)) == -1) {
fprintf(stderr, "Unable to open './openex.c': %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
printf("'./openex.c' opened. File descriptor is: %d\n", fd);
if (close(fd) == 0) {
printf("'./openex.c' closed again\n");
}
}
void
truncateFile() {
int fd;
system("cp openex.c newfile");
printf("Copied 'openex.c' to 'newfile'.\n");
system("ls -l newfile");
printf("Trying to open './newfile' with O_RDONLY | O_TRUNC...\n");
if ((fd = open("./newfile", O_RDONLY | O_TRUNC)) == -1) {
fprintf(stderr, "Unable to open './newfile': %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
printf("'./newfile' opened. File descriptor is: %d\n", fd);
printf("'./newfile' truncated -- see 'ls -l newfile'\n");
system("ls -l newfile");
(void)close(fd);
}
int
main() {
createFile();
system("ls -l newfile");
printf("\n");
sleep(SLEEP);
createFile();
system("ls -l newfile");
printf("\n");
sleep(SLEEP);
failExclFileCreation();
printf("\n");
sleep(SLEEP);
openFile();
printf("\n");
sleep(SLEEP);
failOpenNonexistingFile();
printf("\n");
sleep(SLEEP);
truncateFile();
return 0;
}

View File

@ -0,0 +1,122 @@
/* This file is part of the sample code and exercises
* used by the class "Advanced Programming in the UNIX
* Environment" taught by Jan Schaumann