📄 asprintf.c
字号:
/* * =========================================================================== * PRODUCTION $Log: asprintf.c,v $ * PRODUCTION Revision 1000.0 2003/10/29 20:34:23 gouriano * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.3 * PRODUCTION * =========================================================================== *//* * vasprintf(3), asprintf(3) * 20020809 entropy@tappedin.com * public domain. no warranty. use at your own risk. have a nice day. * * Assumes that mprotect(2) granularity is one page. May need adjustment * on systems with unusual protection semantics. */#include <tds_config.h>#if !HAVE_VASPRINTF#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <string.h>#ifndef _REENTRANT#include <sys/mman.h>#include <setjmp.h>#include <signal.h>#include <assert.h>#endifstatic char software_version[] = "$Id: asprintf.c,v 1000.0 2003/10/29 20:34:23 gouriano Exp $";static void *no_unused_var_warn[] = {software_version, no_unused_var_warn};#ifndef _REENTRANTstatic jmp_buf env;static voidsigsegv(int sig){ longjmp(env, 1);}#endifintvasprintf(char **ret, const char *fmt, va_list ap){#ifdef _REENTRANT FILE *fp; int len; char *buf; *ret = NULL; if ((fp = fopen("/dev/null", "w")) == NULL) return -1; len = vfprintf(fp, fmt, ap); if (fclose(fp) != 0) return -1; if (len < 0) return len; if ((buf = malloc(len + 1)) == NULL) return -1; vsprintf(buf, fmt, ap); *ret = buf; return len;#else# ifndef _SC_PAGE_SIZE# define _SC_PAGE_SIZE _SC_PAGESIZE# endif volatile char *buf = NULL; volatile unsigned int pgs; struct sigaction sa, osa; int len;#ifdef HAVE_GETPAGESIZE long pgsize = getpagesize();#else long pgsize = sysconf(_SC_PAGE_SIZE);#endif pgs = ((strlen(fmt) + 1) / pgsize) + 1; if (sigaction(SIGSEGV, NULL, &osa)) { *ret = NULL; return -1; } sa.sa_handler = sigsegv; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (setjmp(env) != 0) { mprotect((void *) (buf + pgs * pgsize), pgsize, PROT_READ|PROT_WRITE); free((void *) buf); pgs++; } if ((buf = valloc((pgs + 1) * pgsize)) == NULL) { *ret = NULL; return -1; } assert(((unsigned long) buf % pgsize) == 0); if (sigaction(SIGSEGV, &sa, NULL)) { free((void *) buf); *ret = NULL; return -1; } mprotect((void *) (buf + pgs * pgsize), pgsize, PROT_NONE); len = vsprintf((void *) buf, fmt, ap); mprotect((void *) (buf + pgs * pgsize), pgsize, PROT_READ|PROT_WRITE); if (sigaction(SIGSEGV, &osa, NULL)) { free((void *) buf); *ret = NULL; return -1; } if (len < 0) { free((void *) buf); *ret = NULL; return len; } if ((buf = realloc((void *) buf, len + 1)) == NULL) { *ret = NULL; return -1; } *ret = (char *) buf; return len;#endif}intasprintf(char **ret, const char *fmt, ...){ int len; va_list ap; va_start(ap, fmt); len = vasprintf(ret, fmt, ap); va_end(ap); return len;}#endif /* HAVE_VASPRINTF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -