• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

plstdio.c

Go to the documentation of this file.
00001 // $Id: plstdio.c 11257 2010-10-11 22:34:18Z airwin $
00002 //
00003 // Standardized I/O handler for PLplot.
00004 //
00005 // Copyright (C) 2006  Jim Dishaw
00006 // Copyright (C) 2006  Hazen Babcock
00007 //
00008 // This file is part of PLplot.
00009 //
00010 // PLplot is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Library General Public License as published
00012 // by the Free Software Foundation; either version 2 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // PLplot is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Library General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Library General Public License
00021 // along with PLplot; if not, write to the Free Software
00022 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00023 //
00024 //
00025 
00026 #define NEED_PLDEBUG
00027 #include "plplotP.h"
00028 
00029 #if defined ( MSDOS ) || defined ( WIN32 )
00030 #include <sys/types.h>
00031 #include <sys/stat.h>
00032 #include <fcntl.h>
00033 #endif
00034 
00035 // For Visual C++ 2005 and later mktemp() and open() are deprecated (see
00036 // http://msdn.microsoft.com/en-us/library/ms235413.aspx and
00037 // http://msdn.microsoft.com/en-us/library/ms235491.aspx). mktemp()
00038 // is redefined to _mktemp() as well as open() to _open(). In addition
00039 // we need to include io.h.
00040 //
00041 #if defined ( _MSC_VER ) && _MSC_VER >= 1400
00042 #include <io.h>
00043 #define mktemp    _mktemp
00044 #define open      _open
00045 #define fdopen    _fdopen
00046 #endif
00047 //
00048 // plio_write()
00049 //
00050 // Writes the contents of buf to stream.  Handles any I/O error conditions
00051 // so that the caller can "fire and forget."
00052 //
00053 
00054 void
00055 plio_fwrite( void *buf, size_t size, size_t nmemb, FILE *stream )
00056 {
00057     size_t bytes;
00058 
00059     dbug_enter( "plio_fwrite" );
00060 
00061     // Exit if there is nothing to write
00062     if ( size == 0 || nmemb == 0 )
00063         return;
00064 
00065     // Clear the error flag for this steam
00066     clearerr( stream );
00067 
00068     bytes = fwrite( buf, size, nmemb, stream );
00069 
00070     if ( ferror( stream ) )
00071     {
00072         // Perhaps we can add a flag (global or per output stream)
00073         // in order to decide if we should abort or warn.  I think
00074         // I/O errors should generate an abort
00075         plabort( "Error writing to file" );
00076     }
00077 }
00078 
00079 //
00080 // plio_read()
00081 //
00082 // Read from stream into buf.  Like plio_write(), this function will
00083 // handle any I/O error conditions.
00084 //
00085 
00086 void
00087 plio_fread( void *buf, size_t size, size_t nmemb, FILE *stream )
00088 {
00089     size_t bytes;
00090 
00091     dbug_enter( "plio_fread" );
00092 
00093     // If the buffer has a size of zero, we should complain
00094     if ( size == 0 || nmemb == 0 )
00095     {
00096         plwarn( "Zero length buffer size in plio_read, returning" );
00097         return;
00098     }
00099 
00100     // Clear the error flag for this steam
00101     clearerr( stream );
00102 
00103     bytes = fread( buf, size, nmemb, stream );
00104 
00105     if ( ferror( stream ) )
00106     {
00107         // The read resulted in an error
00108         plabort( "Error reading from file" );
00109     }
00110 }
00111 
00112 //
00113 // plio_fgets()
00114 //
00115 // Read from stream into buf.  This version of fgets is designed for the occasions
00116 // where the caller wants to ignore the return value.
00117 //
00118 // NOTE: If one is reading from a file until an EOF condition, fgets() is better suited
00119 // than this function, i.e.
00120 //
00121 //     while(fgets(buf, size, fp) != NULL) { ... do some stuff ... }
00122 //
00123 // rather than
00124 //
00125 //     while(!feof(fp)) { plio_fgets(buf, size, fp);  ... do some stuff ... }
00126 //
00127 // which would require checking for an empty buffer.
00128 //
00129 
00130 void
00131 plio_fgets( char *buf, int size, FILE *stream )
00132 {
00133     char *s;
00134 
00135     dbug_enter( "plio_fgets" );
00136 
00137     // If the buffer has a size of zero, we should complain
00138     if ( size == 0 )
00139     {
00140         plwarn( "Zero length buffer size in plio_fgets, returning" );
00141         return;
00142     }
00143 
00144     // Clear the error flag for this steam
00145     clearerr( stream );
00146 
00147     s = fgets( buf, size, stream );
00148 
00149     if ( s == NULL && ferror( stream ) )
00150     {
00151         // The read resulted in an error
00152         plabort( "Error reading from file" );
00153     }
00154 }
00155 
00156 //
00157 // pl_create_tempfile()
00158 //
00159 // Securely create a temporary file and return a file handle to it.
00160 // This provides cross-platform compatibility and also adds some
00161 // additional functionality over mkstemp in that it honours the TMP /
00162 // TMPDIR / TEMP environment variables.
00163 //
00164 // The function returns the file handle.
00165 //
00166 // If the fname variable is not NULL, then on return it will contain
00167 // a pointer to the full temporary file name. This will be allocated
00168 // with malloc. It is the caller's responsibility to ensure this
00169 // memory is free'd and to ensure the file is deleted after use.
00170 // If fname is NULL then the file will be automatically deleted
00171 // when it is closed.
00172 //
00173 FILE *
00174 pl_create_tempfile( char **fname )
00175 {
00176     int        flags;
00177     FILE       *fd;
00178     char       *tmpdir;
00179     char       *template;
00180     const char *tmpname = "plplot_XXXXXX";
00181 
00182 #if defined ( MSDOS ) || defined ( WIN32 )
00183     tmpdir = getenv( "TEMP" );
00184 #else
00185     tmpdir = getenv( "TMPDIR" );
00186 #endif
00187 
00188 // The P_TMPDIR macro is defined in stdio.h on many UNIX systems - try that
00189 #ifdef P_TMPDIR
00190     if ( tmpdir == NULL )
00191         tmpdir = P_TMPDIR;
00192 #endif
00193 
00194     if ( tmpdir == NULL )
00195     {
00196 #if defined ( MSDOS ) || defined ( WIN32 )
00197         tmpdir = "c:\\windows\\Temp";
00198 #else
00199         tmpdir = "/tmp";
00200 #endif
00201     }
00202 
00203     // N.B. Malloc ensures template is long enough so strcpy and strcat are safe here
00204     template = (char *) malloc( sizeof ( char ) * ( strlen( tmpdir ) + strlen( tmpname ) + 2 ) );
00205     strcpy( template, tmpdir );
00206 #if defined ( MSDOS ) || defined ( WIN32 )
00207     strcat( template, "\\" );
00208 #else
00209     strcat( template, "/" );
00210 #endif
00211     strcat( template, tmpname );
00212 
00213 #ifdef PL_HAVE_MKSTEMP
00214     fd = fdopen( mkstemp( template ), "wb+" );
00215     if ( fd == NULL )
00216     {
00217         plwarn( "pl_create_tempfile: Unable to open temporary file - returning" );
00218         if ( fname != NULL )
00219             *fname = NULL;
00220         free( template );
00221         return NULL;
00222     }
00223     // If we are not returning the file name then unlink the file so it is
00224     // automatically deleted.
00225 #ifdef PL_HAVE_UNLINK
00226     if ( fname == NULL )
00227         unlink( template );
00228 #endif
00229 #else
00230 #if !defined ( _S_IREAD )
00231 #define _S_IREAD     256
00232 #endif
00233 #if !defined ( _S_IWRITE )
00234 #define _S_IWRITE    128
00235 #endif
00236     fd    = NULL;
00237     flags = O_RDWR | O_BINARY | O_CREAT | O_EXCL | _O_SHORT_LIVED;
00238     // If we are not returning the file name then add flag to automatically
00239     // delete file once all file handles are closed.
00240     if ( fname == NULL )
00241         flags = flags | _O_TEMPORARY;
00242     mktemp( template );
00243     fd = fdopen( open( template, flags, _S_IREAD | _S_IWRITE ), "wb+" );
00244 #endif
00245 
00246     if ( fname != NULL )
00247     {
00248         *fname = template;
00249     }
00250     else
00251     {
00252         free( template );
00253     }
00254 
00255     return fd;
00256 }
00257 

Generated on Wed Oct 12 2011 20:42:22 for PLplot by  doxygen 1.7.1