Back to index

glibc  2.9
Functions
hurdlookup.c File Reference
#include <hurd.h>
#include <hurd/lookup.h>
#include <string.h>
#include <fcntl.h>

Go to the source code of this file.

Functions

static error_t lookup_error (error_t error)
error_t __hurd_file_name_lookup (error_t(*use_init_port)(int which, error_t(*operate)(file_t)), file_t(*get_dtable_port)(int fd), error_t(*lookup)(file_t dir, char *name, int flags, mode_t mode, retry_type *do_retry, string_t retry_name, mach_port_t *result), const char *file_name, int flags, mode_t mode, file_t *result)
 weak_alias (__hurd_file_name_lookup, hurd_file_name_lookup)
 weak_alias (__hurd_file_name_split, hurd_file_name_split)
 weak_alias (__hurd_directory_name_split, hurd_directory_name_split)
 weak_alias (__file_name_lookup, file_name_lookup)
 weak_alias (__file_name_split, file_name_split)
 weak_alias (__directory_name_split, directory_name_split)

Function Documentation

error_t __hurd_file_name_lookup ( error_t(*)(int which, error_t(*operate)(file_t))  use_init_port,
file_t(*)(int fd get_dtable_port,
error_t(*)(file_t dir, char *name, int flags, mode_t mode, retry_type *do_retry, string_t retry_name, mach_port_t *result lookup,
const char *  file_name,
int  flags,
mode_t  mode,
file_t *  result 
)

Definition at line 43 of file hurdlookup.c.

{
  error_t err;
  enum retry_type doretry;
  char retryname[1024];            /* XXX string_t LOSES! */
  int startport;

  error_t lookup_op (mach_port_t startdir)
    {
      return lookup_error ((*lookup) (startdir, file_name, flags, mode,
                                  &doretry, retryname, result));
    }

  if (! lookup)
    lookup = __dir_lookup;

  if (file_name[0] == '\0')
    return ENOENT;

  startport = (file_name[0] == '/') ? INIT_PORT_CRDIR : INIT_PORT_CWDIR;
  while (file_name[0] == '/')
    file_name++;

  if (flags & O_NOFOLLOW)   /* See lookup-retry.c about O_NOFOLLOW.  */
    flags |= O_NOTRANS;

  if (flags & O_DIRECTORY)
    {
      /* The caller wants to require that the file we look up is a directory.
        We can do this without an extra RPC by appending a trailing slash
        to the file name we look up.  */
      size_t len = strlen (file_name);
      if (len == 0)
       file_name = "/";
      else if (file_name[len - 1] != '/')
       {
         char *n = alloca (len + 2);
         memcpy (n, file_name, len);
         n[len] = '/';
         n[len + 1] = '\0';
         file_name = n;
       }
    }

  err = (*use_init_port) (startport, &lookup_op);
  if (! err)
    err = __hurd_file_name_lookup_retry (use_init_port, get_dtable_port,
                                    lookup, doretry, retryname,
                                    flags, mode, result);

  return err;
}

Here is the call graph for this function:

static error_t lookup_error ( error_t  error) [inline, static]

Definition at line 28 of file hurdlookup.c.

{
  switch (error)
    {
    case EOPNOTSUPP:
    case MIG_BAD_ID:
      /* These indicate that the server does not understand dir_lookup
        at all.  If it were a directory, it would, by definition.  */
      return ENOTDIR;
    default:
      return error;
    }
}

Here is the caller graph for this function:

Definition at line 103 of file hurdlookup.c.

{
  error_t addref (file_t crdir)
    {
      *dir = crdir;
      return __mach_port_mod_refs (__mach_task_self (),
                               crdir, MACH_PORT_RIGHT_SEND, +1);
    }

  const char *lastslash = strrchr (file_name, '/');

  if (lastslash != NULL)
    {
      if (lastslash == file_name)
       {
         /* "/foobar" => crdir + "foobar".  */
         *name = (char *) file_name + 1;
         return (*use_init_port) (INIT_PORT_CRDIR, &addref);
       }
      else
       {
         /* "/dir1/dir2/.../file".  */
         char dirname[lastslash - file_name + 1];
         memcpy (dirname, file_name, lastslash - file_name);
         dirname[lastslash - file_name] = '\0';
         *name = (char *) lastslash + 1;
         return
           __hurd_file_name_lookup (use_init_port, get_dtable_port, lookup,
                                 dirname, 0, 0, dir);
       }
    }
  else if (file_name[0] == '\0')
    return ENOENT;
  else
    {
      /* "foobar" => cwdir + "foobar".  */
      *name = (char *) file_name;
      return (*use_init_port) (INIT_PORT_CWDIR, &addref);
    }
}

Here is the call graph for this function:

Definition at line 154 of file hurdlookup.c.

{
  error_t addref (file_t crdir)
    {
      *dir = crdir;
      return __mach_port_mod_refs (__mach_task_self (),
                               crdir, MACH_PORT_RIGHT_SEND, +1);
    }

  const char *lastslash = strrchr (file_name, '/');

  if (lastslash != NULL && lastslash[1] == '\0')
    {
      /* Trailing slash doesn't count.  Look back further.  */

      /* Back up over all trailing slashes.  */
      while (lastslash > file_name && *lastslash == '/')
       --lastslash;

      /* Find the last one earlier in the string, before the trailing ones.  */
      lastslash = __memrchr (file_name, '/', lastslash - file_name);
    }

  if (lastslash != NULL)
    {
      if (lastslash == file_name)
       {
         /* "/foobar" => crdir + "foobar".  */
         *name = (char *) file_name + 1;
         return (*use_init_port) (INIT_PORT_CRDIR, &addref);
       }
      else
       {
         /* "/dir1/dir2/.../file".  */
         char dirname[lastslash - file_name + 1];
         memcpy (dirname, file_name, lastslash - file_name);
         dirname[lastslash - file_name] = '\0';
         *name = (char *) lastslash + 1;
         return
           __hurd_file_name_lookup (use_init_port, get_dtable_port, lookup,
                                 dirname, 0, 0, dir);
       }
    }
  else if (file_name[0] == '\0')
    return ENOENT;
  else
    {
      /* "foobar" => cwdir + "foobar".  */
      *name = (char *) file_name;
      return (*use_init_port) (INIT_PORT_CWDIR, &addref);
    }
}

Here is the call graph for this function:

Definition at line 219 of file hurdlookup.c.

{
  error_t err;
  file_t result;

  err = __hurd_file_name_lookup (&_hurd_ports_use, &__getdport, 0,
                             file_name, flags, mode & ~_hurd_umask,
                             &result);

  return err ? (__hurd_fail (err), MACH_PORT_NULL) : result;
}

Here is the call graph for this function:

Definition at line 234 of file hurdlookup.c.

{
  error_t err;
  file_t result;

  err = __hurd_file_name_split (&_hurd_ports_use, &__getdport, 0,
                            file_name, &result, name);

  return err ? (__hurd_fail (err), MACH_PORT_NULL) : result;
}

Here is the call graph for this function:

Definition at line 248 of file hurdlookup.c.

{
  error_t err;
  file_t result;

  err = __hurd_directory_name_split (&_hurd_ports_use, &__getdport, 0,
                                 directory_name, &result, name);

  return err ? (__hurd_fail (err), MACH_PORT_NULL) : result;
}

Here is the call graph for this function:

Definition at line 261 of file hurdlookup.c.

{
  error_t err;
  file_t result;

  error_t use_init_port (int which, error_t (*operate) (mach_port_t))
    {
      return (which == INIT_PORT_CWDIR ? (*operate) (startdir) :
             _hurd_ports_use (which, operate));
    }

  err = __hurd_file_name_lookup (&use_init_port, &__getdport, 0,
                             file_name, flags, mode & ~_hurd_umask,
                             &result);

  return err ? (__hurd_fail (err), MACH_PORT_NULL) : result;
}

Here is the call graph for this function: