Skip to content

Commit

Permalink
Import apue.3e
Browse files Browse the repository at this point in the history
  • Loading branch information
raggi committed Jul 6, 2016
1 parent a6714ae commit 0ae1f03
Show file tree
Hide file tree
Showing 421 changed files with 7,195 additions and 548 deletions.
19 changes: 10 additions & 9 deletions Make.defines.freebsd
Expand Up @@ -3,16 +3,17 @@
# Definitions required in all program directories to compile and link
# C programs using gcc.

WKDIR=$(PWD)/..
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS)
LDDIR=-L../lib
LDLIBS=../lib/libapue.a $(EXTRALIBS)
CFLAGS=-ansi -I$(WKDIR)/include -Wall -DBSD $(EXTRA)

# Our library that almost every program needs.
LIB=../libapue.a
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LDFLAGS=
LDDIR=-L$(ROOT)/lib
LDLIBS=$(LDDIR) -lapue $(EXTRALIBS)
CFLAGS=-ansi -I$(ROOT)/include -Wall -DBSD -D__BSD_VISIBLE $(EXTRA)
RANLIB=ranlib
AR=ar
AWK=awk
LIBAPUE=$(ROOT)/lib/libapue.a

# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out typescript*
TEMPFILES=core core.* *.o temp.* *.out
19 changes: 10 additions & 9 deletions Make.defines.linux
Expand Up @@ -3,16 +3,17 @@
# Definitions required in all program directories to compile and link
# C programs using gcc.

WKDIR=$(PWD)/..
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS)
LDDIR=-L../lib
LDLIBS=../lib/libapue.a $(EXTRALIBS)
CFLAGS=-DLINUX -ansi -I$(WKDIR)/include -Wall -D_GNU_SOURCE $(EXTRA)

# Our library that almost every program needs.
LIB=../libapue.a
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LDFLAGS=
LDDIR=-L$(ROOT)/lib
LDLIBS=$(LDDIR) -lapue $(EXTRALIBS)
CFLAGS=-ansi -I$(ROOT)/include -Wall -DLINUX -D_GNU_SOURCE $(EXTRA)
RANLIB=echo
AR=ar
AWK=awk
LIBAPUE=$(ROOT)/lib/libapue.a

# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out typescript*
TEMPFILES=core core.* *.o temp.* *.out
21 changes: 11 additions & 10 deletions Make.defines.macos
Expand Up @@ -3,16 +3,17 @@
# Definitions required in all program directories to compile and link
# C programs using gcc.

WKDIR=$(PWD)/..
CC=clang
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS)
LDDIR=-L../lib
LDLIBS=../lib/libapue.a
CFLAGS=-ansi -I$(WKDIR)/include -Wall -DMACOS $(EXTRA)

# Our library that almost every program needs.
LIB=../libapue.a
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LDFLAGS=
LDDIR=-L$(ROOT)/lib
LDLIBS=$(LDDIR) -lapue $(EXTRALIBS)
CFLAGS=-ansi -I$(ROOT)/include -Wall -DMACOS -D_DARWIN_C_SOURCE $(EXTRA)
RANLIB=ranlib
AR=ar
AWK=awk
LIBAPUE=$(ROOT)/lib/libapue.a

# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out typescript*
TEMPFILES=core core.* *.o temp.* *.out
20 changes: 11 additions & 9 deletions Make.defines.solaris
Expand Up @@ -3,16 +3,18 @@
# Definitions required in all program directories to compile and link
# C programs using gcc.

WKDIR=$(PWD)/..
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDDIR) $(LDFLAGS)
LDDIR=-L../lib
LDLIBS=../lib/libapue.a $(EXTRALIBS)
CFLAGS=-I$(WKDIR)/include -Wall -DSOLARIS $(EXTRA)

# Our library that almost every program needs.
LIB=../libapue.a
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
LDFLAGS=
LDDIR=-L$(ROOT)/lib
LDLIBS=$(LDDIR) -lapue $(EXTRALIBS)
CFLAGS=-std=c99 -m64 -I$(ROOT)/include -Wall -DSOLARIS -D__EXTENSIONS__ $(EXTRA)
RANLIB=echo
AR=ar
AWK=nawk
LIBAPUE=$(ROOT)/lib/libapue.a
NAMEMAX=-DNAME_MAX=_XOPEN_NAME_MAX

# Common temp files to delete from each directory.
TEMPFILES=core core.* *.o temp.* *.out typescript*
TEMPFILES=core core.* *.o temp.* *.out
2 changes: 2 additions & 0 deletions Make.libapue.inc
@@ -0,0 +1,2 @@
$(LIBAPUE):
(cd $(ROOT)/lib && $(MAKE))
30 changes: 6 additions & 24 deletions Makefile
@@ -1,31 +1,13 @@
DIRS = lib sockets advio call calld daemons datafiles db environ exercises \
file ipc ipp lock mycat open opend opend.fe open.fe proc pty \
sess signals std stdio streams termios threadctl threads
DIRS = lib intro sockets advio daemons datafiles db environ \
fileio filedir ipc1 ipc2 proc pty relation signals standards \
stdio termios threadctl threads printer exercises

all:
$(MAKE) `./systype.sh`

clean:
for i in $(DIRS); do \
(cd $$i && $(MAKE) -f `../systype.sh`.mk clean) || exit 1; \
done

freebsd:
for i in $(DIRS); do \
(cd $$i && $(MAKE) -f freebsd.mk) || exit 1; \
done

linux:
for i in $(DIRS); do \
(cd $$i && $(MAKE) -f linux.mk) || exit 1; \
done

macos:
for i in $(DIRS); do \
(cd $$i && $(MAKE) -f macos.mk) || exit 1; \
(cd $$i && echo "making $$i" && $(MAKE) ) || exit 1; \
done

solaris:
clean:
for i in $(DIRS); do \
(cd $$i && $(MAKE) -f solaris.mk) || exit 1; \
(cd $$i && echo "cleaning $$i" && $(MAKE) clean) || exit 1; \
done
26 changes: 3 additions & 23 deletions README
@@ -1,30 +1,10 @@
Read the file called DISCLAIMER.

Some source changes needed to be made after the book went out for the first
printing. I forgot to make corresponding changes in the source tree on the
system used to develop the book. The changes are summarized below.

1. lib/recvfd.c and sockets/recvfd.c - needed sys/uio.h on Mac OS X
2. lib/sendfd.c and sockets/sendfd.c - needed sys/uio.h on Mac OS X
3. stdio/buf.c - added code for Mac OS X
4. threadctl/suspend.c - changed wait to waitloc to avoid symbol definition
clash on Solaris
5. include/apue.h - FreeBSD compiles work better if we rely on the default
system settings. Solaris needed a different XOPEN_SOURCE definition
and also a CMSG_LEN definition.

To build the source, edit the Make.defines.* file for your system and set
WKDIR to the pathname of the tree containing the source code. Then just
run "make". It should figure out the system type and build the source for
that platform automatically. If you are running on a system other than
FreeBSD, Linux, Mac OS X, or Solaris, you'll need to modify the makefiles
to include the settings for your system. Also, you'll probably need to
modify the source code to get it to build on a different operating system.
The example source was compiled and tested using FreeBSD 5.2.1, Linux 2.4.22,
Mac OS X 10.3, and Solaris 9.
On Freebsd, type "gmake".
On other platforms, type "make" (as long as this is gnu make).

For FAQs, updated source code, and the lost chapter, see http://www.apuebook.com.
Please direct questions, suggestions, and bug reports to sar@apuebook.com.

Steve Rago
May 30, 2005
January 2013
29 changes: 29 additions & 0 deletions advio/Makefile
@@ -0,0 +1,29 @@
ROOT=..
PLATFORM=$(shell $(ROOT)/systype.sh)
include $(ROOT)/Make.defines.$(PLATFORM)

ifeq "$(PLATFORM)" "linux"
EXTRALIBS=-lrt
endif
ifeq "$(PLATFORM)" "solaris"
EXTRALIBS=-lrt
endif

PROGS = deadlock mandatory mcopy2 nonblockw rot13a
MOREPROGS = rot13c2

all: $(PROGS) $(MOREPROGS) lockfile.o

rot13c2.c: rot13c2.c.in $(LIBAPUE)
./fixup.awk rot13a.c >xlate
sed '/same/q' rot13c2.c.in >rot13c2.c
cat xlate >>rot13c2.c
sed '1,/same/d' rot13c2.c.in >>rot13c2.c

%: %.c $(LIBAPUE)
$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) $(LDLIBS)

clean:
rm -f $(PROGS) $(MOREPROGS) $(TEMPFILES) *.o xlate rot13c2.c

include $(ROOT)/Make.libapue.inc
41 changes: 41 additions & 0 deletions advio/deadlock.c
@@ -0,0 +1,41 @@
#include "apue.h"
#include <fcntl.h>

static void
lockabyte(const char *name, int fd, off_t offset)
{
if (writew_lock(fd, offset, SEEK_SET, 1) < 0)
err_sys("%s: writew_lock error", name);
printf("%s: got the lock, byte %lld\n", name, (long long)offset);
}

int
main(void)
{
int fd;
pid_t pid;

/*
* Create a file and write two bytes to it.
*/
if ((fd = creat("templock", FILE_MODE)) < 0)
err_sys("creat error");
if (write(fd, "ab", 2) != 2)
err_sys("write error");

TELL_WAIT();
if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid == 0) { /* child */
lockabyte("child", fd, 0);
TELL_PARENT(getppid());
WAIT_PARENT();
lockabyte("child", fd, 1);
} else { /* parent */
lockabyte("parent", fd, 1);
TELL_CHILD(pid);
WAIT_CHILD();
lockabyte("parent", fd, 0);
}
exit(0);
}
19 changes: 19 additions & 0 deletions advio/fixup.awk
@@ -0,0 +1,19 @@
#!/usr/bin/awk -f
BEGIN {
ready = 0
}
/^translate/ {
ready = 1
next
}
/^{/ {
next
}
/^}/ {
ready = 0
next
}
{
if (ready)
print $0
}
14 changes: 14 additions & 0 deletions advio/lockfile.c
@@ -0,0 +1,14 @@
#include <unistd.h>
#include <fcntl.h>

int
lockfile(int fd)
{
struct flock fl;

fl.l_type = F_WRLCK;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_len = 0;
return(fcntl(fd, F_SETLK, &fl));
}
63 changes: 63 additions & 0 deletions advio/mandatory.c
@@ -0,0 +1,63 @@
#include "apue.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/wait.h>

int
main(int argc, char *argv[])
{
int fd;
pid_t pid;
char buf[5];
struct stat statbuf;

if (argc != 2) {
fprintf(stderr, "usage: %s filename\n", argv[0]);
exit(1);
}
if ((fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, FILE_MODE)) < 0)
err_sys("open error");
if (write(fd, "abcdef", 6) != 6)
err_sys("write error");

/* turn on set-group-ID and turn off group-execute */
if (fstat(fd, &statbuf) < 0)
err_sys("fstat error");
if (fchmod(fd, (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)
err_sys("fchmod error");

TELL_WAIT();

if ((pid = fork()) < 0) {
err_sys("fork error");
} else if (pid > 0) { /* parent */
/* write lock entire file */
if (write_lock(fd, 0, SEEK_SET, 0) < 0)
err_sys("write_lock error");

TELL_CHILD(pid);

if (waitpid(pid, NULL, 0) < 0)
err_sys("waitpid error");
} else { /* child */
WAIT_PARENT(); /* wait for parent to set lock */

set_fl(fd, O_NONBLOCK);

/* first let's see what error we get if region is locked */
if (read_lock(fd, 0, SEEK_SET, 0) != -1) /* no wait */
err_sys("child: read_lock succeeded");
printf("read_lock of already-locked region returns %d\n",
errno);

/* now try to read the mandatory locked file */
if (lseek(fd, 0, SEEK_SET) == -1)
err_sys("lseek error");
if (read(fd, buf, 2) < 0)
err_ret("read failed (mandatory locking works)");
else
printf("read OK (no mandatory locking), buf = %2.2s\n",
buf);
}
exit(0);
}

0 comments on commit 0ae1f03

Please sign in to comment.