pathname.c revision 9985ed6f5fe5d1a32e5a5be21ad888ef5123a6d1
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
* The Regents of the University of California
* All Rights Reserved
*
* University Acknowledgment- Portions of this document are derived from
* software developed by the University of California, Berkeley, and its
* contributors.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/pathname.h>
/*
* Pathname utilities.
*
* In translating file names we copy each argument file
* name into a pathname structure where we operate on it.
* Each pathname structure can hold "pn_bufsize" characters
* including a terminating null, and operations here support
* allocating and freeing pathname structures, fetching
* strings from user space, getting the next character from
* a pathname, combining two pathnames (used in symbolic
* link processing), and peeling off the first component
* of a pathname.
*/
/*
* Allocate contents of pathname structure. Structure is typically
* an automatic variable in calling routine for convenience.
*
* May sleep in the call to kmem_alloc() and so must not be called
* from interrupt level.
*/
void
{
pnp->pn_pathlen = 0;
}
/*
* Free pathname resources.
*/
void
{
/* pn_bufsize is usually MAXPATHLEN, but may not be */
}
/*
* Pull a path name from user or kernel space.
* Called from pn_get() after allocation of a MAXPATHLEN buffer.
* Also called directly with a TYPICALMAXPATHLEN-size buffer
* on the stack as a local optimization.
*/
int
{
int error;
if (seg == UIO_USERSPACE)
else
if (error)
return (error);
return (0);
}
/*
* Pull a path name from user or kernel space.
*/
int
{
int error;
void *buf;
return (error);
}
/*
* Set path name to argument string. Storage has already been allocated
* and pn_buf points to it.
*
* On error, all fields except pn_buf will be undefined.
*/
int
{
int error;
return (error);
}
/*
* Combine two argument path names by putting the second argument
* before the first in the first's buffer. This isn't very general;
* it is designed specifically for symbolic link processing.
* This function copies the symlink in-place in the pathname. This is to
* ensure that vnode path caching remains correct. At the point where this is
* called (from lookuppnvp), we have called pn_getcomponent(), found it is a
* symlink, and are now replacing the contents. The complen parameter indicates
* how much of the pathname to replace. If the symlink is an absolute path,
* then we overwrite the entire contents of the pathname.
*/
int
{
/*
* Full path, replace everything
*/
return (ENAMETOOLONG);
if (pnp->pn_pathlen != 0)
pnp->pn_pathlen);
} else {
/*
* Partial path, replace only last component
*/
return (ENAMETOOLONG);
if (pnp->pn_pathlen != 0)
}
return (0);
}
int
{
int error;
auio.uio_loffset = 0;
else
}
return (error);
}
/*
* Get next component from a path name and leave in
* buffer "component" which should have room for
* MAXNAMELEN bytes (including a null terminator character).
*/
int
{
if (pathlen >= MAXNAMELEN) {
*component++ = c;
return (ENAMETOOLONG);
} else {
*component++ = c;
}
*component = '\0';
return (0);
}
/*
* Skip over consecutive slashes in the path name.
*/
void
{
pnp->pn_pathlen--;
}
}
/*
* Sets pn_path to the last component in the pathname, updating
* pn_pathlen. If pathname is empty, or degenerate, leaves pn_path
* pointing at NULL char. The pathname is explicitly null-terminated
* so that any trailing slashes are effectively removed.
*/
void
{
char *endpath;
--path;
--path;
if (*path == '/')
path++;
*endpath = '\0';
}
/*
* Eliminate any trailing slashes in the pathname.
* Return non-zero iff there were any trailing slashes.
*/
int
{
end--;
return (0);
*end = '\0';
return (1);
}
/*
* Add a slash to the end of the pathname, if it will fit.
* Return ENAMETOOLONG if it won't.
*/
int
{
return (ENAMETOOLONG);
/*
* Move the component to the start of the buffer
* so we have room to add the trailing slash.
*/
}
return (0);
}