1276305Sngie/* $NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $ */ 2236769Sobrien 3236769Sobrien/* 4236769Sobrien * Missing stuff from OS's 5236769Sobrien * 6276305Sngie * $Id: util.c,v 1.33 2014/01/02 02:29:49 sjg Exp $ 7236769Sobrien */ 8276305Sngie#if defined(__MINT__) || defined(__linux__) 9276305Sngie#include <signal.h> 10276305Sngie#endif 11236769Sobrien 12236769Sobrien#include "make.h" 13236769Sobrien 14236769Sobrien#ifndef MAKE_NATIVE 15276305Sngiestatic char rcsid[] = "$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $"; 16236769Sobrien#else 17236769Sobrien#ifndef lint 18276305Sngie__RCSID("$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $"); 19236769Sobrien#endif 20236769Sobrien#endif 21236769Sobrien 22236769Sobrien#include <errno.h> 23236769Sobrien#include <time.h> 24236769Sobrien#include <signal.h> 25236769Sobrien 26236769Sobrien#if !defined(HAVE_STRERROR) 27236769Sobrienextern int errno, sys_nerr; 28236769Sobrienextern char *sys_errlist[]; 29236769Sobrien 30236769Sobrienchar * 31236769Sobrienstrerror(int e) 32236769Sobrien{ 33236769Sobrien static char buf[100]; 34236769Sobrien if (e < 0 || e >= sys_nerr) { 35236769Sobrien snprintf(buf, sizeof(buf), "Unknown error %d", e); 36236769Sobrien return buf; 37236769Sobrien } 38236769Sobrien else 39236769Sobrien return sys_errlist[e]; 40236769Sobrien} 41236769Sobrien#endif 42236769Sobrien 43236769Sobrien#if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) 44236769Sobrienextern char **environ; 45236769Sobrien 46236769Sobrienstatic char * 47236769Sobrienfindenv(const char *name, int *offset) 48236769Sobrien{ 49236769Sobrien size_t i, len; 50236769Sobrien char *p, *q; 51236769Sobrien 52236769Sobrien len = strlen(name); 53236769Sobrien for (i = 0; (q = environ[i]); i++) { 54236769Sobrien p = strchr(q, '='); 55236769Sobrien if (p == NULL || p - q != len) 56236769Sobrien continue; 57236769Sobrien if (strncmp(name, q, len) == 0) { 58236769Sobrien *offset = i; 59236769Sobrien return q + len + 1; 60236769Sobrien } 61236769Sobrien } 62236769Sobrien *offset = i; 63236769Sobrien return NULL; 64236769Sobrien} 65236769Sobrien 66236769Sobrienchar * 67236769Sobriengetenv(const char *name) 68236769Sobrien{ 69236769Sobrien int offset; 70236769Sobrien 71236769Sobrien return(findenv(name, &offset)); 72236769Sobrien} 73236769Sobrien 74236769Sobrienint 75236769Sobrienunsetenv(const char *name) 76236769Sobrien{ 77236769Sobrien char **p; 78236769Sobrien int offset; 79236769Sobrien 80236769Sobrien if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) { 81236769Sobrien errno = EINVAL; 82236769Sobrien return -1; 83236769Sobrien } 84236769Sobrien 85236769Sobrien while (findenv(name, &offset)) { /* if set multiple times */ 86236769Sobrien for (p = &environ[offset];; ++p) 87236769Sobrien if (!(*p = *(p + 1))) 88236769Sobrien break; 89236769Sobrien } 90236769Sobrien return 0; 91236769Sobrien} 92236769Sobrien 93236769Sobrienint 94236769Sobriensetenv(const char *name, const char *value, int rewrite) 95236769Sobrien{ 96236769Sobrien char *c, **newenv; 97236769Sobrien const char *cc; 98236769Sobrien size_t l_value, size; 99236769Sobrien int offset; 100236769Sobrien 101236769Sobrien if (name == NULL || value == NULL) { 102236769Sobrien errno = EINVAL; 103236769Sobrien return -1; 104236769Sobrien } 105236769Sobrien 106236769Sobrien if (*value == '=') /* no `=' in value */ 107236769Sobrien ++value; 108236769Sobrien l_value = strlen(value); 109236769Sobrien 110236769Sobrien /* find if already exists */ 111236769Sobrien if ((c = findenv(name, &offset))) { 112236769Sobrien if (!rewrite) 113236769Sobrien return 0; 114236769Sobrien if (strlen(c) >= l_value) /* old larger; copy over */ 115236769Sobrien goto copy; 116236769Sobrien } else { /* create new slot */ 117236769Sobrien size = sizeof(char *) * (offset + 2); 118236769Sobrien if (savedEnv == environ) { /* just increase size */ 119236769Sobrien if ((newenv = realloc(savedEnv, size)) == NULL) 120236769Sobrien return -1; 121236769Sobrien savedEnv = newenv; 122236769Sobrien } else { /* get new space */ 123236769Sobrien /* 124236769Sobrien * We don't free here because we don't know if 125236769Sobrien * the first allocation is valid on all OS's 126236769Sobrien */ 127236769Sobrien if ((savedEnv = malloc(size)) == NULL) 128236769Sobrien return -1; 129236769Sobrien (void)memcpy(savedEnv, environ, size - sizeof(char *)); 130236769Sobrien } 131236769Sobrien environ = savedEnv; 132236769Sobrien environ[offset + 1] = NULL; 133236769Sobrien } 134236769Sobrien for (cc = name; *cc && *cc != '='; ++cc) /* no `=' in name */ 135236769Sobrien continue; 136236769Sobrien size = cc - name; 137236769Sobrien /* name + `=' + value */ 138236769Sobrien if ((environ[offset] = malloc(size + l_value + 2)) == NULL) 139236769Sobrien return -1; 140236769Sobrien c = environ[offset]; 141236769Sobrien (void)memcpy(c, name, size); 142236769Sobrien c += size; 143236769Sobrien *c++ = '='; 144236769Sobriencopy: 145236769Sobrien (void)memcpy(c, value, l_value + 1); 146236769Sobrien return 0; 147236769Sobrien} 148236769Sobrien 149236769Sobrien#ifdef TEST 150236769Sobrienint 151236769Sobrienmain(int argc, char *argv[]) 152236769Sobrien{ 153236769Sobrien setenv(argv[1], argv[2], 0); 154236769Sobrien printf("%s\n", getenv(argv[1])); 155236769Sobrien unsetenv(argv[1]); 156236769Sobrien printf("%s\n", getenv(argv[1])); 157236769Sobrien return 0; 158236769Sobrien} 159236769Sobrien#endif 160236769Sobrien 161236769Sobrien#endif 162236769Sobrien 163236769Sobrien 164236769Sobrien#if defined(__hpux__) || defined(__hpux) 165236769Sobrien/* strrcpy(): 166236769Sobrien * Like strcpy, going backwards and returning the new pointer 167236769Sobrien */ 168236769Sobrienstatic char * 169236769Sobrienstrrcpy(char *ptr, char *str) 170236769Sobrien{ 171236769Sobrien int len = strlen(str); 172236769Sobrien 173236769Sobrien while (len) 174236769Sobrien *--ptr = str[--len]; 175236769Sobrien 176236769Sobrien return (ptr); 177236769Sobrien} /* end strrcpy */ 178236769Sobrien 179236769Sobrien 180236769Sobrienchar *sys_siglist[] = { 181236769Sobrien "Signal 0", 182236769Sobrien "Hangup", /* SIGHUP */ 183236769Sobrien "Interrupt", /* SIGINT */ 184236769Sobrien "Quit", /* SIGQUIT */ 185236769Sobrien "Illegal instruction", /* SIGILL */ 186236769Sobrien "Trace/BPT trap", /* SIGTRAP */ 187236769Sobrien "IOT trap", /* SIGIOT */ 188236769Sobrien "EMT trap", /* SIGEMT */ 189236769Sobrien "Floating point exception", /* SIGFPE */ 190236769Sobrien "Killed", /* SIGKILL */ 191236769Sobrien "Bus error", /* SIGBUS */ 192236769Sobrien "Segmentation fault", /* SIGSEGV */ 193236769Sobrien "Bad system call", /* SIGSYS */ 194236769Sobrien "Broken pipe", /* SIGPIPE */ 195236769Sobrien "Alarm clock", /* SIGALRM */ 196236769Sobrien "Terminated", /* SIGTERM */ 197236769Sobrien "User defined signal 1", /* SIGUSR1 */ 198236769Sobrien "User defined signal 2", /* SIGUSR2 */ 199236769Sobrien "Child exited", /* SIGCLD */ 200236769Sobrien "Power-fail restart", /* SIGPWR */ 201236769Sobrien "Virtual timer expired", /* SIGVTALRM */ 202236769Sobrien "Profiling timer expired", /* SIGPROF */ 203236769Sobrien "I/O possible", /* SIGIO */ 204236769Sobrien "Window size changes", /* SIGWINDOW */ 205236769Sobrien "Stopped (signal)", /* SIGSTOP */ 206236769Sobrien "Stopped", /* SIGTSTP */ 207236769Sobrien "Continued", /* SIGCONT */ 208236769Sobrien "Stopped (tty input)", /* SIGTTIN */ 209236769Sobrien "Stopped (tty output)", /* SIGTTOU */ 210236769Sobrien "Urgent I/O condition", /* SIGURG */ 211236769Sobrien "Remote lock lost (NFS)", /* SIGLOST */ 212236769Sobrien "Signal 31", /* reserved */ 213236769Sobrien "DIL signal" /* SIGDIL */ 214236769Sobrien}; 215236769Sobrien#endif /* __hpux__ || __hpux */ 216236769Sobrien 217236769Sobrien#if defined(__hpux__) || defined(__hpux) 218236769Sobrien#include <sys/types.h> 219236769Sobrien#include <sys/syscall.h> 220236769Sobrien#include <sys/signal.h> 221236769Sobrien#include <sys/stat.h> 222236769Sobrien#include <dirent.h> 223236769Sobrien#include <sys/time.h> 224236769Sobrien#include <unistd.h> 225236769Sobrien 226236769Sobrienint 227236769Sobrienkillpg(int pid, int sig) 228236769Sobrien{ 229236769Sobrien return kill(-pid, sig); 230236769Sobrien} 231236769Sobrien 232236769Sobrien#if !defined(__hpux__) && !defined(__hpux) 233236769Sobrienvoid 234236769Sobriensrandom(long seed) 235236769Sobrien{ 236236769Sobrien srand48(seed); 237236769Sobrien} 238236769Sobrien 239236769Sobrienlong 240236769Sobrienrandom(void) 241236769Sobrien{ 242236769Sobrien return lrand48(); 243236769Sobrien} 244236769Sobrien#endif 245236769Sobrien 246236769Sobrien#if !defined(__hpux__) && !defined(__hpux) 247236769Sobrienint 248236769Sobrienutimes(char *file, struct timeval tvp[2]) 249236769Sobrien{ 250236769Sobrien struct utimbuf t; 251236769Sobrien 252236769Sobrien t.actime = tvp[0].tv_sec; 253236769Sobrien t.modtime = tvp[1].tv_sec; 254236769Sobrien return(utime(file, &t)); 255236769Sobrien} 256236769Sobrien#endif 257236769Sobrien 258236769Sobrien#if !defined(BSD) && !defined(d_fileno) 259236769Sobrien# define d_fileno d_ino 260236769Sobrien#endif 261236769Sobrien 262236769Sobrien#ifndef DEV_DEV_COMPARE 263236769Sobrien# define DEV_DEV_COMPARE(a, b) ((a) == (b)) 264236769Sobrien#endif 265236769Sobrien#define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/'))) 266236769Sobrien#define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1]))) 267236769Sobrien 268236769Sobrienchar * 269236769Sobriengetwd(char *pathname) 270236769Sobrien{ 271236769Sobrien DIR *dp; 272236769Sobrien struct dirent *d; 273236769Sobrien extern int errno; 274236769Sobrien 275236769Sobrien struct stat st_root, st_cur, st_next, st_dotdot; 276236769Sobrien char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; 277236769Sobrien char *pathptr, *nextpathptr, *cur_name_add; 278236769Sobrien 279236769Sobrien /* find the inode of root */ 280236769Sobrien if (stat("/", &st_root) == -1) { 281236769Sobrien (void)sprintf(pathname, 282236769Sobrien "getwd: Cannot stat \"/\" (%s)", strerror(errno)); 283236769Sobrien return NULL; 284236769Sobrien } 285236769Sobrien pathbuf[MAXPATHLEN - 1] = '\0'; 286236769Sobrien pathptr = &pathbuf[MAXPATHLEN - 1]; 287236769Sobrien nextpathbuf[MAXPATHLEN - 1] = '\0'; 288236769Sobrien cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; 289236769Sobrien 290236769Sobrien /* find the inode of the current directory */ 291236769Sobrien if (lstat(".", &st_cur) == -1) { 292236769Sobrien (void)sprintf(pathname, 293236769Sobrien "getwd: Cannot stat \".\" (%s)", strerror(errno)); 294236769Sobrien return NULL; 295236769Sobrien } 296236769Sobrien nextpathptr = strrcpy(nextpathptr, "../"); 297236769Sobrien 298236769Sobrien /* Descend to root */ 299236769Sobrien for (;;) { 300236769Sobrien 301236769Sobrien /* look if we found root yet */ 302236769Sobrien if (st_cur.st_ino == st_root.st_ino && 303236769Sobrien DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { 304236769Sobrien (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr); 305236769Sobrien return (pathname); 306236769Sobrien } 307236769Sobrien 308236769Sobrien /* open the parent directory */ 309236769Sobrien if (stat(nextpathptr, &st_dotdot) == -1) { 310236769Sobrien (void)sprintf(pathname, 311236769Sobrien "getwd: Cannot stat directory \"%s\" (%s)", 312236769Sobrien nextpathptr, strerror(errno)); 313236769Sobrien return NULL; 314236769Sobrien } 315236769Sobrien if ((dp = opendir(nextpathptr)) == NULL) { 316236769Sobrien (void)sprintf(pathname, 317236769Sobrien "getwd: Cannot open directory \"%s\" (%s)", 318236769Sobrien nextpathptr, strerror(errno)); 319236769Sobrien return NULL; 320236769Sobrien } 321236769Sobrien 322236769Sobrien /* look in the parent for the entry with the same inode */ 323236769Sobrien if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { 324236769Sobrien /* Parent has same device. No need to stat every member */ 325236769Sobrien for (d = readdir(dp); d != NULL; d = readdir(dp)) 326236769Sobrien if (d->d_fileno == st_cur.st_ino) 327236769Sobrien break; 328236769Sobrien } 329236769Sobrien else { 330236769Sobrien /* 331236769Sobrien * Parent has a different device. This is a mount point so we 332236769Sobrien * need to stat every member 333236769Sobrien */ 334236769Sobrien for (d = readdir(dp); d != NULL; d = readdir(dp)) { 335236769Sobrien if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) 336236769Sobrien continue; 337236769Sobrien (void)strcpy(cur_name_add, d->d_name); 338236769Sobrien if (lstat(nextpathptr, &st_next) == -1) { 339236769Sobrien (void)sprintf(pathname, 340236769Sobrien "getwd: Cannot stat \"%s\" (%s)", 341236769Sobrien d->d_name, strerror(errno)); 342236769Sobrien (void)closedir(dp); 343236769Sobrien return NULL; 344236769Sobrien } 345236769Sobrien /* check if we found it yet */ 346236769Sobrien if (st_next.st_ino == st_cur.st_ino && 347236769Sobrien DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) 348236769Sobrien break; 349236769Sobrien } 350236769Sobrien } 351236769Sobrien if (d == NULL) { 352236769Sobrien (void)sprintf(pathname, 353236769Sobrien "getwd: Cannot find \".\" in \"..\""); 354236769Sobrien (void)closedir(dp); 355236769Sobrien return NULL; 356236769Sobrien } 357236769Sobrien st_cur = st_dotdot; 358236769Sobrien pathptr = strrcpy(pathptr, d->d_name); 359236769Sobrien pathptr = strrcpy(pathptr, "/"); 360236769Sobrien nextpathptr = strrcpy(nextpathptr, "../"); 361236769Sobrien (void)closedir(dp); 362236769Sobrien *cur_name_add = '\0'; 363236769Sobrien } 364236769Sobrien} /* end getwd */ 365236769Sobrien 366236769Sobrien#endif /* __hpux */ 367236769Sobrien 368236769Sobrien#if !defined(HAVE_GETCWD) 369236769Sobrienchar * 370236769Sobriengetcwd(path, sz) 371236769Sobrien char *path; 372236769Sobrien int sz; 373236769Sobrien{ 374236769Sobrien return getwd(path); 375236769Sobrien} 376236769Sobrien#endif 377236769Sobrien 378236769Sobrien/* force posix signals */ 379236769Sobrienvoid (* 380236769Sobrienbmake_signal(int s, void (*a)(int)))(int) 381236769Sobrien{ 382236769Sobrien struct sigaction sa, osa; 383236769Sobrien 384236769Sobrien sa.sa_handler = a; 385236769Sobrien sigemptyset(&sa.sa_mask); 386236769Sobrien sa.sa_flags = SA_RESTART; 387236769Sobrien 388236769Sobrien if (sigaction(s, &sa, &osa) == -1) 389236769Sobrien return SIG_ERR; 390236769Sobrien else 391236769Sobrien return osa.sa_handler; 392236769Sobrien} 393236769Sobrien 394236769Sobrien#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF) 395236769Sobrien#include <stdarg.h> 396236769Sobrien#endif 397236769Sobrien 398236769Sobrien#if !defined(HAVE_VSNPRINTF) 399236769Sobrien#if !defined(__osf__) 400236769Sobrien#ifdef _IOSTRG 401236769Sobrien#define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */ 402236769Sobrien#else 403236769Sobrien#if 0 404236769Sobrien#define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */ 405236769Sobrien#endif 406236769Sobrien#endif /* _IOSTRG */ 407236769Sobrien#endif /* __osf__ */ 408236769Sobrien 409236769Sobrienint 410236769Sobrienvsnprintf(char *s, size_t n, const char *fmt, va_list args) 411236769Sobrien{ 412236769Sobrien#ifdef STRFLAG 413236769Sobrien FILE fakebuf; 414236769Sobrien 415236769Sobrien fakebuf._flag = STRFLAG; 416236769Sobrien /* 417236769Sobrien * Some os's are char * _ptr, others are unsigned char *_ptr... 418236769Sobrien * We cast to void * to make everyone happy. 419236769Sobrien */ 420236769Sobrien fakebuf._ptr = (void *)s; 421236769Sobrien fakebuf._cnt = n-1; 422236769Sobrien fakebuf._file = -1; 423236769Sobrien _doprnt(fmt, args, &fakebuf); 424236769Sobrien fakebuf._cnt++; 425236769Sobrien putc('\0', &fakebuf); 426236769Sobrien if (fakebuf._cnt<0) 427236769Sobrien fakebuf._cnt = 0; 428236769Sobrien return (n-fakebuf._cnt-1); 429236769Sobrien#else 430236769Sobrien#ifndef _PATH_DEVNULL 431236769Sobrien# define _PATH_DEVNULL "/dev/null" 432236769Sobrien#endif 433236769Sobrien /* 434236769Sobrien * Rats... we don't want to clobber anything... 435236769Sobrien * do a printf to /dev/null to see how much space we need. 436236769Sobrien */ 437236769Sobrien static FILE *nullfp; 438236769Sobrien int need = 0; /* XXX what's a useful error return? */ 439236769Sobrien 440236769Sobrien if (!nullfp) 441236769Sobrien nullfp = fopen(_PATH_DEVNULL, "w"); 442236769Sobrien if (nullfp) { 443236769Sobrien need = vfprintf(nullfp, fmt, args); 444236769Sobrien if (need < n) 445236769Sobrien (void)vsprintf(s, fmt, args); 446236769Sobrien } 447236769Sobrien return need; 448236769Sobrien#endif 449236769Sobrien} 450236769Sobrien#endif 451236769Sobrien 452236769Sobrien#if !defined(HAVE_SNPRINTF) 453236769Sobrienint 454236769Sobriensnprintf(char *s, size_t n, const char *fmt, ...) 455236769Sobrien{ 456236769Sobrien va_list ap; 457236769Sobrien int rv; 458236769Sobrien 459236769Sobrien va_start(ap, fmt); 460236769Sobrien rv = vsnprintf(s, n, fmt, ap); 461236769Sobrien va_end(ap); 462236769Sobrien return rv; 463236769Sobrien} 464236769Sobrien#endif 465236769Sobrien 466236769Sobrien#if !defined(HAVE_STRFTIME) 467236769Sobriensize_t 468236769Sobrienstrftime(char *buf, size_t len, const char *fmt, const struct tm *tm) 469236769Sobrien{ 470236769Sobrien static char months[][4] = { 471236769Sobrien "Jan", "Feb", "Mar", "Apr", "May", "Jun", 472236769Sobrien "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 473236769Sobrien }; 474236769Sobrien 475236769Sobrien size_t s; 476236769Sobrien char *b = buf; 477236769Sobrien 478236769Sobrien while (*fmt) { 479236769Sobrien if (len == 0) 480236769Sobrien return buf - b; 481236769Sobrien if (*fmt != '%') { 482236769Sobrien *buf++ = *fmt++; 483236769Sobrien len--; 484236769Sobrien continue; 485236769Sobrien } 486236769Sobrien switch (*fmt++) { 487236769Sobrien case '%': 488236769Sobrien *buf++ = '%'; 489236769Sobrien len--; 490236769Sobrien if (len == 0) return buf - b; 491236769Sobrien /*FALLTHROUGH*/ 492236769Sobrien case '\0': 493236769Sobrien *buf = '%'; 494236769Sobrien s = 1; 495236769Sobrien break; 496236769Sobrien case 'k': 497236769Sobrien s = snprintf(buf, len, "%d", tm->tm_hour); 498236769Sobrien break; 499236769Sobrien case 'M': 500236769Sobrien s = snprintf(buf, len, "%02d", tm->tm_min); 501236769Sobrien break; 502236769Sobrien case 'S': 503236769Sobrien s = snprintf(buf, len, "%02d", tm->tm_sec); 504236769Sobrien break; 505236769Sobrien case 'b': 506236769Sobrien if (tm->tm_mon >= 12) 507236769Sobrien return buf - b; 508236769Sobrien s = snprintf(buf, len, "%s", months[tm->tm_mon]); 509236769Sobrien break; 510236769Sobrien case 'd': 511236769Sobrien s = snprintf(buf, len, "%02d", tm->tm_mday); 512236769Sobrien break; 513236769Sobrien case 'Y': 514236769Sobrien s = snprintf(buf, len, "%d", 1900 + tm->tm_year); 515236769Sobrien break; 516236769Sobrien default: 517236769Sobrien s = snprintf(buf, len, "Unsupported format %c", 518236769Sobrien fmt[-1]); 519236769Sobrien break; 520236769Sobrien } 521236769Sobrien buf += s; 522236769Sobrien len -= s; 523236769Sobrien } 524236769Sobrien} 525236769Sobrien#endif 526236769Sobrien 527236769Sobrien#if !defined(HAVE_KILLPG) 528236769Sobrien#if !defined(__hpux__) && !defined(__hpux) 529236769Sobrienint 530236769Sobrienkillpg(int pid, int sig) 531236769Sobrien{ 532236769Sobrien return kill(-pid, sig); 533236769Sobrien} 534236769Sobrien#endif 535236769Sobrien#endif 536236769Sobrien 537236769Sobrien#if !defined(HAVE_WARNX) 538236769Sobrienstatic void 539236769Sobrienvwarnx(const char *fmt, va_list args) 540236769Sobrien{ 541236769Sobrien fprintf(stderr, "%s: ", progname); 542236769Sobrien if ((fmt)) { 543236769Sobrien vfprintf(stderr, fmt, args); 544236769Sobrien fprintf(stderr, ": "); 545236769Sobrien } 546236769Sobrien} 547236769Sobrien#endif 548236769Sobrien 549236769Sobrien#if !defined(HAVE_WARN) 550236769Sobrienstatic void 551236769Sobrienvwarn(const char *fmt, va_list args) 552236769Sobrien{ 553236769Sobrien vwarnx(fmt, args); 554236769Sobrien fprintf(stderr, "%s\n", strerror(errno)); 555236769Sobrien} 556236769Sobrien#endif 557236769Sobrien 558236769Sobrien#if !defined(HAVE_ERR) 559236769Sobrienstatic void 560236769Sobrienverr(int eval, const char *fmt, va_list args) 561236769Sobrien{ 562236769Sobrien vwarn(fmt, args); 563236769Sobrien exit(eval); 564236769Sobrien} 565236769Sobrien#endif 566236769Sobrien 567236769Sobrien#if !defined(HAVE_ERRX) 568236769Sobrienstatic void 569236769Sobrienverrx(int eval, const char *fmt, va_list args) 570236769Sobrien{ 571236769Sobrien vwarnx(fmt, args); 572236769Sobrien exit(eval); 573236769Sobrien} 574236769Sobrien#endif 575236769Sobrien 576236769Sobrien#if !defined(HAVE_ERR) 577236769Sobrienvoid 578236769Sobrienerr(int eval, const char *fmt, ...) 579236769Sobrien{ 580236769Sobrien va_list ap; 581236769Sobrien 582236769Sobrien va_start(ap, fmt); 583236769Sobrien verr(eval, fmt, ap); 584236769Sobrien va_end(ap); 585236769Sobrien} 586236769Sobrien#endif 587236769Sobrien 588236769Sobrien#if !defined(HAVE_ERRX) 589236769Sobrienvoid 590236769Sobrienerrx(int eval, const char *fmt, ...) 591236769Sobrien{ 592236769Sobrien va_list ap; 593236769Sobrien 594236769Sobrien va_start(ap, fmt); 595236769Sobrien verrx(eval, fmt, ap); 596236769Sobrien va_end(ap); 597236769Sobrien} 598236769Sobrien#endif 599236769Sobrien 600236769Sobrien#if !defined(HAVE_WARN) 601236769Sobrienvoid 602236769Sobrienwarn(const char *fmt, ...) 603236769Sobrien{ 604236769Sobrien va_list ap; 605236769Sobrien 606236769Sobrien va_start(ap, fmt); 607236769Sobrien vwarn(fmt, ap); 608236769Sobrien va_end(ap); 609236769Sobrien} 610236769Sobrien#endif 611236769Sobrien 612236769Sobrien#if !defined(HAVE_WARNX) 613236769Sobrienvoid 614236769Sobrienwarnx(const char *fmt, ...) 615236769Sobrien{ 616236769Sobrien va_list ap; 617236769Sobrien 618236769Sobrien va_start(ap, fmt); 619236769Sobrien vwarnx(fmt, ap); 620236769Sobrien va_end(ap); 621236769Sobrien} 622236769Sobrien#endif 623