Team BBL
Previous Page Next Page

B.1. Our Header File

Most programs in the text include the header apue.h, shown in Figure B.1. It defines constants (such as MAXLINE) and prototypes for our own functions.

Figure B.1. Our header: apue.h
/* Our own header, to be included before all standard system headers */

#ifndef _APUE_H
#define _APUE_H

#define _XOPEN_SOURCE   600  /* Single UNIX Specification, Version 3 */

#include <sys/types.h>       /* some systems still require this */
#include <sys/stat.h>
#include <sys/termios.h>     /* for winsize */
#ifndef TIOCGWINSZ
#include <sys/ioctl.h>
#endif
#include <stdio.h>     /* for convenience */
#include <stdlib.h>    /* for convenience */
#include <stddef.h>    /* for offsetof */
#include <string.h>    /* for convenience */
#include <unistd.h>    /* for convenience */
#include <signal.h>    /* for SIG_ERR */


#define MAXLINE 4096               /* max line length */

/*
 * Default file access permissions for new files.
 */
#define FILE_MODE   (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

/*
 * Default permissions for new directories.
 */
#define DIR_MODE    (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)

typedef void   Sigfunc(int);   /* for signal handlers */

#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR ((Sigfunc *)-1)
#endif

#define min(a,b)     ((a) < (b) ? (a) : (b))
#define max(a,b)     ((a) > (b) ? (a) : (b))

/*
 * Prototypes for our own functions.
 */
char    *path_alloc(int *);              /* Figure 2.15 */
long     open_max(void);                 /* Figure 2.16 */
void     clr_fl(int, int);               /* Figure 3.11 */
void     set_fl(int, int);               /* Figure 3.11 */
void     pr_exit(int);                   /* Figure 8.5 */
void     pr_mask(const char *);          /* Figure 10.14 */
Sigfunc *signal_intr(int, Sigfunc *);    /* Figure 10.19 */

int      tty_cbreak(int);                /* Figure 18.20 */
int      tty_raw(int);                   /* Figure 18.20 */
int      tty_reset(int);                 /* Figure 18.20 */
void     tty_atexit(void);               /* Figure 18.20 */
#ifdef  ECHO    /* only if <termios.h>  has been included */
struct termios  *tty_termios(void);      /* Figure 18.20 */
#endif

void     sleep_us(unsigned int);             /* Exercise 14.6 */
ssize_t  readn(int, void *, size_t);         /* Figure 14.29 */
ssize_t  writen(int, const void *, size_t);  /* Figure 14.29 */
void     daemonize(const char *);            /* Figure 13.1 */

int      s_pipe(int *);                 /* Figures 17.6 and 17.13 */
int      recv_fd(int, ssize_t (*func)(int,
                 const void *, size_t));/* Figures 17.21 and 17.23 */
int      send_fd(int, int);             /* Figures 17.20 and 17.22 */
int      send_err(int, int,
                  const char *);        /* Figure 17.19 */
int      serv_listen(const char *);     /* Figures 17.10 and 17.15 */
int      serv_accept(int, uid_t *);     /* Figures 17.11 and 17.16 */

int      cli_conn(const char *);        /* Figures 17.12 and 17.17 */
int      buf_args(char *, int (*func)(int,
                  char **));            /* Figure 17.32 */

int      ptym_open(char *, int);    /* Figures 19.8, 19.9, and 19.10 */
int      ptys_open(char *);         /* Figures 19.8, 19.9, and 19.10 */
#ifdef  TIOCGWINSZ
pid_t    pty_fork(int *, char *, int, const struct termios *,
                  const struct winsize *);      /* Figure 19.11 */
#endif

int     lock_reg(int, int, int, off_t, int, off_t); /* Figure 14.5 */
#define read_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len))
#define readw_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len))
#define write_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len))
#define writew_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len))
#define un_lock(fd, offset, whence, len) \
            lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len))

pid_t   lock_test(int, int, off_t, int, off_t);     /* Figure 14.6 */

#define is_read_lockable(fd, offset, whence, len) \
            (lock_test((fd), F_RDLCK, (offset), (whence), (len)) == 0)
#define is_write_lockable(fd, offset, whence, len) \
            (lock_test((fd), F_WRLCK, (offset), (whence), (len)) == 0)

void    err_dump(const char *, ...);        /* Appendix B */
void    err_msg(const char *, ...);
void    err_quit(const char *, ...);
void    err_exit(int, const char *, ...);
void    err_ret(const char *, ...);
void    err_sys(const char *, ...);

void    log_msg(const char *, ...);         /* Appendix B */
void    log_open(const char *, int, int);
void    log_quit(const char *, ...);
void    log_ret(const char *, ...);
void    log_sys(const char *, ...);

void    TELL_WAIT(void);        /* parent/child from Section 8.9 */
void    TELL_PARENT(pid_t);
void    TELL_CHILD(pid_t);
void    WAIT_PARENT(void);
void    WAIT_CHILD(void);

#endif  /* _APUE_H */

Most programs need to include the following headers: <stdio.h>, <stdlib.h> (for the exit function prototype), and <unistd.h> (for all the standard UNIX function prototypes). So our header automatically includes these system headers, along with <string.h>. This also reduces the size of all the program listings in the text.

The reasons we include our header before all the normal system headers are to allow us to define anything that might be required by headers before they are included, control the order in which header files are included, and allow us to redefine anything that needs to be fixed up to hide the differences between systems.

    Team BBL
    Previous Page Next Page