.P
.\" SRC BEGIN (bind.c)
.EX
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MY_SOCK_PATH "/somepath"
#define LISTEN_BACKLOG 50
\&
-#define handle_error(msg) \[rs]
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
int
main(void)
{
\&
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == \-1)
- handle_error("socket");
+ err(EXIT_FAILURE, "socket");
\&
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sun_family = AF_UNIX;
\&
if (bind(sfd, (struct sockaddr *) &my_addr,
sizeof(my_addr)) == \-1)
- handle_error("bind");
+ err(EXIT_FAILURE, "bind");
\&
if (listen(sfd, LISTEN_BACKLOG) == \-1)
- handle_error("listen");
+ err(EXIT_FAILURE, "listen");
\&
/* Now we can accept incoming connections one
at a time using accept(2). */
cfd = accept(sfd, (struct sockaddr *) &peer_addr,
&peer_addr_size);
if (cfd == \-1)
- handle_error("accept");
+ err(EXIT_FAILURE, "accept");
\&
/* Code to deal with incoming connection(s)... */
\&
if (close(sfd) == \-1)
- handle_error("close");
+ err(EXIT_FAILURE, "close");
\&
if (unlink(MY_SOCK_PATH) == \-1)
- handle_error("unlink");
+ err(EXIT_FAILURE, "unlink");
}
.EE
.\" SRC END
.SS Program source
.\" SRC BEGIN (mmap.c)
.EX
+#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
\&
-#define handle_error(msg) \[rs]
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
int
main(int argc, char *argv[])
{
\&
fd = open(argv[1], O_RDONLY);
if (fd == \-1)
- handle_error("open");
+ err(EXIT_FAILURE, "open");
\&
if (fstat(fd, &sb) == \-1) /* To obtain file size */
- handle_error("fstat");
+ err(EXIT_FAILURE, "fstat");
\&
offset = atoi(argv[2]);
pa_offset = offset & \[ti](sysconf(_SC_PAGE_SIZE) \- 1);
addr = mmap(NULL, length + offset \- pa_offset, PROT_READ,
MAP_PRIVATE, fd, pa_offset);
if (addr == MAP_FAILED)
- handle_error("mmap");
+ err(EXIT_FAILURE, "mmap");
\&
s = write(STDOUT_FILENO, addr + offset \- pa_offset, length);
if (s != length) {
if (s == \-1)
- handle_error("write");
+ err(EXIT_FAILURE, "write");
\&
fprintf(stderr, "partial write");
exit(EXIT_FAILURE);
\&
.\" SRC BEGIN (mprotect.c)
.EX
+#include <err.h>
#include <malloc.h>
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
\&
-#define handle_error(msg) \[rs]
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
static char *buffer;
\&
static void
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = handler;
if (sigaction(SIGSEGV, &sa, NULL) == \-1)
- handle_error("sigaction");
+ err(EXIT_FAILURE, "sigaction");
\&
pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == \-1)
- handle_error("sysconf");
+ err(EXIT_FAILURE, "sysconf");
\&
/* Allocate a buffer aligned on a page boundary;
initial protection is PROT_READ | PROT_WRITE. */
\&
buffer = memalign(pagesize, 4 * pagesize);
if (buffer == NULL)
- handle_error("memalign");
+ err(EXIT_FAILURE, "memalign");
\&
printf("Start of region: %p\[rs]n", buffer);
\&
if (mprotect(buffer + pagesize * 2, pagesize,
PROT_READ) == \-1)
- handle_error("mprotect");
+ err(EXIT_FAILURE, "mprotect");
\&
for (char *p = buffer ; ; )
*(p++) = \[aq]a\[aq];
\&
Licensed under GNU General Public License v2 or later.
*/
+#include <err.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \[rs]
- } while (0)
-\&
int
main(int argc, char *argv[])
{
num_open_fds = nfds = argc \- 1;
pfds = calloc(nfds, sizeof(struct pollfd));
if (pfds == NULL)
- errExit("malloc");
+ err(EXIT_FAILURE, "malloc");
\&
/* Open each file on command line, and add it to \[aq]pfds\[aq] array. */
\&
for (nfds_t j = 0; j < nfds; j++) {
pfds[j].fd = open(argv[j + 1], O_RDONLY);
if (pfds[j].fd == \-1)
- errExit("open");
+ err(EXIT_FAILURE, "open");
\&
printf("Opened \[rs]"%s\[rs]" on fd %d\[rs]n", argv[j + 1], pfds[j].fd);
\&
printf("About to poll()\[rs]n");
ready = poll(pfds, nfds, \-1);
if (ready == \-1)
- errExit("poll");
+ err(EXIT_FAILURE, "poll");
\&
printf("Ready: %d\[rs]n", ready);
\&
if (pfds[j].revents & POLLIN) {
s = read(pfds[j].fd, buf, sizeof(buf));
if (s == \-1)
- errExit("read");
+ err(EXIT_FAILURE, "read");
printf(" read %zd bytes: %.*s\[rs]n",
s, (int) s, buf);
} else { /* POLLERR | POLLHUP */
printf(" closing fd %d\[rs]n", pfds[j].fd);
if (close(pfds[j].fd) == \-1)
- errExit("close");
+ err(EXIT_FAILURE, "close");
num_open_fds\-\-;
}
}
#ifndef SVSHM_STRING_H
#define SVSHM_STRING_H
\&
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sem.h>
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \[rs]
- } while (0)
-\&
union semun { /* Used in calls to semctl() */
int val;
struct semid_ds *buf;
\&
shmid = shmget(IPC_PRIVATE, MEM_SIZE, IPC_CREAT | 0600);
if (shmid == \-1)
- errExit("shmget");
+ err(EXIT_FAILURE, "shmget");
\&
semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
if (semid == \-1)
- errExit("semget");
+ err(EXIT_FAILURE, "semget");
\&
/* Attach shared memory into our address space. */
\&
addr = shmat(shmid, NULL, SHM_RDONLY);
if (addr == (void *) \-1)
- errExit("shmat");
+ err(EXIT_FAILURE, "shmat");
\&
/* Initialize semaphore 0 in set with value 1. */
\&
arg.val = 1;
if (semctl(semid, 0, SETVAL, arg) == \-1)
- errExit("semctl");
+ err(EXIT_FAILURE, "semctl");
\&
printf("shmid = %d; semid = %d\[rs]n", shmid, semid);
\&
sop.sem_flg = 0;
\&
if (semop(semid, &sop, 1) == \-1)
- errExit("semop");
+ err(EXIT_FAILURE, "semop");
\&
/* Print the string from shared memory. */
\&
/* Remove shared memory and semaphore set. */
\&
if (shmctl(shmid, IPC_RMID, NULL) == \-1)
- errExit("shmctl");
+ err(EXIT_FAILURE, "shmctl");
if (semctl(semid, 0, IPC_RMID, dummy) == \-1)
- errExit("semctl");
+ err(EXIT_FAILURE, "semctl");
\&
exit(EXIT_SUCCESS);
}
\&
addr = shmat(shmid, NULL, 0);
if (addr == (void *) \-1)
- errExit("shmat");
+ err(EXIT_FAILURE, "shmat");
\&
memcpy(addr, argv[3], size);
\&
sop.sem_flg = 0;
\&
if (semop(semid, &sop, 1) == \-1)
- errExit("semop");
+ err(EXIT_FAILURE, "semop");
\&
exit(EXIT_SUCCESS);
}
\&
.\" SRC BEGIN (timer_create.c)
.EX
+#include <err.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#define CLOCKID CLOCK_REALTIME
#define SIG SIGRTMIN
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \[rs]
- } while (0)
-\&
static void
print_siginfo(siginfo_t *si)
{
\&
or = timer_getoverrun(*tidp);
if (or == \-1)
- errExit("timer_getoverrun");
- else
- printf(" overrun count = %d\[rs]n", or);
+ err(EXIT_FAILURE, "timer_getoverrun");
+\&
+ printf(" overrun count = %d\[rs]n", or);
}
\&
static void
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIG, &sa, NULL) == \-1)
- errExit("sigaction");
+ err(EXIT_FAILURE, "sigaction");
\&
/* Block timer signal temporarily. */
\&
sigemptyset(&mask);
sigaddset(&mask, SIG);
if (sigprocmask(SIG_SETMASK, &mask, NULL) == \-1)
- errExit("sigprocmask");
+ err(EXIT_FAILURE, "sigprocmask");
\&
/* Create the timer. */
\&
sev.sigev_signo = SIG;
sev.sigev_value.sival_ptr = &timerid;
if (timer_create(CLOCKID, &sev, &timerid) == \-1)
- errExit("timer_create");
+ err(EXIT_FAILURE, "timer_create");
\&
printf("timer ID is %#jx\[rs]n", (uintmax_t) timerid);
\&
its.it_interval.tv_nsec = its.it_value.tv_nsec;
\&
if (timer_settime(timerid, 0, &its, NULL) == \-1)
- errExit("timer_settime");
+ err(EXIT_FAILURE, "timer_settime");
\&
/* Sleep for a while; meanwhile, the timer may expire
multiple times. */
\&
printf("Unblocking signal %d\[rs]n", SIG);
if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == \-1)
- errExit("sigprocmask");
+ err(EXIT_FAILURE, "sigprocmask");
\&
exit(EXIT_SUCCESS);
}
.EX
#define _XOPEN_SOURCE 700
#include <ctype.h>
+#include <err.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \[rs]
- } while (0)
-\&
int
main(int argc, char *argv[])
{
\&
loc = uselocale((locale_t) 0);
if (loc == (locale_t) 0)
- errExit("uselocale");
+ err(EXIT_FAILURE, "uselocale");
\&
nloc = duplocale(loc);
if (nloc == (locale_t) 0)
- errExit("duplocale");
+ err(EXIT_FAILURE, "duplocale");
\&
for (char *p = argv[1]; *p; p++)
putchar(toupper_l(*p, nloc));
/* Link with "\-lresolv" */
\&
#include <arpa/inet.h>
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \[rs]
- } while (0)
-\&
int
main(int argc, char *argv[])
{
\&
bits = inet_net_pton(AF_INET, argv[1], &addr, sizeof(addr));
if (bits == \-1)
- errExit("inet_net_ntop");
+ err(EXIT_FAILURE, "inet_net_ntop");
\&
printf("inet_net_pton() returned: %d\[rs]n", bits);
\&
returned by inet_net_pton(). */
\&
if (inet_net_ntop(AF_INET, &addr, bits, buf, sizeof(buf)) == NULL)
- errExit("inet_net_ntop");
+ err(EXIT_FAILURE, "inet_net_ntop");
\&
printf("inet_net_ntop() yielded: %s\[rs]n", buf);
\&
\&
.\" SRC BEGIN (makecontext.c)
.EX
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
\&
static ucontext_t uctx_main, uctx_func1, uctx_func2;
\&
-#define handle_error(msg) \[rs]
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
static void
func1(void)
{
printf("%s: started\[rs]n", __func__);
printf("%s: swapcontext(&uctx_func1, &uctx_func2)\[rs]n", __func__);
if (swapcontext(&uctx_func1, &uctx_func2) == \-1)
- handle_error("swapcontext");
+ err(EXIT_FAILURE, "swapcontext");
printf("%s: returning\[rs]n", __func__);
}
\&
printf("%s: started\[rs]n", __func__);
printf("%s: swapcontext(&uctx_func2, &uctx_func1)\[rs]n", __func__);
if (swapcontext(&uctx_func2, &uctx_func1) == \-1)
- handle_error("swapcontext");
+ err(EXIT_FAILURE, "swapcontext");
printf("%s: returning\[rs]n", __func__);
}
\&
char func2_stack[16384];
\&
if (getcontext(&uctx_func1) == \-1)
- handle_error("getcontext");
+ err(EXIT_FAILURE, "getcontext");
uctx_func1.uc_stack.ss_sp = func1_stack;
uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
uctx_func1.uc_link = &uctx_main;
makecontext(&uctx_func1, func1, 0);
\&
if (getcontext(&uctx_func2) == \-1)
- handle_error("getcontext");
+ err(EXIT_FAILURE, "getcontext");
uctx_func2.uc_stack.ss_sp = func2_stack;
uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
/* Successor context is f1(), unless argc > 1 */
\&
printf("%s: swapcontext(&uctx_main, &uctx_func2)\[rs]n", __func__);
if (swapcontext(&uctx_main, &uctx_func2) == \-1)
- handle_error("swapcontext");
+ err(EXIT_FAILURE, "swapcontext");
\&
printf("%s: exiting\[rs]n", __func__);
exit(EXIT_SUCCESS);
\&
.\" SRC BEGIN (mq_getattr.c)
.EX
+#include <err.h>
#include <fcntl.h>
#include <mqueue.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \[rs]
- } while (0)
-\&
int
main(int argc, char *argv[])
{
\&
mqd = mq_open(argv[1], O_CREAT | O_EXCL, 0600, NULL);
if (mqd == (mqd_t) \-1)
- errExit("mq_open");
+ err(EXIT_FAILURE, "mq_open");
\&
if (mq_getattr(mqd, &attr) == \-1)
- errExit("mq_getattr");
+ err(EXIT_FAILURE, "mq_getattr");
\&
printf("Maximum # of messages on queue: %ld\[rs]n", attr.mq_maxmsg);
printf("Maximum message size: %ld\[rs]n", attr.mq_msgsize);
\&
if (mq_unlink(argv[1]) == \-1)
- errExit("mq_unlink");
+ err(EXIT_FAILURE, "mq_unlink");
\&
exit(EXIT_SUCCESS);
}
.SS Program source
.\" SRC BEGIN (mq_notify.c)
.EX
+#include <err.h>
#include <mqueue.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
\&
-#define handle_error(msg) \[rs]
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
static void /* Thread start function */
tfunc(union sigval sv)
{
/* Determine max. msg size; allocate buffer to receive msg */
\&
if (mq_getattr(mqdes, &attr) == \-1)
- handle_error("mq_getattr");
+ err(EXIT_FAILURE, "mq_getattr");
buf = malloc(attr.mq_msgsize);
if (buf == NULL)
- handle_error("malloc");
+ err(EXIT_FAILURE, "malloc");
\&
nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
if (nr == \-1)
- handle_error("mq_receive");
+ err(EXIT_FAILURE, "mq_receive");
\&
printf("Read %zd bytes from MQ\[rs]n", nr);
free(buf);
\&
mqdes = mq_open(argv[1], O_RDONLY);
if (mqdes == (mqd_t) \-1)
- handle_error("mq_open");
+ err(EXIT_FAILURE, "mq_open");
\&
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = tfunc;
sev.sigev_notify_attributes = NULL;
sev.sigev_value.sival_ptr = &mqdes; /* Arg. to thread func. */
if (mq_notify(mqdes, &sev) == \-1)
- handle_error("mq_notify");
+ err(EXIT_FAILURE, "mq_notify");
\&
pause(); /* Process will be terminated by thread function */
}
.\" SRC BEGIN (newlocale.c)
.EX
#define _XOPEN_SOURCE 700
+#include <err.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \[rs]
- } while (0)
-\&
int
main(int argc, char *argv[])
{
\&
loc = newlocale(LC_NUMERIC_MASK, argv[1], (locale_t) 0);
if (loc == (locale_t) 0)
- errExit("newlocale");
+ err(EXIT_FAILURE, "newlocale");
\&
/* If a second command\-line argument was specified, modify the
locale object to take the LC_TIME settings from the locale
if (argc > 2) {
nloc = newlocale(LC_TIME_MASK, argv[2], loc);
if (nloc == (locale_t) 0)
- errExit("newlocale");
+ err(EXIT_FAILURE, "newlocale");
loc = nloc;
}
\&
t = time(NULL);
tm = localtime(&t);
if (tm == NULL)
- errExit("time");
+ err(EXIT_FAILURE, "time");
\&
s = strftime(buf, sizeof(buf), "%c", tm);
if (s == 0)
- errExit("strftime");
+ err(EXIT_FAILURE, "strftime");
\&
printf("%s\[rs]n", buf);
\&
\&
.\" SRC BEGIN (posix_spawn.c)
.EX
+#include <err.h>
#include <errno.h>
#include <spawn.h>
#include <stdint.h>
#include <unistd.h>
#include <wait.h>
\&
-#define errExit(msg) do { perror(msg); \[rs]
- exit(EXIT_FAILURE); } while (0)
-\&
-#define errExitEN(en, msg) \[rs]
- do { errno = en; perror(msg); \[rs]
- exit(EXIT_FAILURE); } while (0)
-\&
char **environ;
\&
int
\&
s = posix_spawn_file_actions_init(&file_actions);
if (s != 0)
- errExitEN(s, "posix_spawn_file_actions_init");
+ errc(EXIT_FAILURE, s, "posix_spawn_file_actions_init");
\&
s = posix_spawn_file_actions_addclose(&file_actions,
STDOUT_FILENO);
if (s != 0)
- errExitEN(s, "posix_spawn_file_actions_addclose");
+ errc(EXIT_FAILURE, s, "posix_spawn_file_actions_addclose");
\&
file_actionsp = &file_actions;
break;
\&
s = posix_spawnattr_init(&attr);
if (s != 0)
- errExitEN(s, "posix_spawnattr_init");
+ errc(EXIT_FAILURE, s, "posix_spawnattr_init");
s = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGMASK);
if (s != 0)
- errExitEN(s, "posix_spawnattr_setflags");
+ errc(EXIT_FAILURE, s, "posix_spawnattr_setflags");
\&
sigfillset(&mask);
s = posix_spawnattr_setsigmask(&attr, &mask);
if (s != 0)
- errExitEN(s, "posix_spawnattr_setsigmask");
+ errc(EXIT_FAILURE, s, "posix_spawnattr_setsigmask");
\&
attrp = &attr;
break;
s = posix_spawnp(&child_pid, argv[optind], file_actionsp, attrp,
&argv[optind], environ);
if (s != 0)
- errExitEN(s, "posix_spawn");
+ errc(EXIT_FAILURE, s, "posix_spawn");
\&
/* Destroy any objects that we created earlier. */
\&
if (attrp != NULL) {
s = posix_spawnattr_destroy(attrp);
if (s != 0)
- errExitEN(s, "posix_spawnattr_destroy");
+ errc(EXIT_FAILURE, s, "posix_spawnattr_destroy");
}
\&
if (file_actionsp != NULL) {
s = posix_spawn_file_actions_destroy(file_actionsp);
if (s != 0)
- errExitEN(s, "posix_spawn_file_actions_destroy");
+ errc(EXIT_FAILURE, s, "posix_spawn_file_actions_destroy");
}
\&
printf("PID of child: %jd\[rs]n", (intmax_t) child_pid);
do {
s = waitpid(child_pid, &status, WUNTRACED | WCONTINUED);
if (s == \-1)
- errExit("waitpid");
+ err(EXIT_FAILURE, "waitpid");
\&
printf("Child status: ");
if (WIFEXITED(status)) {
\&
.\" SRC BEGIN (pthread_cancel.c)
.EX
+#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
\&
-#define handle_error_en(en, msg) \[rs]
- do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
static void *
thread_func(void *ignored_argument)
{
\&
s = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (s != 0)
- handle_error_en(s, "pthread_setcancelstate");
+ errc(EXIT_FAILURE, s, "pthread_setcancelstate");
\&
printf("%s(): started; cancelation disabled\[rs]n", __func__);
sleep(5);
\&
s = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (s != 0)
- handle_error_en(s, "pthread_setcancelstate");
+ errc(EXIT_FAILURE, s, "pthread_setcancelstate");
\&
/* sleep() is a cancelation point. */
\&
\&
s = pthread_create(&thr, NULL, &thread_func, NULL);
if (s != 0)
- handle_error_en(s, "pthread_create");
+ errc(EXIT_FAILURE, s, "pthread_create");
\&
sleep(2); /* Give thread a chance to get started */
\&
printf("%s(): sending cancelation request\[rs]n", __func__);
s = pthread_cancel(thr);
if (s != 0)
- handle_error_en(s, "pthread_cancel");
+ errc(EXIT_FAILURE, s, "pthread_cancel");
\&
/* Join with thread to see what its exit status was. */
\&
s = pthread_join(thr, &res);
if (s != 0)
- handle_error_en(s, "pthread_join");
+ errc(EXIT_FAILURE, s, "pthread_join");
\&
if (res == PTHREAD_CANCELED)
printf("%s(): thread was canceled\[rs]n", __func__);
\&
.\" SRC BEGIN (pthread_cleanup_push.c)
.EX
+#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
\&
-#define handle_error_en(en, msg) \[rs]
- do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
static int done = 0;
static int cleanup_pop_arg = 0;
static int cnt = 0;
\&
s = pthread_create(&thr, NULL, thread_start, NULL);
if (s != 0)
- handle_error_en(s, "pthread_create");
+ errc(EXIT_FAILURE, s, "pthread_create");
\&
sleep(2); /* Allow new thread to run a while */
\&
printf("Canceling thread\[rs]n");
s = pthread_cancel(thr);
if (s != 0)
- handle_error_en(s, "pthread_cancel");
+ errc(EXIT_FAILURE, s, "pthread_cancel");
}
\&
s = pthread_join(thr, &res);
if (s != 0)
- handle_error_en(s, "pthread_join");
+ errc(EXIT_FAILURE, s, "pthread_join");
\&
if (res == PTHREAD_CANCELED)
printf("Thread was canceled; cnt = %d\[rs]n", cnt);
.\" SRC BEGIN (pthread_create.c)
.EX
#include <ctype.h>
+#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
\&
-#define handle_error_en(en, msg) \[rs]
- do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
-#define handle_error(msg) \[rs]
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
struct thread_info { /* Used as argument to thread_start() */
pthread_t thread_id; /* ID returned by pthread_create() */
int thread_num; /* Application\-defined thread # */
\&
uargv = strdup(tinfo\->argv_string);
if (uargv == NULL)
- handle_error("strdup");
+ err(EXIT_FAILURE, "strdup");
\&
for (char *p = uargv; *p != \[aq]\[rs]0\[aq]; p++)
*p = toupper(*p);
\&
s = pthread_attr_init(&attr);
if (s != 0)
- handle_error_en(s, "pthread_attr_init");
+ errc(EXIT_FAILURE, s, "pthread_attr_init");
\&
if (stack_size > 0) {
s = pthread_attr_setstacksize(&attr, stack_size);
if (s != 0)
- handle_error_en(s, "pthread_attr_setstacksize");
+ errc(EXIT_FAILURE, s, "pthread_attr_setstacksize");
}
\&
/* Allocate memory for pthread_create() arguments. */
\&
tinfo = calloc(num_threads, sizeof(*tinfo));
if (tinfo == NULL)
- handle_error("calloc");
+ err(EXIT_FAILURE, "calloc");
\&
/* Create one thread for each command\-line argument. */
\&
s = pthread_create(&tinfo[tnum].thread_id, &attr,
&thread_start, &tinfo[tnum]);
if (s != 0)
- handle_error_en(s, "pthread_create");
+ errc(EXIT_FAILURE, s, "pthread_create");
}
\&
/* Destroy the thread attributes object, since it is no
\&
s = pthread_attr_destroy(&attr);
if (s != 0)
- handle_error_en(s, "pthread_attr_destroy");
+ errc(EXIT_FAILURE, s, "pthread_attr_destroy");
\&
/* Now join with each thread, and display its returned value. */
\&
for (size_t tnum = 0; tnum < num_threads; tnum++) {
s = pthread_join(tinfo[tnum].thread_id, &res);
if (s != 0)
- handle_error_en(s, "pthread_join");
+ errc(EXIT_FAILURE, s, "pthread_join");
\&
printf("Joined with thread %d; returned value was %s\[rs]n",
tinfo[tnum].thread_num, (char *) res);
.EX
/* Link with "\-lrt" */
\&
+#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
\&
-#define handle_error(msg) \[rs]
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
-#define handle_error_en(en, msg) \[rs]
- do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
static void *
thread_start(void *arg)
{
\&
printf("%s", msg);
if (clock_gettime(cid, &ts) == \-1)
- handle_error("clock_gettime");
+ err(EXIT_FAILURE, "clock_gettime");
printf("%4jd.%03ld\[rs]n", (intmax_t) ts.tv_sec, ts.tv_nsec / 1000000);
}
\&
\&
s = pthread_create(&thread, NULL, thread_start, NULL);
if (s != 0)
- handle_error_en(s, "pthread_create");
+ errc(EXIT_FAILURE, s, "pthread_create");
\&
printf("Main thread sleeping\[rs]n");
sleep(1);
\&
s = pthread_getcpuclockid(pthread_self(), &cid);
if (s != 0)
- handle_error_en(s, "pthread_getcpuclockid");
+ errc(EXIT_FAILURE, s, "pthread_getcpuclockid");
pclock("Main thread CPU time: ", cid);
\&
/* The preceding 4 lines of code could have been replaced by:
\&
s = pthread_getcpuclockid(thread, &cid);
if (s != 0)
- handle_error_en(s, "pthread_getcpuclockid");
+ errc(EXIT_FAILURE, s, "pthread_getcpuclockid");
pclock("Subthread CPU time: 1 ", cid);
\&
exit(EXIT_SUCCESS); /* Terminates both threads */
.SS Program source
.\" SRC BEGIN (pthread_mutexattr_setrobust.c)
.EX
+#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
\&
-#define handle_error_en(en, msg) \[rs]
- do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
static pthread_mutex_t mtx;
\&
static void *
printf("[main] Now make the mutex consistent\[rs]n");
s = pthread_mutex_consistent(&mtx);
if (s != 0)
- handle_error_en(s, "pthread_mutex_consistent");
+ errc(EXIT_FAILURE, s, "pthread_mutex_consistent");
printf("[main] Mutex is now consistent; unlocking\[rs]n");
s = pthread_mutex_unlock(&mtx);
if (s != 0)
- handle_error_en(s, "pthread_mutex_unlock");
+ errc(EXIT_FAILURE, s, "pthread_mutex_unlock");
\&
exit(EXIT_SUCCESS);
} else if (s == 0) {
exit(EXIT_FAILURE);
} else {
printf("[main] pthread_mutex_lock() unexpectedly failed\[rs]n");
- handle_error_en(s, "pthread_mutex_lock");
+ errc(EXIT_FAILURE, s, "pthread_mutex_lock");
}
}
.EE
.EX
/* pthreads_sched_test.c */
\&
+#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
\&
-#define handle_error_en(en, msg) \[rs]
- do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
[[noreturn]]
static void
usage(char *prog_name, char *msg)
\&
s = pthread_getschedparam(pthread_self(), &policy, ¶m);
if (s != 0)
- handle_error_en(s, "pthread_getschedparam");
+ errc(EXIT_FAILURE, s, "pthread_getschedparam");
\&
printf("%s\[rs]n", msg);
display_sched_attr(policy, ¶m);
\&
s = pthread_setschedparam(pthread_self(), policy, ¶m);
if (s != 0)
- handle_error_en(s, "pthread_setschedparam");
+ errc(EXIT_FAILURE, s, "pthread_setschedparam");
}
\&
display_thread_sched_attr("Scheduler settings of main thread");
if (!use_null_attrib) {
s = pthread_attr_init(&attr);
if (s != 0)
- handle_error_en(s, "pthread_attr_init");
+ errc(EXIT_FAILURE, s, "pthread_attr_init");
attrp = &attr;
}
\&
\&
s = pthread_attr_setinheritsched(&attr, inheritsched);
if (s != 0)
- handle_error_en(s, "pthread_attr_setinheritsched");
+ errc(EXIT_FAILURE, s, "pthread_attr_setinheritsched");
}
\&
if (attr_sched_str != NULL) {
\&
s = pthread_attr_setschedpolicy(&attr, policy);
if (s != 0)
- handle_error_en(s, "pthread_attr_setschedpolicy");
+ errc(EXIT_FAILURE, s, "pthread_attr_setschedpolicy");
s = pthread_attr_setschedparam(&attr, ¶m);
if (s != 0)
- handle_error_en(s, "pthread_attr_setschedparam");
+ errc(EXIT_FAILURE, s, "pthread_attr_setschedparam");
}
\&
/* If we initialized a thread attributes object, display
if (attrp != NULL) {
s = pthread_attr_getschedparam(&attr, ¶m);
if (s != 0)
- handle_error_en(s, "pthread_attr_getschedparam");
+ errc(EXIT_FAILURE, s, "pthread_attr_getschedparam");
s = pthread_attr_getschedpolicy(&attr, &policy);
if (s != 0)
- handle_error_en(s, "pthread_attr_getschedpolicy");
+ errc(EXIT_FAILURE, s, "pthread_attr_getschedpolicy");
\&
printf("Scheduler settings in \[aq]attr\[aq]\[rs]n");
display_sched_attr(policy, ¶m);
\&
s = pthread_create(&thread, attrp, &thread_start, NULL);
if (s != 0)
- handle_error_en(s, "pthread_create");
+ errc(EXIT_FAILURE, s, "pthread_create");
\&
/* Destroy unneeded thread attributes object. */
\&
if (!use_null_attrib) {
s = pthread_attr_destroy(&attr);
if (s != 0)
- handle_error_en(s, "pthread_attr_destroy");
+ errc(EXIT_FAILURE, s, "pthread_attr_destroy");
}
\&
s = pthread_join(thread, NULL);
if (s != 0)
- handle_error_en(s, "pthread_join");
+ errc(EXIT_FAILURE, s, "pthread_join");
\&
exit(EXIT_SUCCESS);
}
\&
.\" SRC BEGIN (pthread_sigmask.c)
.EX
+#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
\&
/* Simple error handling functions */
\&
-#define handle_error_en(en, msg) \[rs]
- do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
static void *
sig_thread(void *arg)
{
for (;;) {
s = sigwait(set, &sig);
if (s != 0)
- handle_error_en(s, "sigwait");
+ errc(EXIT_FAILURE, s, "sigwait");
printf("Signal handling thread got signal %d\[rs]n", sig);
}
}
sigaddset(&set, SIGUSR1);
s = pthread_sigmask(SIG_BLOCK, &set, NULL);
if (s != 0)
- handle_error_en(s, "pthread_sigmask");
+ errc(EXIT_FAILURE, s, "pthread_sigmask");
\&
s = pthread_create(&thread, NULL, &sig_thread, &set);
if (s != 0)
- handle_error_en(s, "pthread_create");
+ errc(EXIT_FAILURE, s, "pthread_create");
\&
/* Main thread carries on to create other threads and/or do
other work. */
\&
.\" SRC BEGIN (sem_wait.c)
.EX
+#include <err.h>
#include <errno.h>
#include <semaphore.h>
#include <signal.h>
\&
sem_t sem;
\&
-#define handle_error(msg) \[rs]
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
static void
handler(int sig)
{
}
\&
if (sem_init(&sem, 0, 0) == \-1)
- handle_error("sem_init");
+ err(EXIT_FAILURE, "sem_init");
\&
/* Establish SIGALRM handler; set alarm timer using argv[1]. */
\&
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGALRM, &sa, NULL) == \-1)
- handle_error("sigaction");
+ err(EXIT_FAILURE, "sigaction");
\&
alarm(atoi(argv[1]));
\&
number of seconds given argv[2]. */
\&
if (clock_gettime(CLOCK_REALTIME, &ts) == \-1)
- handle_error("clock_gettime");
+ err(EXIT_FAILURE, "clock_gettime");
\&
ts.tv_sec += atoi(argv[2]);
\&
#ifndef PSHM_UCASE_H
#define PSHM_UCASE_H
\&
+#include <err.h>
#include <semaphore.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \[rs]
- } while (0)
-\&
#define BUF_SIZE 1024 /* Maximum size for exchanged string */
\&
/* Define a structure that will be imposed on the shared
\&
fd = shm_open(shmpath, O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd == \-1)
- errExit("shm_open");
+ err(EXIT_FAILURE, "shm_open");
\&
if (ftruncate(fd, sizeof(struct shmbuf)) == \-1)
- errExit("ftruncate");
+ err(EXIT_FAILURE, "ftruncate");
\&
/* Map the object into the caller\[aq]s address space. */
\&
shmp = mmap(NULL, sizeof(*shmp), PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (shmp == MAP_FAILED)
- errExit("mmap");
+ err(EXIT_FAILURE, "mmap");
\&
/* Initialize semaphores as process\-shared, with value 0. */
\&
if (sem_init(&shmp\->sem1, 1, 0) == \-1)
- errExit("sem_init\-sem1");
+ err(EXIT_FAILURE, "sem_init\-sem1");
if (sem_init(&shmp\->sem2, 1, 0) == \-1)
- errExit("sem_init\-sem2");
+ err(EXIT_FAILURE, "sem_init\-sem2");
\&
/* Wait for \[aq]sem1\[aq] to be posted by peer before touching
shared memory. */
\&
if (sem_wait(&shmp\->sem1) == \-1)
- errExit("sem_wait");
+ err(EXIT_FAILURE, "sem_wait");
\&
/* Convert data in shared memory into upper case. */
\&
access the modified data in shared memory. */
\&
if (sem_post(&shmp\->sem2) == \-1)
- errExit("sem_post");
+ err(EXIT_FAILURE, "sem_post");
\&
/* Unlink the shared memory object. Even if the peer process
is still using the object, this is okay. The object will
\&
fd = shm_open(shmpath, O_RDWR, 0);
if (fd == \-1)
- errExit("shm_open");
+ err(EXIT_FAILURE, "shm_open");
\&
shmp = mmap(NULL, sizeof(*shmp), PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (shmp == MAP_FAILED)
- errExit("mmap");
+ err(EXIT_FAILURE, "mmap");
\&
/* Copy data into the shared memory object. */
\&
/* Tell peer that it can now access shared memory. */
\&
if (sem_post(&shmp\->sem1) == \-1)
- errExit("sem_post");
+ err(EXIT_FAILURE, "sem_post");
\&
/* Wait until peer says that it has finished accessing
the shared memory. */
\&
if (sem_wait(&shmp\->sem2) == \-1)
- errExit("sem_wait");
+ err(EXIT_FAILURE, "sem_wait");
\&
/* Write modified data in shared memory to standard output. */
\&
if (write(STDOUT_FILENO, &shmp\->buf, len) == \-1)
- errExit("write");
+ err(EXIT_FAILURE, "write");
if (write(STDOUT_FILENO, "\[rs]n", 1) == \-1)
- errExit("write");
+ err(EXIT_FAILURE, "write");
\&
exit(EXIT_SUCCESS);
}
.SS Program source
\&
.EX
+#include <err.h>
#include <fcntl.h>
#include <linux/loop.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \[rs]
- } while (0)
-\&
int
main(int argc, char *argv[])
{
\&
loopctlfd = open("/dev/loop\-control", O_RDWR);
if (loopctlfd == \-1)
- errExit("open: /dev/loop\-control");
+ err(EXIT_FAILURE, "open: /dev/loop\-control");
\&
devnr = ioctl(loopctlfd, LOOP_CTL_GET_FREE);
if (devnr == \-1)
- errExit("ioctl\-LOOP_CTL_GET_FREE");
+ err(EXIT_FAILURE, "ioctl\-LOOP_CTL_GET_FREE");
\&
sprintf(loopname, "/dev/loop%ld", devnr);
printf("loopname = %s\[rs]n", loopname);
\&
loopfd = open(loopname, O_RDWR);
if (loopfd == \-1)
- errExit("open: loopname");
+ err(EXIT_FAILURE, "open: loopname");
\&
backingfile = open(argv[1], O_RDWR);
if (backingfile == \-1)
- errExit("open: backing\-file");
+ err(EXIT_FAILURE, "open: backing\-file");
\&
if (ioctl(loopfd, LOOP_SET_FD, backingfile) == \-1)
- errExit("ioctl\-LOOP_SET_FD");
+ err(EXIT_FAILURE, "ioctl\-LOOP_SET_FD");
\&
exit(EXIT_SUCCESS);
}
.SS Program source
\&
.EX
+#include <err.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
\&
#define BUF_SIZE 20 /* Size of buffers for read operations */
\&
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
-\&
struct ioRequest { /* Application\-defined structure for tracking
I/O requests */
int reqNum;
\&
struct ioRequest *ioList = calloc(numReqs, sizeof(*ioList));
if (ioList == NULL)
- errExit("calloc");
+ err(EXIT_FAILURE, "calloc");
\&
struct aiocb *aiocbList = calloc(numReqs, sizeof(*aiocbList));
if (aiocbList == NULL)
- errExit("calloc");
+ err(EXIT_FAILURE, "calloc");
\&
/* Establish handlers for SIGQUIT and the I/O completion signal. */
\&
\&
sa.sa_handler = quitHandler;
if (sigaction(SIGQUIT, &sa, NULL) == \-1)
- errExit("sigaction");
+ err(EXIT_FAILURE, "sigaction");
\&
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sa.sa_sigaction = aioSigHandler;
if (sigaction(IO_SIGNAL, &sa, NULL) == \-1)
- errExit("sigaction");
+ err(EXIT_FAILURE, "sigaction");
\&
/* Open each file specified on the command line, and queue
a read request on the resulting file descriptor. */
\&
ioList[j].aiocbp\->aio_fildes = open(argv[j + 1], O_RDONLY);
if (ioList[j].aiocbp\->aio_fildes == \-1)
- errExit("open");
+ err(EXIT_FAILURE, "open");
printf("opened %s on descriptor %d\[rs]n", argv[j + 1],
ioList[j].aiocbp\->aio_fildes);
\&
ioList[j].aiocbp\->aio_buf = malloc(BUF_SIZE);
if (ioList[j].aiocbp\->aio_buf == NULL)
- errExit("malloc");
+ err(EXIT_FAILURE, "malloc");
\&
ioList[j].aiocbp\->aio_nbytes = BUF_SIZE;
ioList[j].aiocbp\->aio_reqprio = 0;
\&
s = aio_read(ioList[j].aiocbp);
if (s == \-1)
- errExit("aio_read");
+ err(EXIT_FAILURE, "aio_read");
}
\&
openReqs = numReqs;