Mercurial > hg > octave-kai > gnulib-hg
annotate lib/link.c @ 11583:dc80f2cc1327
Second attempt to work around an AIX 5.3, 6.1 compiler bug with include_next.
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Thu, 21 May 2009 16:48:12 +0200 |
parents | 2921cdaa1164 |
children | 7e5f9267c62e |
rev | line source |
---|---|
11041 | 1 /* Emulate link on platforms that lack it, namely native Windows platforms. |
2 | |
3 Copyright (C) 2009 Free Software Foundation, Inc. | |
4 | |
5 This program is free software; you can redistribute it and/or modify | |
6 it under the terms of the GNU General Public License as published by | |
7 the Free Software Foundation; either version 2, or (at your option) | |
8 any later version. | |
9 | |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 GNU General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU General Public License | |
16 along with this program; if not, write to the Free Software Foundation, | |
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | |
18 | |
19 #include <config.h> | |
20 | |
21 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | |
22 | |
23 #define WIN32_LEAN_AND_MEAN | |
24 #include <unistd.h> | |
25 #include <windows.h> | |
26 | |
27 #include <errno.h> | |
28 | |
11063
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
29 /* CreateHardLink was introduced only in Windows 2000. */ |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
30 typedef BOOL (WINAPI * CreateHardLinkFuncType) (LPCTSTR lpFileName, |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
31 LPCTSTR lpExistingFileName, |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
32 LPSECURITY_ATTRIBUTES lpSecurityAttributes); |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
33 static CreateHardLinkFuncType CreateHardLinkFunc = NULL; |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
34 static BOOL initialized = FALSE; |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
35 |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
36 static void |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
37 initialize (void) |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
38 { |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
39 HMODULE kernel32 = LoadLibrary ("kernel32.dll"); |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
40 if (kernel32 != NULL) |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
41 { |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
42 CreateHardLinkFunc = |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
43 (CreateHardLinkFuncType) GetProcAddress (kernel32, "CreateHardLinkA"); |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
44 } |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
45 initialized = TRUE; |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
46 } |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
47 |
11041 | 48 int |
49 link (const char *path1, const char *path2) | |
50 { | |
11063
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
51 if (!initialized) |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
52 initialize (); |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
53 if (CreateHardLinkFunc == NULL) |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
54 { |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
55 /* System does not support hard links. */ |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
56 errno = EPERM; |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
57 return -1; |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
58 } |
2921cdaa1164
Make the 'link' module link on Windows NT 4.
Bruno Haible <bruno@clisp.org>
parents:
11041
diff
changeset
|
59 if (CreateHardLinkFunc (path2, path1, NULL) == 0) |
11041 | 60 { |
61 /* It is not documented which errors CreateHardLink() can produce. | |
62 * The following conversions are based on tests on a Windows XP SP2 | |
63 * system. */ | |
64 DWORD err = GetLastError (); | |
65 switch (err) | |
66 { | |
67 case ERROR_ACCESS_DENIED: | |
68 errno = EACCES; | |
69 break; | |
70 | |
71 case ERROR_INVALID_FUNCTION: /* fs does not support hard links */ | |
72 errno = EPERM; | |
73 break; | |
74 | |
75 case ERROR_NOT_SAME_DEVICE: | |
76 errno = EXDEV; | |
77 break; | |
78 | |
79 case ERROR_PATH_NOT_FOUND: | |
80 case ERROR_FILE_NOT_FOUND: | |
81 errno = ENOENT; | |
82 break; | |
83 | |
84 case ERROR_INVALID_PARAMETER: | |
85 errno = ENAMETOOLONG; | |
86 break; | |
87 | |
88 case ERROR_TOO_MANY_LINKS: | |
89 errno = EMLINK; | |
90 break; | |
91 | |
92 case ERROR_ALREADY_EXISTS: | |
93 errno = EEXIST; | |
94 break; | |
95 | |
96 default: | |
97 errno = EIO; | |
98 } | |
99 return -1; | |
100 } | |
101 | |
102 return 0; | |
103 } | |
104 | |
105 #else /* !Windows */ | |
106 | |
107 #error "This platform lacks a link function, and Gnulib doesn't provide a replacement. This is a bug in Gnulib." | |
108 | |
109 #endif /* !Windows */ |