(linenum→info "unix/slp.c:2238")

glibc/2.7/hurd/path-lookup.c

    1: /* Filename lookup using a search path
    2:    Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4:    Written by Miles Bader <miles@gnu.ai.mit.edu>
    5: 
    6:    The GNU C Library is free software; you can redistribute it and/or
    7:    modify it under the terms of the GNU Lesser General Public
    8:    License as published by the Free Software Foundation; either
    9:    version 2.1 of the License, or (at your option) any later version.
   10: 
   11:    The GNU C Library is distributed in the hope that it will be useful,
   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:    Lesser General Public License for more details.
   15: 
   16:    You should have received a copy of the GNU Lesser General Public
   17:    License along with the GNU C Library; if not, write to the Free
   18:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   19:    02111-1307 USA.  */
   20: 
   21: #include <string.h>
   22: #include <hurd.h>
   23: #include <hurd/lookup.h>
   24: 
   25: /* If FILE_NAME contains a '/', or PATH is NULL, call FUN with FILE_NAME, and
   26:    return the result (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to
   27:    NULL).  Otherwise, call FUN repeatedly with FILE_NAME prefixed with each
   28:    successive `:' separated element of PATH, returning whenever FUN returns
   29:    0 (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to the resulting
   30:    prefixed path).  If FUN never returns 0, return the first non-ENOENT
   31:    return value, or ENOENT if there is none.  */
   32: error_t
   33: file_name_path_scan (const char *file_name, const char *path,
   34:                      error_t (*fun)(const char *name),
   35:                      char **prefixed_name)
   36: {
   37:   if (path == NULL || index (file_name, '/'))
   38:     {
   39:       if (prefixed_name)
   40:         *prefixed_name = 0;
   41:       return (*fun)(file_name);
   42:     }
   43:   else
   44:     {
   45:       error_t real_err = 0;
   46:       size_t file_name_len = strlen (file_name);
   47: 
   48:       for (;;)
   49:         {
   50:           error_t err;
   51:           const char *next = index (path, ':') ?: path + strlen (path);
   52:           size_t pfx_len = next - path;
   53:           char pfxed_name[pfx_len + 2 + file_name_len + 1];
   54: 
   55:           if (pfx_len == 0)
   56:             pfxed_name[pfx_len++] = '.';
   57:           else
   58:             memcpy (pfxed_name, path, pfx_len);
   59:           if (pfxed_name[pfx_len - 1] != '/')
   60:             pfxed_name[pfx_len++] = '/';
   61:           memcpy (pfxed_name + pfx_len, file_name, file_name_len + 1);
   62: 
   63:           err = (*fun)(pfxed_name);
   64:           if (err == 0)
   65:             {
   66:               if (prefixed_name)
   67:                 *prefixed_name = strdup (pfxed_name);
   68:               return 0;
   69:             }
   70:           if (!real_err && err != ENOENT)
   71:             real_err = err;
   72: 
   73:           if (*next == '\0')
   74:             return real_err ?: ENOENT;
   75:           else
   76:             path = next + 1;
   77:         }
   78:     }
   79: }
   80: 
   81: /* Lookup FILE_NAME and return the node opened with FLAGS & MODE in result
   82:    (see hurd_file_name_lookup for details), but a simple filename (without
   83:    any directory prefixes) will be consecutively prefixed with the pathnames
   84:    in the `:' separated list PATH until one succeeds in a successful lookup.
   85:    If none succeed, then the first error that wasn't ENOENT is returned, or
   86:    ENOENT if no other errors were returned.  If PREFIXED_NAME is non-NULL,
   87:    then if RESULT is looked up directly, *PREFIXED_NAME is set to NULL, and
   88:    if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to
   89:    malloced storage containing the prefixed name.  */
   90: error_t
   91: hurd_file_name_path_lookup (error_t (*use_init_port)
   92:                               (int which, error_t (*operate) (mach_port_t)),
   93:                             file_t (*get_dtable_port) (int fd),
   94:                             error_t (*lookup)
   95:                               (file_t dir, char *name, int flags, mode_t mode,
   96:                                retry_type *do_retry, string_t retry_name,
   97:                                mach_port_t *result),
   98:                             const char *file_name, const char *path,
   99:                             int flags, mode_t mode,
  100:                             file_t *result, char **prefixed_name)
  101: {
  102:   error_t scan_lookup (const char *name)
  103:     {
  104:       return
  105:         __hurd_file_name_lookup (use_init_port, get_dtable_port, lookup,
  106:                                  name, flags, mode, result);
  107:     }
  108:   return file_name_path_scan (file_name, path, scan_lookup, prefixed_name);
  109: }
  110: 
  111: file_t
  112: file_name_path_lookup (const char *file_name, const char *path,
  113:                        int flags, mode_t mode, char **prefixed_name)
  114: {
  115:   error_t err;
  116:   file_t result;
  117: 
  118:   err = hurd_file_name_path_lookup (&_hurd_ports_use, &__getdport, 0,
  119:                                     file_name, path, flags, mode,
  120:                                     &result, prefixed_name);
  121: 
  122:   return err ? (__hurd_fail (err), MACH_PORT_NULL) : result;
  123: }
Syntax (Markdown)