From afa40ade775710f3a449e10778159ade4c133d45 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Wed, 15 Nov 2000 21:12:09 +0000 Subject: Add in tmpnam() support from David Whedon , rework include/stdio.h, and fix up the resultant damage. --- libc/stdio/Makefile | 2 +- libc/stdio/getdelim.c | 16 ++++++++++-- libc/stdio/getline.c | 2 +- libc/stdio/popen.c | 11 +++------ libc/stdio/scanf.c | 13 +++------- libc/stdio/stdio.c | 2 +- libc/stdio/tmpnam.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ libc/stdio/tmpnam_r.c | 43 ++++++++++++++++++++++++++++++++ 8 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 libc/stdio/tmpnam.c create mode 100644 libc/stdio/tmpnam_r.c (limited to 'libc/stdio') diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile index fed74e216..49408c95a 100644 --- a/libc/stdio/Makefile +++ b/libc/stdio/Makefile @@ -36,7 +36,7 @@ MOBJ2=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o snprintf.o vs MSRC3=scanf.c MOBJ3=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o -CSRC=dputs.c popen.c perror.c remove.c getdelim.c getline.c +CSRC=dputs.c popen.c perror.c remove.c getdelim.c getline.c tmpnam.c COBJS=$(patsubst %.c,%.o, $(CSRC)) OBJS=$(MOBJ) $(MOBJ2) $(MOBJ3) $(COBJS) diff --git a/libc/stdio/getdelim.c b/libc/stdio/getdelim.c index 682ed2866..6f9ebb4fb 100644 --- a/libc/stdio/getdelim.c +++ b/libc/stdio/getdelim.c @@ -34,18 +34,28 @@ NULL), pointing to *N characters of space. It is realloc'd as necessary. Returns the number of characters read (not including the null delimiter), or -1 on error or EOF. */ -size_t getdelim(char **linebuf, size_t *linebufsz, int delimiter, FILE *file) +ssize_t getdelim(char **linebuf, size_t *linebufsz, int delimiter, FILE *file) { static const int GROWBY = 80; /* how large we will grow strings by */ int ch; int idx = 0; - if (file == NULL || linebuf==NULL || *linebuf == NULL || linebufsz == NULL) { + if ((file == NULL || linebuf==NULL || *linebuf == NULL || *linebufsz == 0) + && !(*linebuf == NULL && *linebufsz ==0 )) { errno=EINVAL; return -1; } + if (*linebuf == NULL && *linebufsz == 0){ + *linebuf = malloc(GROWBY); + if (!*linebuf) { + errno=ENOMEM; + return -1; + } + *linebufsz += GROWBY; + } + while (1) { ch = fgetc(file); if (ch == EOF) @@ -65,6 +75,8 @@ size_t getdelim(char **linebuf, size_t *linebufsz, int delimiter, FILE *file) if (idx != 0) (*linebuf)[idx] = 0; + else if ( ch == EOF ) + return -1; return idx; } diff --git a/libc/stdio/getline.c b/libc/stdio/getline.c index c6896fca7..ecc48ffac 100644 --- a/libc/stdio/getline.c +++ b/libc/stdio/getline.c @@ -25,7 +25,7 @@ #include /* Basically getdelim() with the delimiter hard wired to '\n' */ -size_t getline(char **linebuf, size_t *n, FILE *file) +ssize_t getline(char **linebuf, size_t *n, FILE *file) { return (getdelim (linebuf, n, '\n', file)); } diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c index a07c411eb..7a00e570f 100644 --- a/libc/stdio/popen.c +++ b/libc/stdio/popen.c @@ -4,16 +4,14 @@ #include -FILE *popen(command, rw) -char *command; -char *rw; +FILE *popen (const char *command, const char *modes) { int pipe_fd[2]; int pid, reading; if (pipe(pipe_fd) < 0) return NULL; - reading = (rw[0] == 'r'); + reading = (modes[0] == 'r'); pid = vfork(); if (pid < 0) { @@ -34,11 +32,10 @@ char *rw; } close(pipe_fd[reading]); - return fdopen(pipe_fd[!reading], rw); + return fdopen(pipe_fd[!reading], modes); } -int pclose(fd) -FILE *fd; +int pclose(FILE *fd) { int waitstat; diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c index 8ce590684..51d30cdde 100644 --- a/libc/stdio/scanf.c +++ b/libc/stdio/scanf.c @@ -3,14 +3,7 @@ #include #include #include - -#ifdef __STDC__ #include -#define va_strt va_start -#else -#include -#define va_strt(p,i) va_start(p) -#endif #ifdef L_scanf #ifdef __STDC__ @@ -24,7 +17,7 @@ va_dcl va_list ptr; int rv; - va_strt(ptr, fmt); + va_start(ptr, fmt); rv = vfscanf(stdin, fmt, ptr); va_end(ptr); return rv; @@ -49,7 +42,7 @@ va_dcl va_list ptr; int rv; - va_strt(ptr, fmt); + va_start(ptr, fmt); string->bufpos = (unsigned char *) ((void *) sp); rv = vfscanf(string, fmt, ptr); va_end(ptr); @@ -70,7 +63,7 @@ va_dcl va_list ptr; int rv; - va_strt(ptr, fmt); + va_start(ptr, fmt); rv = vfscanf(fp, fmt, ptr); va_end(ptr); return rv; diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c index b34631154..6c8c69380 100644 --- a/libc/stdio/stdio.c +++ b/libc/stdio/stdio.c @@ -778,7 +778,7 @@ FILE *fp; void setbuffer(fp, buf, size) FILE *fp; char *buf; -int size; +size_t size; { fflush(fp); diff --git a/libc/stdio/tmpnam.c b/libc/stdio/tmpnam.c new file mode 100644 index 000000000..3a3ef67ca --- /dev/null +++ b/libc/stdio/tmpnam.c @@ -0,0 +1,68 @@ +/* vi: set sw=4 ts=4: */ +/* + * tmpnam for uClibc + * + * Copyright (C) 2000 by David Whedon + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License + * for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Modified by Erik Andersen to be reentrant for + * the case when S != NULL... + */ + + +#include +#include +#include +#include +#include + + +static char tmpnam_buffer[L_tmpnam]; + + +/* Generate a unique filename in /tmp */ +char * tmpnam (char *s) +{ + int num __attribute__ ((unused)); /* UNINITIALIZED, so we get whatever crap + happens to be in memory, producing (in theory) + pseudo-random tmpname results... */ + int n2; + char buf[L_tmpnam], *ptr; + struct stat statbuf; + unsigned char l, i; + + ptr=s ? s : buf; + + l = snprintf(ptr, L_tmpnam, "%s/tmp.", P_tmpdir); + +again: + n2 = num; + for (i = l ; i < l + 6; i++) { + ptr[i] = '0' + n2 % 10; + n2 /= 10; + } + + if (stat (ptr, &statbuf) == 0){ + num++; + goto again; + } + + if (s == NULL) + return (char *) memcpy (tmpnam_buffer, ptr, L_tmpnam); + + return ptr; +} + diff --git a/libc/stdio/tmpnam_r.c b/libc/stdio/tmpnam_r.c new file mode 100644 index 000000000..5533a399f --- /dev/null +++ b/libc/stdio/tmpnam_r.c @@ -0,0 +1,43 @@ +/* vi: set sw=4 ts=4: */ +/* + * tmpnam for uClibc + * + * Copyright (C) 2000 by Lineo, inc. Written by Erik Andersen + * , + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License + * for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Modified by Erik Andersen to be reentrant for + * the case when S != NULL... + */ + +#include +#include +#include +#include +#include + + +/* Generate a unique filename in /tmp. + * If s is NULL return NULL, making this function thread safe. */ + +char * tmpnam_r (char *s) +{ + if (s == NULL) + return NULL; + else + return (tmpnam(s)); +} + -- cgit v1.2.3