Xapian on Windows for users with a non-ASCII login
Jean-Francois Dockes
jf at dockes.org
Fri Aug 21 09:58:48 BST 2026
Olly Betts writes:
> Thanks for the -A patch - I've merged it.
Thanks !
> On Thu, Aug 20, 2026 at 11:14:47AM +0200, Jean-Francois Dockes wrote:
> > Olly Betts writes:
> > > On Wed, Aug 19, 2026 at 05:19:30PM +0200, Jean-Francois Dockes wrote:
> > > | > In terms of workarounds, simply changing directory to where the
> > > | > database lives and then using a relative non-wide path should work.
> > > |
> > > | It quite probably would, assuming that Xapian never computes an
> > > | absolute path (which you know, but I don't without scanning the code), and
> > > | also that there are no getcwd/chdir Windows pitfalls waiting for me...
> > >
> > > There are no calls to getcwd() at all.
> > >
> > > In general, I'd expect a library to avoid chdir() (unless that's part
> > > of its purpose perhaps) as it changes the current directory for the
> > > application too. Xapian has a single call to chdir() in C/C++ code in
> > > Unix-specific locking code where we chdir("/") after fork() when we
> > > don't have OFD locks available (so the current directory of the
> > > lock-holding subprocess can't block unmounting of a filesystem).
> > >
> > > I'm pretty sure we don't compute absolute paths anywhere. We do resolve
> > > relative paths against a base directory, but that base directory can
> > > itself be a relative path in which case the result is still relative.
> >
> > The Recoll indexer changes its current directory to one specified by the
> > runtime configuration (TMPDIR by default), because some executed external
> > format handlers tend/used to create temporary files in the current
> > directory and are/were not too good with cleanup.
>
> You could probably fork() then chdir() then exec() so the parent indexer
> process doesn't need to chdir() to the scratch directory.
Yes, this is a good idea, I probably did not think long enough at the
time. Plugging a chdir in the programs' init function was simplest. Windows
CreateProcess() also has a current directory parameter, so this would have
been portable.
> I've also definitely seen some filters leave junk in the current
> directory, but omindex doesn't currently chdir() at all. I guess we
> must have worked around it with chdir() in a local script to run omindex
> rather than addressing it in the omega code. For an upstream-able
> omindex fix we'd need to ensure the filenames of files being indexed
> were absolute (which probably can be achieved by resolving a relative
> start directory to an absolute path once at the start of an indexing
> run). I've made a note to look into this.
Being a user app, recoll can be started from anywhere, so it converts all
paths to absolute.
> > > I think the best way forwards is probably something you suggested in the
> > > previous thread - move to using std::filesystem. We now require C++17,
> > > so it should be available. I'm not sure how big a job that is though
> > > (I've not used std::filesystem anywhere yet).
> >
> > I had another look at std::filesystem, and I don't think that it really
> > solves the problem, it just dispatches depending on the input type (char vs
> > wchar_t), and/or an explicit locale spec instead of having separate
> > calls. To make use of it, it seems to me that you would have to increase
> > the complexity of the Database interface by providing overloads for the
> > methods which take paths. Maybe I'm wrong.
>
> We might want to anyway, since that's useful for user code which uses
> std::filesystem.
I looked a bit closer, and I think that using std::filesystem::path solves
both the case of unspecified char input (it uses the Windows code page,
including of course UTF-8 if this is in use) and the case of explicit UTF-8
input: use u8path (c++17) or char8_t (c++20). I agree that this is the way
forward, but of course this would have been a vastly more intrusive change
than the current patch.
> > I still think that the approach in the patch is best on Windows: use the
> > wide Win32 API when UTF-8 is detected, else use the narrow API and hope for
> > the best. This keeps the Xapian API unchanged and maintains compatibility
> > for hypothetical code which might be relying on code pages. The
> > implementation is a bit wasteful if the input is actually ASCII, but the
> > performance impact is probably negligible.
>
> Didn't Microsoft finally add support for UTF-8 locales though? Does
> this work correctly in that case?
I think that, yes, if the current code page is UTF-8, the unpatched code
should work. I did not try though.
According to Gemini: UTF-8 is not the default code page for any Windows
version at the moment, but, for recent versions (Windows 10 version 1903),
you can force UTF-8 for a specific application through an "application
manifest".
The latter would be another possible approach, which I would be tempted to
use if the current patch did not exist and work unconditionally.
Cheers,
jf
More information about the Xapian-discuss
mailing list