use dynwind_begin and dynwind_end
[bpt/emacs.git] / src / cygw32.c
CommitLineData
f701ab72 1/* Cygwin support routines.
ba318903 2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
f701ab72
DC
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
18
19
20#include "cygw32.h"
21#include "character.h"
22#include "buffer.h"
23#include <unistd.h>
24#include <fcntl.h>
f701ab72 25
27e498e6
PE
26static void
27fchdir_unwind (int dir_fd)
f701ab72 28{
27e498e6
PE
29 (void) fchdir (dir_fd);
30 (void) close (dir_fd);
f701ab72
DC
31}
32
33static void
34chdir_to_default_directory ()
35{
36 Lisp_Object new_cwd;
406af475 37 int old_cwd_fd = emacs_open (".", O_RDONLY | O_DIRECTORY, 0);
f701ab72
DC
38
39 if (old_cwd_fd == -1)
40 error ("could not open current directory: %s", strerror (errno));
41
27e498e6 42 record_unwind_protect_int (fchdir_unwind, old_cwd_fd);
f701ab72
DC
43
44 new_cwd = Funhandled_file_name_directory (
45 Fexpand_file_name (build_string ("."), Qnil));
46 if (!STRINGP (new_cwd))
47 new_cwd = build_string ("/");
48
49 if (chdir (SDATA (ENCODE_FILE (new_cwd))))
50 error ("could not chdir: %s", strerror (errno));
51}
52
53static Lisp_Object
54conv_filename_to_w32_unicode (Lisp_Object in, int absolute_p)
55{
56 ssize_t converted_len;
57 Lisp_Object converted;
58 unsigned flags;
2bfa3d3e 59 dynwind_begin ();
f701ab72
DC
60
61 chdir_to_default_directory ();
62
63 flags = CCP_POSIX_TO_WIN_W;
64 if (!absolute_p) {
65 flags |= CCP_RELATIVE;
66 }
67
68 in = ENCODE_FILE (in);
69
70 converted_len = cygwin_conv_path (flags, SDATA (in), NULL, 0);
71 if (converted_len < 2)
72 error ("cygwin_conv_path: %s", strerror (errno));
73
74 converted = make_uninit_string (converted_len - 1);
75 if (cygwin_conv_path (flags, SDATA (in),
76 SDATA (converted), converted_len))
77 error ("cygwin_conv_path: %s", strerror (errno));
78
2bfa3d3e
BT
79 dynwind_end ();
80 return converted;
f701ab72
DC
81}
82
83static Lisp_Object
84conv_filename_from_w32_unicode (const wchar_t* in, int absolute_p)
85{
86 ssize_t converted_len;
87 Lisp_Object converted;
88 unsigned flags;
2bfa3d3e 89 dynwind_begin ();
f701ab72
DC
90
91 chdir_to_default_directory ();
92
93 flags = CCP_WIN_W_TO_POSIX;
94 if (!absolute_p) {
95 flags |= CCP_RELATIVE;
96 }
97
98 converted_len = cygwin_conv_path (flags, in, NULL, 0);
99 if (converted_len < 1)
100 error ("cygwin_conv_path: %s", strerror (errno));
101
102 converted = make_uninit_string (converted_len - 1 /*subtract terminator*/);
103 if (cygwin_conv_path (flags, in, SDATA (converted), converted_len))
104 error ("cygwin_conv_path: %s", strerror (errno));
105
2bfa3d3e
BT
106 Lisp_Object tem0 = DECODE_FILE (converted);
107 dynwind_end ();
108 return tem0;
f701ab72
DC
109}
110
a16ac13f
DC
111DEFUN ("cygwin-convert-file-name-to-windows",
112 Fcygwin_convert_file_name_to_windows,
113 Scygwin_convert_file_name_to_windows,
f701ab72 114 1, 2, 0,
1ab0c851
GM
115 doc: /* Convert a Cygwin file name FILE to a Windows-style file name.
116If ABSOLUTE-P is non-nil, return an absolute file name.
117For the reverse operation, see `cygwin-convert-file-name-from-windows'. */)
118 (Lisp_Object file, Lisp_Object absolute_p)
f701ab72
DC
119{
120 return from_unicode (
1ab0c851 121 conv_filename_to_w32_unicode (file, EQ (absolute_p, Qnil) ? 0 : 1));
f701ab72
DC
122}
123
a16ac13f
DC
124DEFUN ("cygwin-convert-file-name-from-windows",
125 Fcygwin_convert_file_name_from_windows,
126 Scygwin_convert_file_name_from_windows,
f701ab72 127 1, 2, 0,
1ab0c851
GM
128 doc: /* Convert a Windows-style file name FILE to a Cygwin file name.
129If ABSOLUTE-P is non-nil, return an absolute file name.
130For the reverse operation, see `cygwin-convert-file-name-to-windows'. */)
131 (Lisp_Object file, Lisp_Object absolute_p)
f701ab72 132{
1ab0c851 133 return conv_filename_from_w32_unicode (to_unicode (file, &file),
fcf14875 134 EQ (absolute_p, Qnil) ? 0 : 1);
f701ab72
DC
135}
136
137void
138syms_of_cygw32 (void)
139{
fe6aa7a1 140#include "cygw32.x"
f701ab72 141}