Back to index

tetex-bin  3.0
my-vsnprintf.c
Go to the documentation of this file.
00001 /*------------------------------------------------------------
00002 
00003 written by Stefan Ulrich <stefanulrich@users.sourceforge.net> 2001/02/25
00004 
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to
00007 deal in the Software without restriction, including without limitation the
00008 rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
00009 sell copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011 
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00016 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL PAUL VOJTA OR ANY OTHER AUTHOR OF THIS SOFTWARE BE
00019 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00020 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00021 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 ------------------------------------------------------------*/
00023 
00024 #include <string.h>
00025 #include <stdio.h>
00026 #include "xdvi-config.h"
00027 #include "xdvi.h"
00028 #include "my-vsnprintf.h"
00029 
00030 #if !HAVE_VSNPRINTF || !HAVE_GOOD_VSNPRINTF
00031 /*------------------------------------------------------------
00032  *  my_vsnprintf - emulation of glibc2.1 vsnprintf, use if
00033  *               vsnprintf is not available      
00034  *
00035  *  Arguments:
00036  *     char *buf     - buffer to print <format> string into
00037  *     int len              - print only len characters of <format>
00038  *     char *format  - format string
00039  *     va_list argp  - variable argument list
00040  *
00041  *  Returns:
00042  *      int size - number of characters that would have been
00043  *                written if enough space had been available
00044  *
00045  *  Purpose:
00046  *     Implementation of GNU's vsnprintf using POSIX pipes (less
00047  *      portable and much slower than the original, but also much
00048  *     easier to implement ;-):
00049  *     Print the formatted string to a pipe and read back
00050  *     at most len-1 characters, appending a '\0' at the end.
00051  *------------------------------------------------------------*/
00052 
00053 int
00054 my_vsnprintf(char *buf, int len, const char *format, va_list argp)
00055 {
00056     int pipe_fd[2];
00057     FILE *fd;
00058     int size;
00059 #ifdef DEBUG
00060     printf("=============my_vsnprintf called!\n");
00061 #endif
00062     len--;    /* for the trailing '\0' */
00063     
00064     /* create a pipe for reading/writing */
00065     if (xpipe(pipe_fd) == -1) {
00066        perror("my_vsnprintf: pipe");
00067        xdvi_exit(EXIT_FAILURE);
00068     }
00069     if ((fd = try_fdopen(pipe_fd[1], "w")) == NULL) {
00070        perror("my_vsnprintf: fdopen");
00071        xdvi_exit(EXIT_FAILURE);
00072     }
00073     /* instead of setting fd to non-buffering, flush it explicitly: */
00074     /*  setvbuf(fd, NULL, _IONBF, BUFSIZ); */
00075     size = vfprintf(fd, format, argp);
00076     fflush(fd);
00077 
00078     /* wrote less characters than len -> adjust len for the subsequent read */
00079     if (size < len) {
00080        len = size;
00081     }
00082     read(pipe_fd[0], buf, len);
00083     buf[len] = '\0';     /* always null-terminate */
00084 
00085     fclose(fd);
00086     close(pipe_fd[0]);
00087     close(pipe_fd[1]);
00088 
00089     return size;
00090 }
00091 
00092 #endif /* !HAVE_VSNPRINTF || !HAVE_GOOD_VSNPRINTF */