aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/ChangeLog22
-rw-r--r--util/Makefile.am18
-rw-r--r--util/argparse.c5
-rw-r--r--util/iobuf.c132
4 files changed, 168 insertions, 9 deletions
diff --git a/util/ChangeLog b/util/ChangeLog
index c693e3857..25034cfda 100644
--- a/util/ChangeLog
+++ b/util/ChangeLog
@@ -1,3 +1,13 @@
+2001-03-08 Werner Koch <[email protected]>
+
+ * argparse.c (default_strusage): Changed year of printed copyright
+ to 2001.
+
+ * iobuf.c (fd_cache_invalidate, fd_cache_close, fd_cache_open): New.
+ (direct_open): Invalidate the fd_cache for read access.
+ (file_filter): Cache the close here.
+ (iobuf_open): Use new my_fopen_ro macro to try the cache first.
+
2001-03-07 Werner Koch <[email protected]>
* iobuf.c: Made the old stdio file handling cpp conditional
@@ -606,3 +616,15 @@ Fri Feb 13 15:14:13 1998 Werner Koch ([email protected])
* argparse.c (show_help): New '\v' kludge.
+
+ Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
diff --git a/util/Makefile.am b/util/Makefile.am
index 5870fb6a9..407595989 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -1,3 +1,21 @@
+# Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+#
+# This file is part of GnuPG.
+#
+# GnuPG is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GnuPG 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 General Public License for more details.
+#
+# You should have received a copy of the GNU 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
+
## Process this file with automake to produce Makefile.in
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
diff --git a/util/argparse.c b/util/argparse.c
index 1fdc8d1bd..35144560a 100644
--- a/util/argparse.c
+++ b/util/argparse.c
@@ -1,5 +1,6 @@
/* [argparse.c wk 17.06.97] Argument Parser for option handling
- * Copyright (C) 1998,1999 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
@@ -898,7 +899,7 @@ default_strusage( int level )
switch( level ) {
case 11: p = "foo"; break;
case 13: p = "0.0"; break;
- case 14: p = "Copyright (C) 2000 Free Software Foundation, Inc."; break;
+ case 14: p = "Copyright (C) 2001 Free Software Foundation, Inc."; break;
case 15: p =
"This program comes with ABSOLUTELY NO WARRANTY.\n"
"This is free software, and you are welcome to redistribute it\n"
diff --git a/util/iobuf.c b/util/iobuf.c
index 5e46db272..ce4f93645 100644
--- a/util/iobuf.c
+++ b/util/iobuf.c
@@ -45,7 +45,8 @@
#ifdef FILE_FILTER_USES_STDIO
#define my_fileno(a) fileno ((a))
- #define my_fopen(a,b) fopen ((a),(b))
+ #define my_fopen_ro(a,b) fopen ((a),(b))
+ #define my_fopen(a,b) fopen ((a),(b))
typedef FILE *FILEP_OR_FD;
#define INVALID_FP NULL
#define FILEP_OR_FD_FOR_STDIN (stdin)
@@ -57,6 +58,7 @@
} file_filter_ctx_t ;
#else
#define my_fileno(a) (a)
+ #define my_fopen_ro(a,b) fd_cache_open ((a),(b))
#define my_fopen(a,b) direct_open ((a),(b))
#ifdef HAVE_DOSISH_SYSTEM
typedef HANDLE FILEP_OR_FD;
@@ -76,6 +78,14 @@
int print_only_name; /* flags indicating that fname is not a real file*/
char fname[1]; /* name of the file */
} file_filter_ctx_t ;
+
+ struct close_cache_s {
+ struct close_cache_s *next;
+ FILEP_OR_FD fp;
+ char fname[1];
+ };
+ typedef struct close_cache_s *CLOSE_CACHE;
+ static CLOSE_CACHE close_cache;
#endif
@@ -101,6 +111,33 @@ static int special_names_enabled;
static int underflow(IOBUF a);
#ifndef FILE_FILTER_USES_STDIO
+
+/*
+ * Invalidate (i.e. close) a cached iobuf
+ */
+static void
+fd_cache_invalidate (const char *fname)
+{
+ CLOSE_CACHE cc;
+
+ assert (fname);
+ if( DBG_IOBUF )
+ log_debug ("fd_cache_invalidate (%s)\n", fname);
+
+ for (cc=close_cache; cc; cc = cc->next ) {
+ if ( cc->fp != INVALID_FP && !strcmp (cc->fname, fname) ) {
+ #ifdef HAVE_DOSISH_SYSTEM
+ CloseHandle (cc->fp);
+ #else
+ close(cc->fp);
+ #endif
+ cc->fp = INVALID_FP;
+ }
+ }
+}
+
+
+
static FILEP_OR_FD
direct_open (const char *fname, const char *mode)
{
@@ -115,11 +152,13 @@ direct_open (const char *fname, const char *mode)
* something new for MS applications ;-)
*/
if ( strchr (mode, '+') ) {
+ fd_cache_invalidate (fname);
da = GENERIC_READ|GENERIC_WRITE;
cd = OPEN_EXISTING;
sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
}
else if ( strchr (mode, 'w') ) {
+ fd_cache_invalidate (fname);
da = GENERIC_WRITE;
cd = CREATE_ALWAYS;
sm = FILE_SHARE_WRITE;
@@ -137,15 +176,94 @@ direct_open (const char *fname, const char *mode)
int cflag = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
/* Note, that we do not handle all mode combinations */
- if ( strchr (mode, '+') )
+ if ( strchr (mode, '+') ) {
+ fd_cache_invalidate (fname);
oflag = O_RDWR;
- else if ( strchr (mode, 'w') )
+ }
+ else if ( strchr (mode, 'w') ) {
+ fd_cache_invalidate (fname);
oflag = O_WRONLY | O_CREAT | O_TRUNC;
- else
+ }
+ else {
oflag = O_RDONLY;
+ }
return open (fname, oflag, cflag );
#endif
}
+
+
+/*
+ * Instead of closing an FD we keep it open and cache it for later reuse
+ * Note that this caching strategy only works if the process does not chdir.
+ */
+static void
+fd_cache_close (const char *fname, FILEP_OR_FD fp)
+{
+ CLOSE_CACHE cc;
+
+ assert (fp);
+ if ( !fname || !*fname ) {
+#ifdef HAVE_DOSISH_SYSTEM
+ CloseHandle (fp);
+#else
+ close(fp);
+#endif
+ if( DBG_IOBUF )
+ log_debug ("fd_cache_close (%s) immediately\n", fname);
+ return;
+ }
+ /* try to reuse a slot */
+ for (cc=close_cache; cc; cc = cc->next ) {
+ if ( cc->fp == INVALID_FP && !strcmp (cc->fname, fname) ) {
+ cc->fp = fp;
+ }
+ }
+ /* add a new one */
+ if( DBG_IOBUF )
+ log_debug ("fd_cache_close (%s) new\n", fname);
+ cc = m_alloc_clear (sizeof *cc + strlen (fname));
+ strcpy (cc->fname, fname);
+ cc->fp = fp;
+ cc->next = close_cache;
+ close_cache = cc;
+}
+
+/*
+ * Do an direct_open on FNAME but first try to reuse one from the fd_cache
+ */
+static FILEP_OR_FD
+fd_cache_open (const char *fname, const char *mode)
+{
+ CLOSE_CACHE cc;
+
+ assert (fname);
+ for (cc=close_cache; cc; cc = cc->next ) {
+ if ( cc->fp != INVALID_FP && !strcmp (cc->fname, fname) ) {
+ FILEP_OR_FD fp = cc->fp;
+ cc->fp = INVALID_FP;
+ if( DBG_IOBUF )
+ log_debug ("fd_cache_open (%s) hit\n", fname);
+ #ifdef HAVE_DOSISH_SYSTEM
+ if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff ) {
+ log_error ("rewind file failed on handle %p: ec=%d\n",
+ fp, (int)GetLastError () );
+ fp = INVALID_FP;
+ }
+ #else
+ if ( lseek (fp, 0, SEEK_SET) == (off_t)-1 ) {
+ log_error("can't rewind fd %d: %s\n", fp, strerror(errno) );
+ fp = INVALID_FP;
+ }
+ #endif
+ return fp;
+ }
+ }
+ if( DBG_IOBUF )
+ log_debug ("fd_cache_open (%s) miss\n", fname);
+ return direct_open (fname, mode);
+}
+
+
#endif /*FILE_FILTER_USES_STDIO*/
@@ -334,13 +452,13 @@ file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
if ( f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT ) {
if( DBG_IOBUF )
log_debug("%s: close handle %p\n", a->fname, f );
- CloseHandle (f);
+ fd_cache_close (a->fname, f);
}
#else
if ( (int)f != 0 && (int)f != 1 ) {
if( DBG_IOBUF )
log_debug("%s: close fd %d\n", a->fname, f );
- close(f);
+ fd_cache_close (a->fname, f);
}
f = INVALID_FP;
#endif
@@ -825,7 +943,7 @@ iobuf_open( const char *fname )
}
else if ( (fd = check_special_filename ( fname )) != -1 )
return iobuf_fdopen ( iobuf_translate_file_handle (fd,0), "rb" );
- else if( (fp = my_fopen(fname, "rb")) == INVALID_FP )
+ else if( (fp = my_fopen_ro(fname, "rb")) == INVALID_FP )
return NULL;
a = iobuf_alloc(1, 8192 );
fcx = m_alloc( sizeof *fcx + strlen(fname) );