/src/mysql-server/mysys/my_getwd.cc
Line | Count | Source |
1 | | /* Copyright (c) 2000, 2025, Oracle and/or its affiliates. |
2 | | |
3 | | This program is free software; you can redistribute it and/or modify |
4 | | it under the terms of the GNU General Public License, version 2.0, |
5 | | as published by the Free Software Foundation. |
6 | | |
7 | | This program is designed to work with certain software (including |
8 | | but not limited to OpenSSL) that is licensed under separate terms, |
9 | | as designated in a particular file or component or in included license |
10 | | documentation. The authors of MySQL hereby grant you an additional |
11 | | permission to link the program and your derivative works with the |
12 | | separately licensed software that they have either included with |
13 | | the program or referenced in the documentation. |
14 | | |
15 | | Without limiting anything contained in the foregoing, this file, |
16 | | which is part of C Driver for MySQL (Connector/C), is also subject to the |
17 | | Universal FOSS Exception, version 1.0, a copy of which can be found at |
18 | | http://oss.oracle.com/licenses/universal-foss-exception. |
19 | | |
20 | | This program is distributed in the hope that it will be useful, |
21 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | | GNU General Public License, version 2.0, for more details. |
24 | | |
25 | | You should have received a copy of the GNU General Public License |
26 | | along with this program; if not, write to the Free Software |
27 | | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
28 | | |
29 | | /** |
30 | | @file mysys/my_getwd.cc |
31 | | */ |
32 | | |
33 | | /* my_setwd() and my_getwd() works with intern_filenames !! */ |
34 | | |
35 | | #include "my_config.h" |
36 | | |
37 | | #include <sys/types.h> |
38 | | #include <cerrno> |
39 | | #include <cstring> |
40 | | #ifdef HAVE_UNISTD_H |
41 | | #include <unistd.h> |
42 | | #endif |
43 | | |
44 | | #include "m_string.h" |
45 | | #include "my_dbug.h" |
46 | | #include "my_inttypes.h" |
47 | | #include "my_io.h" |
48 | | #include "my_sys.h" |
49 | | #include "my_thread_local.h" |
50 | | #include "mysys/my_static.h" |
51 | | #include "mysys_err.h" |
52 | | #include "nulls.h" |
53 | | #include "strmake.h" |
54 | | #if defined(_WIN32) |
55 | | #include <direct.h> |
56 | | #include <dos.h> |
57 | | |
58 | | #include "mysql/strings/m_ctype.h" |
59 | | #endif |
60 | | |
61 | | /* Gets current working directory in buff. |
62 | | |
63 | | SYNPOSIS |
64 | | my_getwd() |
65 | | buf Buffer to store result. Can be curr_dir[]. |
66 | | size Size of buffer |
67 | | MyFlags Flags |
68 | | |
69 | | NOTES |
70 | | Directory is always ended with FN_LIBCHAR |
71 | | |
72 | | RESULT |
73 | | 0 ok |
74 | | # error |
75 | | */ |
76 | | |
77 | 0 | int my_getwd(char *buf, size_t size, myf MyFlags) { |
78 | 0 | char *pos; |
79 | 0 | DBUG_TRACE; |
80 | 0 | DBUG_PRINT("my", ("buf: %p size: %u MyFlags %d", buf, (uint)size, MyFlags)); |
81 | |
|
82 | 0 | if (size < 1) return -1; |
83 | | |
84 | 0 | if (curr_dir[0]) /* Current pos is saved here */ |
85 | 0 | (void)strmake(buf, &curr_dir[0], size - 1); |
86 | 0 | else { |
87 | 0 | if (size < 2) return -1; |
88 | 0 | if (!getcwd(buf, (uint)(size - 2)) && MyFlags & MY_WME) { |
89 | 0 | set_my_errno(errno); |
90 | 0 | MyOsError(my_errno(), EE_GETWD, MYF(0)); |
91 | 0 | return -1; |
92 | 0 | } |
93 | 0 | if (*((pos = strend(buf)) - 1) != FN_LIBCHAR) /* End with FN_LIBCHAR */ |
94 | 0 | { |
95 | 0 | pos[0] = FN_LIBCHAR; |
96 | 0 | pos[1] = 0; |
97 | 0 | } |
98 | 0 | (void)strmake(&curr_dir[0], buf, (size_t)(FN_REFLEN - 1)); |
99 | 0 | } |
100 | 0 | return 0; |
101 | 0 | } /* my_getwd */ |
102 | | |
103 | | /* Set new working directory */ |
104 | | |
105 | 0 | int my_setwd(const char *dir, myf MyFlags) { |
106 | 0 | int res; |
107 | 0 | size_t length; |
108 | 0 | char *pos; |
109 | 0 | DBUG_TRACE; |
110 | 0 | DBUG_PRINT("my", ("dir: '%s' MyFlags %d", dir, MyFlags)); |
111 | |
|
112 | 0 | const char *start = dir; |
113 | 0 | if (!dir[0] || (dir[0] == FN_LIBCHAR && dir[1] == 0)) dir = FN_ROOTDIR; |
114 | 0 | if ((res = chdir(dir)) != 0) { |
115 | 0 | set_my_errno(errno); |
116 | 0 | if (MyFlags & MY_WME) { |
117 | 0 | MyOsError(my_errno(), EE_SETWD, MYF(0), start); |
118 | 0 | } |
119 | 0 | } else { |
120 | 0 | if (test_if_hard_path(start)) { /* Hard pathname */ |
121 | 0 | pos = strmake(&curr_dir[0], start, (size_t)FN_REFLEN - 1); |
122 | 0 | if (pos[-1] != FN_LIBCHAR) { |
123 | 0 | length = (uint)(pos - (char *)curr_dir); |
124 | 0 | curr_dir[length] = FN_LIBCHAR; /* must end with '/' */ |
125 | 0 | curr_dir[length + 1] = '\0'; |
126 | 0 | } |
127 | 0 | } else |
128 | 0 | curr_dir[0] = '\0'; /* Don't save name */ |
129 | 0 | } |
130 | 0 | return res; |
131 | 0 | } |
132 | | |
133 | | /* Test if hard pathname */ |
134 | | /* Returns 1 if dirname is a hard path */ |
135 | | |
136 | 1 | int test_if_hard_path(const char *dir_name) { |
137 | 1 | if (dir_name[0] == FN_HOMELIB && dir_name[1] == FN_LIBCHAR) |
138 | 0 | return (home_dir != NullS && test_if_hard_path(home_dir)); |
139 | 1 | if (dir_name[0] == FN_LIBCHAR) return (true); |
140 | | #ifdef FN_DEVCHAR |
141 | | return (strchr(dir_name, FN_DEVCHAR) != nullptr); |
142 | | #else |
143 | 0 | return false; |
144 | 1 | #endif |
145 | 1 | } /* test_if_hard_path */ |
146 | | |
147 | | /* |
148 | | Test if a name contains an (absolute or relative) path. |
149 | | |
150 | | SYNOPSIS |
151 | | has_path() |
152 | | name The name to test. |
153 | | |
154 | | RETURN |
155 | | true name contains a path. |
156 | | false name does not contain a path. |
157 | | */ |
158 | | |
159 | 0 | bool has_path(const char *name) { |
160 | 0 | return (strchr(name, FN_LIBCHAR) != nullptr) |
161 | | #if FN_LIBCHAR != '/' |
162 | | || (strchr(name, '/') != nullptr) |
163 | | #endif |
164 | | #ifdef FN_DEVCHAR |
165 | | || (strchr(name, FN_DEVCHAR) != nullptr) |
166 | | #endif |
167 | 0 | ; |
168 | 0 | } |