-
Notifications
You must be signed in to change notification settings - Fork 253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change TMPPATH to the standard TMPDIR in configuration #1334
Conversation
Would it be feasible to query from tempfile import NamedTemporaryFile
f = NamedTemporaryFile()
print(f.name)
f.close() is able to use a different temporary location upon each execution:
I mainly use flint through sage, and sage through python, so in the rare event that someone wants to override |
We could check against the environment like we do in |
That's a better idea, I didn't realize how isolated the temp path usage is. Thanks again. |
I'm wondering if this PR might be the cause of the problem I'm seeing with The failure is:
|
One guess: were you setting Otherwise the easiest way to debug this is going to be to tweak https://github.com/flintlib/flint2/blob/ef89816abda221fc40cb4a960430cb570ef0f43c/src/qsieve/factor.c#L225 to output which error occurred. |
I don't have
I also see the failure in CI and I am not sure what environment variables are set there:
I'll have to see if I reproduce this with a local build (rather than the CI build). |
I don't think these should be acting differently. The old behavior was to default to |
Something has definitely changed :) I changed the relevant code to: strcpy(qs_inf->fname, FLINT_TMPDIR "/siqsXXXXXX");
printf("qsinf->fname= \"%s\"\n", qs_inf->fname);
fd = mkstemp(qs_inf->fname);
if (fd == -1) {
perror("perror shows");
flint_throw(FLINT_ERROR, "mkstemp failed\n");
} The output then is is:
I tried to reproduce that in plain C without flint etc: #include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int fd = mkstemp("/tmp/siqsXXXXXX");
return 0;
} That gives a segfault though (I must be doing something stupid here but I'm too tired to see it!): $ gcc test.c
$ ./a.exe
Segmentation fault |
And in the morning it becomes obvious. The argument to #include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char fname[] = "/tmp/siqsXXXXXX";
int fd = mkstemp(fname);
printf("fd = %d\n", fd);
perror("perror shows");
return 0;
} This program runs fine on Linux and shows: $ gcc test.c
$ ./a.out
fd = 3
perror shows: Success However it fails with "no such file or directory" when compiled with mingw64 and run under Windows: pc@NUCPC MINGW64 /c/Users/pc/src/flint/python-flint/test_dir/test_mkstemp
$ gcc --version
gcc.exe (Rev4, Built by MSYS2 project) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
pc@NUCPC MINGW64 /c/Users/pc/src/flint/python-flint/test_dir/test_mkstemp
$ cat test.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char fname[] = "/tmp/siqsXXXXXX";
int fd = mkstemp(fname);
printf("fd = %d\n", fd);
perror("perror shows");
return 0;
}
pc@NUCPC MINGW64 /c/Users/pc/src/flint/python-flint/test_dir/test_mkstemp
$ gcc test.c
pc@NUCPC MINGW64 /c/Users/pc/src/flint/python-flint/test_dir/test_mkstemp
$ ./a.exe
fd = -1
perror shows: No such file or directory |
Comparing with Flint 2.9.0 it seems that |
I'm not sure how this is supposed to work with mingw. in cmd.exe the TMP env var is set correctly:
In the mingw shell it shows differently:
However mingw translates this to the same directory:
If I change the path in the test program above explicitly to I am not sure exactly when and where this translation between unix paths and Windows paths happens. At runtime the flint code sees Presumably then it is the job of that mingw translation layer somewhere to make |
I'm not sure but this seems like a mingw bug. I'm just wondering now what Taking a step back it seems somewhat surprising that >>> import tempfile
>>> tempfile.gettempdir()
'C:\\Users\\pc\\AppData\\Local\\Temp' There are a few functions that indirectly call through to |
Actually this is not true. The problem is just that "/tmp" is baked into the binary.
Or perhaps just the Still though being able to set this explicitly from the Python side would be better in python_flint's case. |
So the translation happens in the environment, and not in the call to
Using But, yes, this one function is the only place that uses the temporary directory, and it can probably be eliminated. That actually already came up earlier in the discussion: #1334 (comment) #1334 (comment) |
I think so. I find it hard to be sure about anything with MinGW but I think the idea is that although its shell messes around with things to emulate a unix-like environment the binaries produced by gcc are still supposed to be ordinary Windows binaries. Within the binary itself all paths should be Windows paths and so If I am right about that then this is not a mingw bug: the bug is that Flint hardcodes The non-MinGW Windows path here uses It looks like
Presumably The Linux and OSX CI for python_flint pass without having configured anything for I guess if Flint CI uses
Ultimately that would be best. For now though this leaves python_flint in a bit of a bind: without some change in Flint there is nothing that python_flint can do to generate a wheel whose What python_flint needs is one of:
If the ultimate plan is 3. then probably 2. is not a good temporary solution. Perhaps then the proper fix is 1. using something like |
Actually it is only the MinGW CI job that uses |
One thing I still don't understand is, how did the behavior change? Even before #1201, |
I presume you have read the lengthy explanation in gh-1416.
That's not true unless I've misunderstood something. Before gh-1201 the current working directory was used (as explained in that PR). The prior code was: #if defined (__WIN32) && !defined(__CYGWIN__)
srand((int) GetCurrentProcessId());
#else
srand((int) getpid());
#endif
nchars = sprintf(qs_inf->fname, "%d", (int) rand());
strcat(qs_inf->fname + nchars, "siqs.dat");
qs_inf->siqs = fopen(qs_inf->fname, "w"); So the pid is used to seed As of gh-1416 the appropriate temporary directory is used on Windows or for other platforms it is hard-coded to This is not really my expertise but I think that
https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap10.html That suggests that gh-1416 should be fine and that the only way to potentially improve it is to use the environment variable |
You're right, I misread the diff.
Agreed as far as temporary file handling goes, but doing it in memory would eliminate the platform-specific |
Yes, of course that would be better. Removing the use of files seems to have been suggested a few times and I'm sure several people have looked at it and thought about it. I did consider changing that myself but then when I actually looked at the code I immediately decided to go for a quicker fix. |
Thanks to @orlitzky