* 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) */
| 1774 | * kernel) |
| 1775 | */ |
| 1776 | static char * |
| 1777 | linker_lookup_file(const char *path, int pathlen, const char *name, |
| 1778 | int namelen, struct vattr *vap) |
| 1779 | { |
| 1780 | struct nameidata nd; |
| 1781 | struct thread *td = curthread; /* XXX */ |
| 1782 | const char * const *cpp, *sep; |
| 1783 | char *result; |
| 1784 | int error, len, extlen, reclen, flags; |
| 1785 | enum vtype type; |
| 1786 | |
| 1787 | extlen = 0; |
| 1788 | for (cpp = linker_ext_list; *cpp; cpp++) { |
| 1789 | len = strlen(*cpp); |
| 1790 | if (len > extlen) |
| 1791 | extlen = len; |
| 1792 | } |
| 1793 | extlen++; /* trailing '\0' */ |
| 1794 | sep = (path[pathlen - 1] != '/') ? "/" : ""; |
| 1795 | |
| 1796 | reclen = pathlen + strlen(sep) + namelen + extlen + 1; |
| 1797 | result = malloc(reclen, M_LINKER, M_WAITOK); |
| 1798 | for (cpp = linker_ext_list; *cpp; cpp++) { |
| 1799 | snprintf(result, reclen, "%.*s%s%.*s%s", pathlen, path, sep, |
| 1800 | namelen, name, *cpp); |
| 1801 | /* |
| 1802 | * Attempt to open the file, and return the path if |
| 1803 | * we succeed and it's a regular file. |
| 1804 | */ |
| 1805 | NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, result, td); |
| 1806 | flags = FREAD; |
| 1807 | error = vn_open(&nd, &flags, 0, NULL); |
| 1808 | if (error == 0) { |
| 1809 | NDFREE(&nd, NDF_ONLY_PNBUF); |
| 1810 | type = nd.ni_vp->v_type; |
| 1811 | if (vap) |
| 1812 | VOP_GETATTR(nd.ni_vp, vap, td->td_ucred); |
| 1813 | VOP_UNLOCK(nd.ni_vp); |
| 1814 | vn_close(nd.ni_vp, FREAD, td->td_ucred, td); |
| 1815 | if (type == VREG) |
| 1816 | return (result); |
| 1817 | } |
| 1818 | } |
| 1819 | free(result, M_LINKER); |
| 1820 | return (NULL); |
| 1821 | } |
| 1822 | |
| 1823 | #define INT_ALIGN(base, ptr) ptr = \ |
| 1824 | (base) + roundup2((ptr) - (base), sizeof(int)) |