1 /* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
23 #include "stdio/_itoa.h"
24 #include <hurd/term.h>
27 /* Translate the error from dir_lookup into the error the user sees. */
29 lookup_error (error_t error
)
35 /* These indicate that the server does not understand dir_lookup
36 at all. If it were a directory, it would, by definition. */
44 __hurd_file_name_lookup (file_t crdir
, file_t cwdir
,
45 const char *file_name
, int flags
, mode_t mode
,
49 enum retry_type doretry
;
50 char retryname
[1024]; /* XXX string_t LOSES! */
53 startdir
= file_name
[0] == '/' ? crdir
: cwdir
;
55 while (file_name
[0] == '/')
58 if (err
= __dir_lookup (startdir
, file_name
, flags
, mode
,
59 &doretry
, retryname
, result
))
60 return lookup_error (err
);
62 return __hurd_file_name_lookup_retry (crdir
, doretry
, retryname
, flags
, mode
,
65 weak_alias (__hurd_file_name_lookup
, hurd_file_name_lookup
)
68 __hurd_file_name_lookup_retry (file_t crdir
,
69 enum retry_type doretry
,
71 int flags
, mode_t mode
,
88 __mach_port_deallocate (__mach_task_self (), startdir
);
90 return lookup_error (err
);
96 mach_port_t ref
= __mach_reply_port ();
97 err
= __io_reauthenticate (*result
,
98 ref
, MACH_MSG_TYPE_MAKE_SEND
);
101 (AUTH
, __auth_user_authenticate (port
, *result
,
103 MACH_MSG_TYPE_MAKE_SEND
,
105 __mach_port_destroy (__mach_task_self (), ref
);
107 __mach_port_deallocate (__mach_task_self (), *result
);
113 case FS_RETRY_NORMAL
:
115 if (nloops
++ >= SYMLOOP_MAX
)
119 /* An empty RETRYNAME indicates we have the final port. */
120 if (retryname
[0] == '\0')
122 /* We got a successful translation. Now apply any open-time
123 action flags we were passed. */
124 if (flags
& O_EXLOCK
)
126 if (!err
&& (flags
& O_SHLOCK
))
128 if (!err
&& (flags
& O_TRUNC
))
129 err
= __file_truncate (*result
, 0);
132 __mach_port_deallocate (__mach_task_self (), *result
);
138 file_name
= retryname
;
141 case FS_RETRY_MAGICAL
:
142 switch (retryname
[0])
147 if (*result
!= MACH_PORT_NULL
)
148 __mach_port_deallocate (__mach_task_self (), *result
);
149 file_name
= &retryname
[1];
153 if (retryname
[1] == 'd' && retryname
[2] == '/')
159 fd
= (int) strtol (retryname
, &end
, 10);
160 if (end
== NULL
|| errno
|| /* Malformed number. */
161 /* Check for excess text after the number. A slash
162 is valid; it ends the component. Anything else
163 does not name a numeric file descriptor. */
164 (*end
!= '/' && *end
!= '\0'))
169 *result
= __getdport (fd
);
170 if (*result
== MACH_PORT_NULL
)
172 /* If the name was a proper number, but the file
173 descriptor does not exist, we return EBADF instead
184 /* Do a normal retry on the remaining components. */
187 file_name
= end
+ 1; /* Skip the slash. */
196 if (retryname
[1] == 'a' && retryname
[2] == 'c' &&
197 retryname
[3] == 'h' && retryname
[4] == 't' &&
198 retryname
[5] == 'y' && retryname
[6] == 'p' &&
202 struct host_basic_info hostinfo
;
203 mach_msg_type_number_t hostinfocnt
= HOST_BASIC_INFO_COUNT
;
205 if (err
= __host_info (__mach_host_self (), HOST_BASIC_INFO
,
206 (natural_t
*) &hostinfo
,
209 if (hostinfocnt
!= HOST_BASIC_INFO_COUNT
)
211 p
= _itoa (hostinfo
.cpu_subtype
, &retryname
[8], 10, 0);
213 p
= _itoa (hostinfo
.cpu_type
, &retryname
[8], 10, 0);
215 abort (); /* XXX write this right if this ever happens */
217 strcpy (retryname
, p
);
226 if (retryname
[1] == 't' && retryname
[2] == 'y')
227 switch (retryname
[3])
229 error_t
opentty (file_t
*result
)
233 err
= __USEPORT (CTTYID
,
234 __termctty_open_terminal (port
,
239 mach_port_t ref
= __mach_reply_port ();
240 err
= __io_reauthenticate
243 MACH_MSG_TYPE_MAKE_SEND
);
246 (AUTH
, __auth_user_authenticate
249 ref
, MACH_MSG_TYPE_MAKE_SEND
,
251 __mach_port_deallocate (__mach_task_self (),
253 __mach_port_destroy (__mach_task_self (), ref
);
259 return opentty (result
);
261 if (err
= opentty (&startdir
))
264 strcpy (retryname
, &retryname
[4]);
283 err
= __dir_lookup (startdir
, file_name
, flags
, mode
,
284 &doretry
, retryname
, result
);
287 weak_alias (__hurd_file_name_lookup_retry
, hurd_file_name_lookup_retry
)
290 __hurd_file_name_split (file_t crdir
, file_t cwdir
,
291 const char *file_name
,
292 file_t
*dir
, char **name
)
294 const char *lastslash
;
297 lastslash
= strrchr (file_name
, '/');
298 if (lastslash
!= NULL
)
300 if (lastslash
== file_name
)
302 /* "/foobar" => crdir + "foobar". */
303 *name
= (char *) file_name
+ 1;
304 if (err
= __mach_port_mod_refs (__mach_task_self (),
305 crdir
, MACH_PORT_RIGHT_SEND
, +1))
312 /* "/dir1/dir2/.../file". */
313 char dirname
[lastslash
- file_name
+ 1];
314 memcpy (dirname
, file_name
, lastslash
- file_name
);
315 dirname
[lastslash
- file_name
] = '\0';
316 *name
= (char *) lastslash
+ 1;
317 return __hurd_file_name_lookup (crdir
, cwdir
, dirname
, 0, 0, dir
);
322 /* "foobar" => cwdir + "foobar". */
323 *name
= (char *) file_name
;
324 if (err
= __mach_port_mod_refs (__mach_task_self (),
325 cwdir
, MACH_PORT_RIGHT_SEND
, +1))
331 weak_alias (__hurd_file_name_split
, hurd_file_name_split
)
335 __file_name_lookup (const char *file_name
, int flags
, mode_t mode
)
338 file_t result
, crdir
, cwdir
;
339 struct hurd_userlink crdir_ulink
, cwdir_ulink
;
341 crdir
= _hurd_port_get (&_hurd_ports
[INIT_PORT_CRDIR
], &crdir_ulink
);
342 cwdir
= _hurd_port_get (&_hurd_ports
[INIT_PORT_CWDIR
], &cwdir_ulink
);
344 err
= __hurd_file_name_lookup (crdir
, cwdir
, file_name
, flags
, mode
,
347 _hurd_port_free (&_hurd_ports
[INIT_PORT_CRDIR
], &crdir_ulink
, crdir
);
348 _hurd_port_free (&_hurd_ports
[INIT_PORT_CWDIR
], &cwdir_ulink
, cwdir
);
351 return __hurd_fail (err
), MACH_PORT_NULL
;
355 weak_alias (__file_name_lookup
, file_name_lookup
)
359 __file_name_split (const char *file_name
, char **name
)
362 file_t dir
, crdir
, cwdir
;
363 struct hurd_userlink crdir_ulink
, cwdir_ulink
;
365 crdir
= _hurd_port_get (&_hurd_ports
[INIT_PORT_CRDIR
], &crdir_ulink
);
366 cwdir
= _hurd_port_get (&_hurd_ports
[INIT_PORT_CWDIR
], &cwdir_ulink
);
368 err
= __hurd_file_name_split (crdir
, cwdir
, file_name
, &dir
, name
);
370 _hurd_port_free (&_hurd_ports
[INIT_PORT_CRDIR
], &crdir_ulink
, crdir
);
371 _hurd_port_free (&_hurd_ports
[INIT_PORT_CWDIR
], &cwdir_ulink
, cwdir
);
376 return MACH_PORT_NULL
;
381 weak_alias (__file_name_split
, file_name_split
)