Commit 4776faf1 authored by Rusty Russell's avatar Rusty Russell

ccan/err: new err.h-replacing module.

Seems like Solaris doesn't have err.h, as discovered by Samba.
parent 465655bb
#include <stdio.h>
#include <string.h>
#include "config.h"
/**
* err - err(), errx(), warn() and warnx(), as per BSD's err.h.
*
* A few platforms don't provide err.h; for those, this provides replacements.
* For most, it simple includes the system err.h.
*
* Example:
* #include <ccan/err/err.h>
*
* int main(int argc, char *argv[])
* {
* if (argc != 1)
* errx(1, "Expect no arguments");
* exit(0);
* }
*
* License: Public domain
* Author: Rusty Russell <rusty@rustcorp.com.au>
*/
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
#if !HAVE_ERR_H
printf("ccan/compiler\n");
#endif
return 0;
}
return 1;
}
#ifndef CCAN_ERR_H
#define CCAN_ERR_H
#include "config.h"
#if HAVE_ERR_H
#include <err.h>
#else
#include <ccan/compiler/compiler.h>
/**
* err - exit(eval) with message based on format and errno.
* @eval: the exit code
* @fmt: the printf-style format string
*
* The format string is printed to stderr like so:
* <executable name>: <format>: <strerror(errno)>\n
*
* Example:
* char *p = strdup("hello");
* if (!p)
* err(1, "Failed to strdup 'hello'");
*/
void NORETURN err(int eval, const char *fmt, ...);
/**
* errx - exit(eval) with message based on format.
* @eval: the exit code
* @fmt: the printf-style format string
*
* The format string is printed to stderr like so:
* <executable name>: <format>\n
*
* Example:
* if (argc != 1)
* errx(1, "I don't expect any arguments");
*/
void NORETURN errx(int eval, const char *fmt, ...);
/**
* warn - print a message to stderr based on format and errno.
* @eval: the exit code
* @fmt: the printf-style format string
*
* The format string is printed to stderr like so:
* <executable name>: <format>: <strerror(errno)>\n
*
* Example:
* char *p = strdup("hello");
* if (!p)
* warn("Failed to strdup 'hello'");
*/
void warn(const char *fmt, ...);
/**
* warnx - print a message to stderr based on format.
* @eval: the exit code
* @fmt: the printf-style format string
*
* The format string is printed to stderr like so:
* <executable name>: <format>\n
*
* Example:
* if (argc != 1)
* warnx("I don't expect any arguments (ignoring)");
*/
void warnx(const char *fmt, ...);
#endif
#endif /* CCAN_ERR_H */
#include <ccan/err/err.h>
#include <ccan/tap/tap.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BUFFER_MAX 1024
int main(void)
{
int pfd[2];
plan_tests(20);
fflush(stdout);
/* Test err() in child */
pipe(pfd);
if (fork()) {
char buffer[BUFFER_MAX+1];
unsigned int i;
int status;
/* We are parent. */
close(pfd[1]);
for (i = 0; i < BUFFER_MAX; i++) {
if (read(pfd[0], buffer + i, 1) == 0) {
buffer[i] = '\0';
ok1(strstr(buffer, "running err:"));
ok1(strstr(buffer, strerror(ENOENT)));
ok1(buffer[i-1] == '\n');
break;
}
}
close(pfd[0]);
ok1(wait(&status) != -1);
ok1(WIFEXITED(status));
ok1(WEXITSTATUS(status) == 17);
} else {
close(pfd[0]);
dup2(pfd[1], STDERR_FILENO);
errno = ENOENT;
err(17, "running %s", "err");
abort();
}
/* Test errx() in child */
pipe(pfd);
fflush(stdout);
if (fork()) {
char buffer[BUFFER_MAX+1];
unsigned int i;
int status;
/* We are parent. */
close(pfd[1]);
for (i = 0; i < BUFFER_MAX; i++) {
if (read(pfd[0], buffer + i, 1) == 0) {
buffer[i] = '\0';
ok1(strstr(buffer, "running errx\n"));
break;
}
}
close(pfd[0]);
ok1(wait(&status) != -1);
ok1(WIFEXITED(status));
ok1(WEXITSTATUS(status) == 17);
} else {
close(pfd[0]);
dup2(pfd[1], STDERR_FILENO);
errx(17, "running %s", "errx");
abort();
}
/* Test warn() in child */
pipe(pfd);
fflush(stdout);
if (fork()) {
char buffer[BUFFER_MAX+1];
unsigned int i;
int status;
/* We are parent. */
close(pfd[1]);
for (i = 0; i < BUFFER_MAX; i++) {
if (read(pfd[0], buffer + i, 1) == 0) {
buffer[i] = '\0';
ok1(strstr(buffer, "running warn:"));
ok1(strstr(buffer, strerror(ENOENT)));
ok1(buffer[i-1] == '\n');
break;
}
}
close(pfd[0]);
ok1(wait(&status) != -1);
ok1(WIFEXITED(status));
ok1(WEXITSTATUS(status) == 17);
} else {
close(pfd[0]);
dup2(pfd[1], STDERR_FILENO);
errno = ENOENT;
warn("running %s", "warn");
exit(17);
}
/* Test warnx() in child */
pipe(pfd);
fflush(stdout);
if (fork()) {
char buffer[BUFFER_MAX+1];
unsigned int i;
int status;
/* We are parent. */
close(pfd[1]);
for (i = 0; i < BUFFER_MAX; i++) {
if (read(pfd[0], buffer + i, 1) == 0) {
buffer[i] = '\0';
ok1(strstr(buffer, "running warnx\n"));
break;
}
}
close(pfd[0]);
ok1(wait(&status) != -1);
ok1(WIFEXITED(status));
ok1(WEXITSTATUS(status) == 17);
} else {
close(pfd[0]);
dup2(pfd[1], STDERR_FILENO);
warnx("running %s", "warnx");
exit(17);
}
return exit_status();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment