FreeBSD/sys/kern/kern_linker.c
/*
 * Check if file actually exists either with or without extension listed in
 * the linker_ext_list. (probably should be generic for the rest of the
 * kernel)
 */
Check if file actually exists either with or without extension listed in
the linker_ext_list. (probably should be generic for the rest of the
kernel)
Check if file actually exists either with or without extension listed in the linker_ext_list . ( probably should be generic for the rest of the kernel )
static char *
linker_lookup_file(const char *path, int pathlen, const char *name,
    int namelen, struct vattr *vap)
{
	struct nameidata nd;
	struct thread *td = curthread;	
	char *result, **cpp, *sep;
	int error, len, extlen, reclen, flags;
	enum vtype type;
	extlen = 0;
	for (cpp = linker_ext_list; *cpp; cpp++) {
		len = strlen(*cpp);
		if (len > extlen)
			extlen = len;
	}
	extlen++;		
	sep = (path[pathlen - 1] != '/') ? "/" : "";
	reclen = pathlen + strlen(sep) + namelen + extlen + 1;
	result = malloc(reclen, M_LINKER, M_WAITOK);
	for (cpp = linker_ext_list; *cpp; cpp++) {
		snprintf(result, reclen, "%.*s%s%.*s%s", pathlen, path, sep,
		    namelen, name, *cpp);
		NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, result, td);
		flags = FREAD;
		error = vn_open(&nd, &flags, 0, NULL);
		if (error == 0) {
			NDFREE(&nd, NDF_ONLY_PNBUF);
			type = nd.ni_vp->v_type;
			if (vap)
				VOP_GETATTR(nd.ni_vp, vap, td->td_ucred);
			VOP_UNLOCK(nd.ni_vp, 0);
			vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
			if (type == VREG)
				return (result);
		}
	}
	free(result, M_LINKER);
	return (NULL);
}
static char * linker_lookup_file ( const char * path , int pathlen , const char * name , int namelen , struct vattr * vap ) { struct nameidata nd ; struct thread * td = curthread ; char * result , * * cpp , * sep ; int error , len , extlen , reclen , flags ; enum vtype type ; extlen = 0 ; for ( cpp = linker_ext_list ; * cpp ; cpp ++ ) { len = strlen ( * cpp ) ; if ( len > extlen ) extlen = len ; } extlen ++ ; sep = ( path [ pathlen - 1 ] != ' ' ) ? " " : " " ; reclen = pathlen + strlen ( sep ) + namelen + extlen + 1 ; result = malloc ( reclen , M_LINKER , M_WAITOK ) ; for ( cpp = linker_ext_list ; * cpp ; cpp ++ ) { snprintf ( result , reclen , " " , pathlen , path , sep , namelen , name , * cpp ) ; NDINIT ( & nd , LOOKUP , FOLLOW , UIO_SYSSPACE , result , td ) ; flags = FREAD ; error = vn_open ( & nd , & flags , 0 , NULL ) ; if ( error == 0 ) { NDFREE ( & nd , NDF_ONLY_PNBUF ) ; type = nd . ni_vp -> v_type ; if ( vap ) VOP_GETATTR ( nd . ni_vp , vap , td -> td_ucred ) ; VOP_UNLOCK ( nd . ni_vp , 0 ) ; vn_close ( nd . ni_vp , FREAD , td -> td_ucred , td ) ; if ( type == VREG ) return ( result ) ; } } free ( result , M_LINKER ) ; return ( NULL ) ; }
Check if file actually exists either with or without extension listed in
 the linker_ext_list.
Check if file actually exists either with or without extension listed in the linker_ext_list .
/* XXX */ /* trailing '\0' */ /*
		 * Attempt to open the file, and return the path if
		 * we succeed and it's a regular file.
		 */