Здравствуйте.
Оказывается что есть у fopen в солярке проблема: "безпричинный" отказ
"too many files opened".
И этот баг сильно мешает работать tsearch2 - время от времени tsearch2
не может открыть файлы словарей.
Предлагаю вот такие патчи (для dict_syn.c, stopword.c, ispell/spell.c),
которые у меня искоренили проблему полностью.
И покачто tsearch2 работает хорошо.
Скорее всего как есть они вам не понравится, но идея надеюсь будет
использована в будущем.
--- contrib/tsearch2/dict_syn.c.orig Tue Aug 7 11:31:33 2007
+++ contrib/tsearch2/dict_syn.c Tue Aug 7 11:54:05 2007
@@ -7,6 +7,10 @@
#include "postgres.h"
#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
#include "dict.h"
#include "common.h"
@@ -64,7 +68,7 @@
text *in;
DictSyn *d;
int cur = 0;
- FILE *fin;
+ int fd = -1;
char *filename;
char buf[SYNBUFLEN];
char *starti,
@@ -85,23 +89,24 @@
filename = text2char(in);
PG_FREE_IF_COPY(in, 0);
- if ((fin = fopen(filename, "r")) == NULL)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open file \"%s\": %m",
- filename)));
+ if ( -1 == ( fd = open( filename, O_RDONLY ) ) )
+ {
+ char *errbuff = strerror(errno);
+ ereport(ERROR, (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
+ errmsg("%s.%i: Could not load %s. %s", __FILE__, __LINE__, filename, errbuff)));
+ }
d = (DictSyn *) malloc(sizeof(DictSyn));
if (!d)
{
- fclose(fin);
+ close(fd);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
}
memset(d, 0, sizeof(DictSyn));
- while (fgets(buf, SYNBUFLEN, fin))
+ while ( read(fd, buf, SYNBUFLEN ) )
{
slen = strlen(buf) - 1;
buf[slen] = '\0';
@@ -113,7 +118,7 @@
d->syn = (Syn *) realloc(d->syn, sizeof(Syn) * d->len);
if (!d->syn)
{
- fclose(fin);
+ close(fd);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
@@ -136,7 +141,7 @@
d->syn[cur].out = strdup(lowerstr(starto));
if (!(d->syn[cur].in && d->syn[cur].out))
{
- fclose(fin);
+ close(fd);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
@@ -145,7 +150,7 @@
cur++;
}
- fclose(fin);
+ close(fd);
d->len = cur;
if (cur > 1)
--- contrib/tsearch2/ispell/spell.c.orig Tue Jul 31 16:45:45 2007
+++ contrib/tsearch2/ispell/spell.c Tue Aug 7 11:47:45 2007
@@ -1,6 +1,10 @@
#include "postgres.h"
#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
#include "spell.h"
#include "common.h"
@@ -148,11 +152,16 @@
NIImportDictionary(IspellDict * Conf, const char *filename)
{
char str[BUFSIZ], *pstr;
- FILE *dict;
-
- if (!(dict = fopen(filename, "r")))
+ int fd = -1;
+ if ( -1 == ( fd = open( filename, O_RDONLY ) ) )
+ {
+ char *errbuff = strerror(errno);
+ ereport(ERROR, (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
+ errmsg("%s.%i: Could not load %s. %s", __FILE__, __LINE__, filename, errbuff)));
return (1);
- while (fgets(str, sizeof(str), dict))
+ }
+
+ while ( read(fd, str, sizeof(str) ) )
{
char *s;
const char *flag;
@@ -195,7 +204,7 @@
NIAddSpell(Conf, pstr, flag);
pfree(pstr);
}
- fclose(dict);
+ close(fd);
return (0);
}
@@ -428,15 +437,21 @@
int prefixes = 0;
int flag = 0;
char flagflags = 0;
- FILE *affix;
+ int fd = -1;
int line = 0;
int oldformat = 0;
- if (!(affix = fopen(filename, "r")))
+ if ( -1 == ( fd = open( filename, O_RDONLY ) ) )
+ {
+ char *errbuff = strerror(errno);
+ ereport(ERROR, (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
+ errmsg("%s.%i: Could not load %s. %s", __FILE__, __LINE__, filename, errbuff)));
return (1);
+ }
+
Conf->compoundcontrol = '\t';
- while (fgets(str, sizeof(str), affix))
+ while ( read(fd, str, sizeof(str) ) )
{
line++;
if ( *str == '#' || *str == '\n' )
@@ -519,7 +534,7 @@
if (oldformat)
elog(ERROR, "Wrong affix file format");
- fclose(affix);
+ close(fd);
return NIImportOOAffixes(Conf, filename);
}
@@ -531,7 +546,7 @@
NIAddAffix(Conf, flag, flagflags, mask, find, repl, suffixes ? FF_SUFFIX : FF_PREFIX);
}
- fclose(affix);
+ close(fd);
if ( pstr )
pfree( pstr );
@@ -551,18 +566,24 @@
bool isSuffix = false;
int flag = 0;
char flagflags = 0;
- FILE *affix;
+ int fd = -1;
int line = 0;
int scanread = 0;
char scanbuf[BUFSIZ];
sprintf(scanbuf, "%%6s %%%ds %%%ds %%%ds %%%ds", BUFSIZ / 5, BUFSIZ / 5, BUFSIZ / 5, BUFSIZ / 5);
- if (!(affix = fopen(filename, "r")))
+ if ( -1 == ( fd = open( filename, O_RDONLY ) ) )
+ {
+ char *errbuff = strerror(errno);
+ ereport(ERROR, (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
+ errmsg("%s.%i: Could not load %s. %s", __FILE__, __LINE__, filename, errbuff)));
return (1);
+ }
+
Conf->compoundcontrol = '\t';
- while (fgets(str, sizeof(str), affix))
+ while ( read(fd, str, sizeof(str) ) )
{
line++;
if (*str == '\0' || t_isspace(str) || t_iseq(str, '#'))
@@ -622,7 +643,7 @@
if (ptype)
pfree(ptype);
- fclose(affix);
+ close(fd);
return 0;
}
--- contrib/tsearch2/stopword.c.orig Tue Aug 7 11:31:48 2007
+++ contrib/tsearch2/stopword.c Tue Aug 7 12:00:12 2007
@@ -4,6 +4,11 @@
*/
#include "postgres.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
#include "common.h"
#include "dict.h"
#include "ts_locale.h"
@@ -35,17 +40,18 @@
if (in && VARSIZE(in) - VARHDRSZ > 0)
{
char *filename = to_absfilename(text2char(in));
- FILE *hin;
+ int fd = -1;
char buf[STOPBUFLEN], *pbuf;
int reallen = 0;
- if ((hin = fopen(filename, "r")) == NULL)
- ereport(ERROR,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("could not open file \"%s\": %m",
- filename)));
+ if ( -1 == ( fd = open( filename, O_RDONLY ) ) )
+ {
+ char *errbuff = strerror(errno);
+ ereport(ERROR, (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
+ errmsg("%s.%i: Could not load %s. %s", __FILE__, __LINE__, filename, errbuff)));
+ }
- while (fgets(buf, STOPBUFLEN, hin))
+ while ( read(fd, buf, STOPBUFLEN ) )
{
buf[strlen(buf) - 1] = '\0';
pg_verifymbstr(buf, strlen(buf), false);
@@ -61,7 +67,7 @@
if (!tmp)
{
freestoplist(s);
- fclose(hin);
+ close(fd);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
@@ -80,7 +86,7 @@
if (!stop[s->len])
{
freestoplist(s);
- fclose(hin);
+ close(fd);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
@@ -88,7 +94,7 @@
(s->len)++;
}
- fclose(hin);
+ close(fd);
pfree(filename);
}
s->stop = stop;