diff options
-rw-r--r-- | libbb/bb_asprintf.c | 89 | ||||
-rw-r--r-- | libbb/xconnect.c | 5 |
2 files changed, 91 insertions, 3 deletions
diff --git a/libbb/bb_asprintf.c b/libbb/bb_asprintf.c new file mode 100644 index 000000000..c0c5cdeda --- /dev/null +++ b/libbb/bb_asprintf.c @@ -0,0 +1,89 @@ +/* + Copyright (C) 2002 Vladimir Oleynik <dzo@simtreas.ru> +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> + + +#ifdef TEST +extern void *xrealloc(void *p, size_t size); +#else +#include "libbb.h" /* busybox source */ +#endif + + +/* Exchange glibc vasprintf - minimize allocate memory version */ +/* libc5 and uclibc have not vasprintf function */ +void bb_vasprintf(char **string_ptr, const char *format, va_list args) +{ + int bs = 128; + char stack_buff[128]; + char *buff = stack_buff; + int done; + + /* two or more loop, first - calculate memory size only */ + while(1) { + done = vsnprintf (buff, bs, format, args); +/* Different libc have different interpretation vsnprintf returned value */ + if(done >= 0) { + if(done < bs && buff != stack_buff) { + /* allocated */ + *string_ptr = buff; + return; + } else { + /* true calculate memory size */ + bs = done+1; + } + } else { + /* + * Old libc. Incrementaly test. + * Exact not minimize allocate memory. + */ + bs += 128; + } + buff = xrealloc((buff == stack_buff ? NULL : buff), bs); + } +} + +void bb_asprintf(char **string_ptr, const char *format, ...) +{ + va_list p; + + va_start(p, format); + bb_vasprintf(string_ptr, format, p); + va_end(p); +} + +#ifdef TEST +int main(int argc, char **argv) +{ + char *out_buf; + char big_buf[200]; + int i; + + bb_asprintf(&out_buf, "Hi!\nargc=%d argv[0]=%s\n", argc, argv[0]); + printf(out_buf); + free(out_buf); + + for(i=0; i < sizeof(big_buf)-1; i++) + big_buf[i]='x'; + big_buf[i]=0; + bb_asprintf(&out_buf, "Test Big\n%s\n", big_buf); + printf(out_buf); + free(out_buf); + + return 0; +} + +void *xrealloc(void *p, size_t size) +{ + void *p2 = realloc(p, size); + if(p2==0) { + fprintf(stderr, "TEST: memory_exhausted\n"); + exit(1); + } + return p2; +} +#endif diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 9e771495d..f3a1b4462 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c @@ -6,7 +6,6 @@ * */ -#include "inet_common.h" #include <unistd.h> #include <string.h> #include <stdlib.h> @@ -58,7 +57,7 @@ int xconnect(const char *host, const char *port) struct sockaddr_in s_addr; int s = socket(AF_INET, SOCK_STREAM, 0); struct servent *tserv; - int port_nr=atoi(port); + int port_nr=htons(atoi(port)); struct hostent * he; if (port_nr==0 && (tserv = getservbyname(port, "tcp")) != NULL) @@ -66,7 +65,7 @@ int xconnect(const char *host, const char *port) memset(&s_addr, 0, sizeof(struct sockaddr_in)); s_addr.sin_family = AF_INET; - s_addr.sin_port = htons(port_nr); + s_addr.sin_port = port_nr; he = xgethostbyname(host); memcpy(&s_addr.sin_addr, he->h_addr, sizeof s_addr.sin_addr); |