Initial commit
This commit is contained in:
commit
129a4ecbc9
|
@ -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
|
Binary file not shown.
|
@ -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: Can’t fork: %s\n", strerror(errno));
|
||||
continue;
|
||||
} else if (pid == 0) {
|
||||
execlp(buf, buf, (char *)0);
|
||||
fprintf(stderr, "SHELL: Can’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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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())
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
|
@ -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;
|
||||
}
|
|
@ -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.
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||