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