OSDN Git Service

Replace valid memory checks with new myfault class "exception handling", almost
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / path.h
1 /* path.h: path data structures
2
3    Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "devices.h"
12
13 #include <sys/ioctl.h>
14 #include <fcntl.h>
15 #include <ntdef.h>
16
17 enum executable_states
18 {
19   is_executable,
20   dont_care_if_executable,
21   not_executable = dont_care_if_executable,
22   dont_know_if_executable
23 };
24
25 struct suffix_info
26 {
27   const char *name;
28   int addon;
29   suffix_info (const char *s, int addit = 0): name (s), addon (addit) {}
30 };
31
32 enum pathconv_arg
33 {
34   PC_SYM_FOLLOW         = 0x0001,
35   PC_SYM_NOFOLLOW       = 0x0002,
36   PC_SYM_IGNORE         = 0x0004,
37   PC_SYM_CONTENTS       = 0x0008,
38   PC_NOFULL             = 0x0010,
39   PC_NULLEMPTY          = 0x0020,
40   PC_CHECK_EA           = 0x0040,
41   PC_POSIX              = 0x0080,
42   PC_NO_ACCESS_CHECK    = 0x00800000,
43   PC_WRITABLE           = 0x00400000
44 };
45
46 enum case_checking
47 {
48   PCHECK_RELAXED        = 0,
49   PCHECK_ADJUST         = 1,
50   PCHECK_STRICT         = 2
51 };
52
53 #define PC_NONULLEMPTY -1
54
55 #include "sys/mount.h"
56
57 enum path_types
58 {
59   PATH_NOTHING          = 0,
60   PATH_SYMLINK          = MOUNT_SYMLINK,
61   PATH_BINARY           = MOUNT_BINARY,
62   PATH_EXEC             = MOUNT_EXEC,
63   PATH_NOTEXEC          = MOUNT_NOTEXEC,
64   PATH_CYGWIN_EXEC      = MOUNT_CYGWIN_EXEC,
65   PATH_ENC              = MOUNT_ENC,
66   PATH_RO               = MOUNT_RO,
67   PATH_ALL_EXEC         = (PATH_CYGWIN_EXEC | PATH_EXEC),
68   PATH_NO_ACCESS_CHECK  = PC_NO_ACCESS_CHECK,
69   PATH_LNK              = 0x01000000,
70   PATH_TEXT             = 0x02000000,
71   PATH_HAS_SYMLINKS     = 0x10000000,
72   PATH_SOCKET           = 0x40000000
73 };
74
75 class symlink_info;
76 struct fs_info
77 {
78  private:
79   __ino64_t name_hash;
80   struct status_flags
81   {
82     DWORD flags;  /* Volume flags */
83     DWORD serial; /* Volume serial number */
84     unsigned is_remote_drive : 1;
85     unsigned has_buggy_open  : 1;
86     unsigned has_ea          : 1;
87     unsigned has_acls        : 1;
88     unsigned is_fat          : 1;
89     unsigned drive_type      : 3;
90   } status;
91  public:
92   void clear ()
93   {
94     name_hash = 0;
95     flags () = serial () = 0;
96     is_remote_drive (false);
97     has_buggy_open (false);
98     has_ea (false);
99     has_acls (false);
100     is_fat (false);
101     drive_type (false);
102   }
103   inline DWORD& flags () {return status.flags;};
104   inline DWORD& serial () {return status.serial;};
105
106   IMPLEMENT_STATUS_FLAG (bool, is_remote_drive)
107   IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
108   IMPLEMENT_STATUS_FLAG (bool, is_fat)
109   IMPLEMENT_STATUS_FLAG (bool, has_ea)
110   IMPLEMENT_STATUS_FLAG (bool, has_acls)
111   IMPLEMENT_STATUS_FLAG (DWORD, drive_type)
112
113   bool update (const char *);
114 };
115
116 class path_conv
117 {
118   DWORD fileattr;
119   fs_info fs;
120   void add_ext_from_sym (symlink_info&);
121  public:
122
123   unsigned path_flags;
124   char *known_suffix;
125   int error;
126   device dev;
127   bool case_clash;
128
129   bool isremote () {return fs.is_remote_drive ();}
130   int has_acls () const {return fs.has_acls (); }
131   int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
132   int hasgood_inode () const {return has_acls ();}  // Not strictly correct
133   int has_buggy_open () const {return fs.has_buggy_open ();}
134   bool isencoded () {return path_flags & PATH_ENC;}
135   int binmode () const
136   {
137     if (path_flags & PATH_BINARY)
138       return O_BINARY;
139     if (path_flags & PATH_TEXT)
140       return O_TEXT;
141     return 0;
142   }
143   int issymlink () const {return path_flags & PATH_SYMLINK;}
144   int is_lnk_symlink () const {return path_flags & PATH_LNK;}
145   int isdevice () const {return dev.devn && dev.devn != FH_FS && dev.devn != FH_FIFO;}
146   int isfifo () const {return dev == FH_FIFO;}
147   int isspecial () const {return dev.devn && dev.devn != FH_FS;}
148   int is_auto_device () const {return isdevice () && !is_fs_special ();}
149   int is_fs_device () const {return isdevice () && is_fs_special ();}
150   int is_fs_special () const {return isspecial () && dev.isfs ();}
151   int is_lnk_special () const {return is_fs_device () || isfifo () || is_lnk_symlink ();}
152   int issocket () const {return dev.devn == FH_UNIX;}
153   int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
154   bool isro () const {return !!(path_flags & PATH_RO);}
155   bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
156   bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
157   int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
158   executable_states exec_state ()
159   {
160     extern int _check_for_executable;
161     if (path_flags & PATH_ALL_EXEC)
162       return is_executable;
163     if (path_flags & PATH_NOTEXEC)
164       return not_executable;
165     if (!_check_for_executable)
166       return dont_care_if_executable;
167     return dont_know_if_executable;
168   }
169
170   void set_binary () {path_flags |= PATH_BINARY;}
171   void set_symlink (DWORD n) {path_flags |= PATH_SYMLINK; symlink_length = n;}
172   void set_has_symlinks () {path_flags |= PATH_HAS_SYMLINKS;}
173   void set_exec (int x = 1) {path_flags |= x ? PATH_EXEC : PATH_NOTEXEC;}
174
175   void check (const char *src, unsigned opt = PC_SYM_FOLLOW,
176               const suffix_info *suffixes = NULL)  __attribute__ ((regparm(3)));
177
178   path_conv (const device& in_dev): fileattr (INVALID_FILE_ATTRIBUTES),
179      path_flags (0), known_suffix (NULL), error (0), dev (in_dev)
180     {
181       strcpy (path, in_dev.native);
182     }
183
184   path_conv (int, const char *src, unsigned opt = PC_SYM_FOLLOW,
185              const suffix_info *suffixes = NULL)
186   {
187     check (src, opt, suffixes);
188   }
189
190   path_conv (const char *src, unsigned opt = PC_SYM_FOLLOW,
191              const suffix_info *suffixes = NULL)
192   {
193     check (src, opt | PC_NULLEMPTY, suffixes);
194   }
195
196   path_conv (): fileattr (INVALID_FILE_ATTRIBUTES), path_flags (0),
197                 known_suffix (NULL), error (0), normalized_path (NULL)
198     {path[0] = '\0';}
199
200   ~path_conv ();
201   void set_name (const char *win32, const char *posix);
202   inline char *get_win32 () { return path; }
203   PUNICODE_STRING get_nt_native_path (UNICODE_STRING &upath);
204   operator char *() {return path;}
205   operator const char *() {return path;}
206   operator DWORD &() {return fileattr;}
207   operator int () {return fileattr; }
208   char operator [](int i) const {return path[i];}
209   DWORD get_devn () {return dev.devn;}
210   short get_unitn () {return dev.minor;}
211   DWORD file_attributes () {return fileattr;}
212   void file_attributes (DWORD new_attr) {fileattr = new_attr;}
213   DWORD drive_type () {return fs.drive_type ();}
214   DWORD fs_flags () {return fs.flags ();}
215   bool fs_has_ea () {return fs.has_ea ();}
216   bool fs_is_fat () {return fs.is_fat ();}
217   void set_path (const char *p) {strcpy (path, p);}
218   DWORD volser () { return fs.serial (); }
219   void fillin (HANDLE h);
220   inline size_t size ()
221   {
222     return (sizeof (*this) - sizeof (path)) + strlen (path) + 1 + normalized_path_size;
223   }
224
225   unsigned __stdcall ndisk_links (DWORD);
226   char *normalized_path;
227   size_t normalized_path_size;
228   void set_normalized_path (const char *, bool) __attribute__ ((regparm (3)));
229   DWORD get_symlink_length () { return symlink_length; };
230  private:
231   DWORD symlink_length;
232   char path[CYG_MAX_PATH];
233 };
234
235 /* Symlink marker */
236 #define SYMLINK_COOKIE "!<symlink>"
237
238 #define SYMLINK_EA_NAME ".CYGSYMLINK"
239
240 /* Socket marker */
241 #define SOCKET_COOKIE  "!<socket >"
242
243 /* The sizeof header written to a shortcut by Cygwin or U/WIN. */
244 #define SHORTCUT_HDR_SIZE       76
245
246 /* Maximum depth of symlinks (after which ELOOP is issued).  */
247 #define MAX_LINK_DEPTH 10
248 int __stdcall slash_unc_prefix_p (const char *path) __attribute__ ((regparm(1)));
249
250 enum fe_types
251 {
252   FE_NADA = 0,          /* Nothing special */
253   FE_NNF = 1,           /* Return NULL if not found */
254   FE_NATIVE = 2,        /* Return native path in path_conv struct */
255   FE_CWD = 4            /* Search CWD for program */
256 };
257 const char * __stdcall find_exec (const char *name, path_conv& buf,
258                                   const char *winenv = "PATH=",
259                                   unsigned opt = FE_NADA,
260                                   const char **known_suffix = NULL)
261   __attribute__ ((regparm(3)));
262
263 /* Common macros for checking for invalid path names */
264 #define isdrive(s) (isalpha (*(s)) && (s)[1] == ':')
265
266 static inline bool
267 has_exec_chars (const char *buf, int len)
268 {
269   return len >= 2 &&
270          ((buf[0] == '#' && buf[1] == '!') ||
271           (buf[0] == ':' && buf[1] == '\n') ||
272           (buf[0] == 'M' && buf[1] == 'Z'));
273 }
274
275 int pathmatch (const char *path1, const char *path2) __attribute__ ((regparm (2)));
276 int pathnmatch (const char *path1, const char *path2, int len) __attribute__ ((regparm (2)));
277
278 bool fnunmunge (char *, const char *) __attribute__ ((regparm (2)));
279
280 int path_prefix_p (const char *path1, const char *path2, int len1) __attribute__ ((regparm (3)));
281
282 bool is_floppy (const char *);
283
284 /* FIXME: Move to own include file eventually */
285
286 #define MAX_ETC_FILES 2
287 class etc
288 {
289   friend class dtable;
290   static int curr_ix;
291   static bool change_possible[MAX_ETC_FILES + 1];
292   static const char *fn[MAX_ETC_FILES + 1];
293   static FILETIME last_modified[MAX_ETC_FILES + 1];
294   static bool dir_changed (int);
295   static int init (int, const char *);
296   static bool file_changed (int);
297   static bool test_file_change (int);
298   friend class pwdgrp;
299 };