* do_edit -- handler for \e * * If you do not specify a filename, the current query buffer will be copied * into a temporary file. * * After this function is done, the resulting file will be copied back into the * query buffer. As an exception to this, the query buffer will be emptied * if the file was not modified (or the editor failed) and the caller passes * "discard_on_quit" = true.
| 3811 | * is successfully replaced. |
| 3812 | */ |
| 3813 | static bool |
| 3814 | do_edit(const char *filename_arg, PQExpBuffer query_buf, |
| 3815 | int lineno, bool discard_on_quit, bool *edited) |
| 3816 | { |
| 3817 | char fnametmp[MAXPGPATH]; |
| 3818 | FILE *stream = NULL; |
| 3819 | const char *fname; |
| 3820 | bool error = false; |
| 3821 | int fd; |
| 3822 | struct stat before, |
| 3823 | after; |
| 3824 | |
| 3825 | if (filename_arg) |
| 3826 | fname = filename_arg; |
| 3827 | else |
| 3828 | { |
| 3829 | /* make a temp file to edit */ |
| 3830 | #ifndef WIN32 |
| 3831 | const char *tmpdir = getenv("TMPDIR"); |
| 3832 | |
| 3833 | if (!tmpdir) |
| 3834 | tmpdir = "/tmp"; |
| 3835 | #else |
| 3836 | char tmpdir[MAXPGPATH]; |
| 3837 | int ret; |
| 3838 | |
| 3839 | ret = GetTempPath(MAXPGPATH, tmpdir); |
| 3840 | if (ret == 0 || ret > MAXPGPATH) |
| 3841 | { |
| 3842 | pg_log_error("could not locate temporary directory: %s", |
| 3843 | !ret ? strerror(errno) : ""); |
| 3844 | return false; |
| 3845 | } |
| 3846 | #endif |
| 3847 | |
| 3848 | /* |
| 3849 | * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the |
| 3850 | * current directory to the supplied path unless we use only |
| 3851 | * backslashes, so we do that. |
| 3852 | */ |
| 3853 | #ifndef WIN32 |
| 3854 | snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir, |
| 3855 | "/", (int) getpid()); |
| 3856 | #else |
| 3857 | snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir, |
| 3858 | "" /* trailing separator already present */ , (int) getpid()); |
| 3859 | #endif |
| 3860 | |
| 3861 | fname = (const char *) fnametmp; |
| 3862 | |
| 3863 | fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0600); |
| 3864 | if (fd != -1) |
| 3865 | stream = fdopen(fd, "w"); |
| 3866 | |
| 3867 | if (fd == -1 || !stream) |
| 3868 | { |
| 3869 | pg_log_error("could not open temporary file \"%s\": %m", fname); |
| 3870 | error = true; |
no test coverage detected