diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 070be8861c25537df8dda31cf97a630d5e125125..fa016c7353d2846519606486aa4362005b0dcc6c 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -6,7 +6,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.56 1998/08/29 05:27:15 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.57 1998/08/29 18:19:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -108,12 +108,21 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, the class. ----------------------------------------------------------------------------*/ - FILE *fp; + static FILE *fp; /* static for cleanup */ + static bool file_opened = false; /* static for cleanup */ Relation rel; extern char *UserName; /* defined in global.c */ const AclMode required_access = from ? ACL_WR : ACL_RD; int result; + /* + * Close previous file opened for COPY but failed with elog(). + * There should be a better way, but would not be modular. + * Prevents file descriptor leak. bjm 1998/08/29 + */ + if (file_opened) + FreeFile(fp); + rel = heap_openr(relname); if (rel == NULL) elog(ERROR, "COPY command failed. Class %s " @@ -146,14 +155,13 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, } else { - /* if we elog() out, the file stays open */ fp = AllocateFile(filename, "r"); if (fp == NULL) elog(ERROR, "COPY command, running in backend with " "effective uid %d, could not open file '%s' for " "reading. Errno = %s (%d).", geteuid(), filename, strerror(errno), errno); - /* Above should not return */ + file_opened = true; } CopyFrom(rel, binary, oids, fp, delim); } @@ -174,7 +182,6 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, mode_t oumask; /* Pre-existing umask value */ oumask = umask((mode_t) 0); - /* if we elog() out, the file stays open */ fp = AllocateFile(filename, "w"); umask(oumask); if (fp == NULL) @@ -182,12 +189,15 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe, "effective uid %d, could not open file '%s' for " "writing. Errno = %s (%d).", geteuid(), filename, strerror(errno), errno); - /* Above should not return */ + file_opened = true; } CopyTo(rel, binary, oids, fp, delim); } if (!pipe) + { FreeFile(fp); + file_opened = false; + } else if (!from && !binary) { fputs("\\.\n", fp);