ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libeio/eio.c
(Generate patch)

Comparing libeio/eio.c (file contents):
Revision 1.102 by root, Sun Aug 21 01:03:09 2011 UTC vs.
Revision 1.103 by root, Thu Sep 15 13:20:54 2011 UTC

1706 dirp = FindFirstFile (path, &entp); 1706 dirp = FindFirstFile (path, &entp);
1707 free (path); 1707 free (path);
1708 1708
1709 if (dirp == INVALID_HANDLE_VALUE) 1709 if (dirp == INVALID_HANDLE_VALUE)
1710 { 1710 {
1711 dirp = 0;
1712
1713 /* should steal _dosmaperr */ 1711 /* should steal _dosmaperr */
1714 switch (GetLastError ()) 1712 switch (GetLastError ())
1715 { 1713 {
1716 case ERROR_FILE_NOT_FOUND: 1714 case ERROR_FILE_NOT_FOUND:
1717 req->result = 0; 1715 req->result = 0;
1718 break; 1716 break;
1719 1717
1720 case ERROR_INVALID_NAME: 1718 case ERROR_INVALID_NAME:
1721 case ERROR_PATH_NOT_FOUND: 1719 case ERROR_PATH_NOT_FOUND:
1722 case ERROR_NO_MORE_FILES: 1720 case ERROR_NO_MORE_FILES:
1723 errno = ENOENT; 1721 errno = ENOENT;
1724 break; 1722 break;
1725 1723
1726 case ERROR_NOT_ENOUGH_MEMORY: 1724 case ERROR_NOT_ENOUGH_MEMORY:
1727 errno = ENOMEM; 1725 errno = ENOMEM;
1728 break; 1726 break;
1729 1727
1730 default: 1728 default:
1731 errno = EINVAL; 1729 errno = EINVAL;
1732 break; 1730 break;
1733 } 1731 }
1732
1733 return;
1734 } 1734 }
1735 } 1735 }
1736#else 1736#else
1737 dirp = opendir (req->ptr1); 1737 dirp = opendir (req->ptr1);
1738
1739 if (!dirp)
1740 return;
1738#endif 1741#endif
1739 1742
1740 if (req->flags & EIO_FLAG_PTR1_FREE) 1743 if (req->flags & EIO_FLAG_PTR1_FREE)
1741 free (req->ptr1); 1744 free (req->ptr1);
1742 1745
1743 req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE; 1746 req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE;
1744 req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0; 1747 req->ptr1 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0;
1745 req->ptr2 = names = malloc (namesalloc); 1748 req->ptr2 = names = malloc (namesalloc);
1746 1749
1747 if (dirp && names && (!flags || dents)) 1750 if (!names || (flags && !dents))
1751 return;
1752
1748 for (;;) 1753 for (;;)
1749 { 1754 {
1750 int done; 1755 int done;
1751 1756
1752#ifdef _WIN32 1757#ifdef _WIN32
1753 done = !dirp; 1758 done = !dirp;
1754#else 1759#else
1755 errno = 0; 1760 errno = 0;
1756 entp = readdir (dirp); 1761 entp = readdir (dirp);
1757 done = !entp; 1762 done = !entp;
1758#endif 1763#endif
1759 1764
1760 if (done) 1765 if (done)
1761 { 1766 {
1762#ifndef _WIN32 1767#ifndef _WIN32
1763 int old_errno = errno; 1768 int old_errno = errno;
1764 closedir (dirp); 1769 closedir (dirp);
1765 errno = old_errno; 1770 errno = old_errno;
1766 1771
1767 if (errno) 1772 if (errno)
1768 break; 1773 break;
1769#endif 1774#endif
1770 1775
1771 /* sort etc. */ 1776 /* sort etc. */
1772 req->int1 = flags; 1777 req->int1 = flags;
1773 req->result = dentoffs; 1778 req->result = dentoffs;
1774 1779
1775 if (flags & EIO_READDIR_STAT_ORDER) 1780 if (flags & EIO_READDIR_STAT_ORDER)
1776 eio_dent_sort (dents, dentoffs, flags & EIO_READDIR_DIRS_FIRST ? 7 : 0, inode_bits); 1781 eio_dent_sort (dents, dentoffs, flags & EIO_READDIR_DIRS_FIRST ? 7 : 0, inode_bits);
1777 else if (flags & EIO_READDIR_DIRS_FIRST) 1782 else if (flags & EIO_READDIR_DIRS_FIRST)
1778 if (flags & EIO_READDIR_FOUND_UNKNOWN) 1783 if (flags & EIO_READDIR_FOUND_UNKNOWN)
1779 eio_dent_sort (dents, dentoffs, 7, inode_bits); /* sort by score and inode */ 1784 eio_dent_sort (dents, dentoffs, 7, inode_bits); /* sort by score and inode */
1780 else 1785 else
1786 {
1787 /* in this case, all is known, and we just put dirs first and sort them */
1788 eio_dirent *oth = dents + dentoffs;
1789 eio_dirent *dir = dents;
1790
1791 /* now partition dirs to the front, and non-dirs to the back */
1792 /* by walking from both sides and swapping if necessary */
1793 while (oth > dir)
1794 {
1795 if (dir->type == EIO_DT_DIR)
1796 ++dir;
1797 else if ((--oth)->type == EIO_DT_DIR)
1798 {
1799 eio_dirent tmp = *dir; *dir = *oth; *oth = tmp;
1800
1801 ++dir;
1802 }
1803 }
1804
1805 /* now sort the dirs only (dirs all have the same score) */
1806 eio_dent_sort (dents, dir - dents, 0, inode_bits);
1807 }
1808
1809 break;
1810 }
1811
1812 /* now add the entry to our list(s) */
1813 name = D_NAME (entp);
1814
1815 /* skip . and .. entries */
1816 if (name [0] != '.' || (name [1] && (name [1] != '.' || name [2])))
1817 {
1818 int len = D_NAMLEN (entp) + 1;
1819
1820 while (ecb_expect_false (namesoffs + len > namesalloc))
1821 {
1822 namesalloc *= 2;
1823 req->ptr2 = names = realloc (names, namesalloc);
1824
1825 if (!names)
1826 break;
1827 }
1828
1829 memcpy (names + namesoffs, name, len);
1830
1831 if (dents)
1832 {
1833 struct eio_dirent *ent;
1834
1835 if (ecb_expect_false (dentoffs == dentalloc))
1781 { 1836 {
1782 /* in this case, all is known, and we just put dirs first and sort them */ 1837 dentalloc *= 2;
1838 req->ptr1 = dents = realloc (dents, dentalloc * sizeof (eio_dirent));
1839
1840 if (!dents)
1841 break;
1842 }
1843
1783 eio_dirent *oth = dents + dentoffs; 1844 ent = dents + dentoffs;
1784 eio_dirent *dir = dents;
1785 1845
1786 /* now partition dirs to the front, and non-dirs to the back */ 1846 ent->nameofs = namesoffs; /* rather dirtily we store the offset in the pointer */
1787 /* by walking from both sides and swapping if necessary */ 1847 ent->namelen = len - 1;
1788 while (oth > dir) 1848 ent->inode = D_INO (entp);
1849
1850 inode_bits |= ent->inode;
1851
1852 switch (D_TYPE (entp))
1853 {
1854 default:
1855 ent->type = EIO_DT_UNKNOWN;
1856 flags |= EIO_READDIR_FOUND_UNKNOWN;
1857 break;
1858
1859 #ifdef DT_FIFO
1860 case DT_FIFO: ent->type = EIO_DT_FIFO; break;
1861 #endif
1862 #ifdef DT_CHR
1863 case DT_CHR: ent->type = EIO_DT_CHR; break;
1864 #endif
1865 #ifdef DT_MPC
1866 case DT_MPC: ent->type = EIO_DT_MPC; break;
1867 #endif
1868 #ifdef DT_DIR
1869 case DT_DIR: ent->type = EIO_DT_DIR; break;
1870 #endif
1871 #ifdef DT_NAM
1872 case DT_NAM: ent->type = EIO_DT_NAM; break;
1873 #endif
1874 #ifdef DT_BLK
1875 case DT_BLK: ent->type = EIO_DT_BLK; break;
1876 #endif
1877 #ifdef DT_MPB
1878 case DT_MPB: ent->type = EIO_DT_MPB; break;
1879 #endif
1880 #ifdef DT_REG
1881 case DT_REG: ent->type = EIO_DT_REG; break;
1882 #endif
1883 #ifdef DT_NWK
1884 case DT_NWK: ent->type = EIO_DT_NWK; break;
1885 #endif
1886 #ifdef DT_CMP
1887 case DT_CMP: ent->type = EIO_DT_CMP; break;
1888 #endif
1889 #ifdef DT_LNK
1890 case DT_LNK: ent->type = EIO_DT_LNK; break;
1891 #endif
1892 #ifdef DT_SOCK
1893 case DT_SOCK: ent->type = EIO_DT_SOCK; break;
1894 #endif
1895 #ifdef DT_DOOR
1896 case DT_DOOR: ent->type = EIO_DT_DOOR; break;
1897 #endif
1898 #ifdef DT_WHT
1899 case DT_WHT: ent->type = EIO_DT_WHT; break;
1900 #endif
1901 }
1902
1903 ent->score = 7;
1904
1905 if (flags & EIO_READDIR_DIRS_FIRST)
1906 {
1907 if (ent->type == EIO_DT_UNKNOWN)
1789 { 1908 {
1790 if (dir->type == EIO_DT_DIR) 1909 if (*name == '.') /* leading dots are likely directories, and, in any case, rare */
1791 ++dir; 1910 ent->score = 1;
1792 else if ((--oth)->type == EIO_DT_DIR) 1911 else if (!strchr (name, '.')) /* absense of dots indicate likely dirs */
1793 { 1912 ent->score = len <= 2 ? 4 - len : len <= 4 ? 4 : len <= 7 ? 5 : 6; /* shorter == more likely dir, but avoid too many classes */
1794 eio_dirent tmp = *dir; *dir = *oth; *oth = tmp;
1795
1796 ++dir;
1797 }
1798 } 1913 }
1799 1914 else if (ent->type == EIO_DT_DIR)
1800 /* now sort the dirs only (dirs all have the same score) */ 1915 ent->score = 0;
1801 eio_dent_sort (dents, dir - dents, 0, inode_bits);
1802 } 1916 }
1803
1804 break;
1805 }
1806
1807 /* now add the entry to our list(s) */
1808 name = D_NAME (entp);
1809
1810 /* skip . and .. entries */
1811 if (name [0] != '.' || (name [1] && (name [1] != '.' || name [2])))
1812 {
1813 int len = D_NAMLEN (entp) + 1;
1814
1815 while (ecb_expect_false (namesoffs + len > namesalloc))
1816 {
1817 namesalloc *= 2;
1818 req->ptr2 = names = realloc (names, namesalloc);
1819
1820 if (!names)
1821 break;
1822 } 1917 }
1823 1918
1824 memcpy (names + namesoffs, name, len);
1825
1826 if (dents)
1827 {
1828 struct eio_dirent *ent;
1829
1830 if (ecb_expect_false (dentoffs == dentalloc))
1831 {
1832 dentalloc *= 2;
1833 req->ptr1 = dents = realloc (dents, dentalloc * sizeof (eio_dirent));
1834
1835 if (!dents)
1836 break;
1837 }
1838
1839 ent = dents + dentoffs;
1840
1841 ent->nameofs = namesoffs; /* rather dirtily we store the offset in the pointer */
1842 ent->namelen = len - 1;
1843 ent->inode = D_INO (entp);
1844
1845 inode_bits |= ent->inode;
1846
1847 switch (D_TYPE (entp))
1848 {
1849 default:
1850 ent->type = EIO_DT_UNKNOWN;
1851 flags |= EIO_READDIR_FOUND_UNKNOWN;
1852 break;
1853
1854 #ifdef DT_FIFO
1855 case DT_FIFO: ent->type = EIO_DT_FIFO; break;
1856 #endif
1857 #ifdef DT_CHR
1858 case DT_CHR: ent->type = EIO_DT_CHR; break;
1859 #endif
1860 #ifdef DT_MPC
1861 case DT_MPC: ent->type = EIO_DT_MPC; break;
1862 #endif
1863 #ifdef DT_DIR
1864 case DT_DIR: ent->type = EIO_DT_DIR; break;
1865 #endif
1866 #ifdef DT_NAM
1867 case DT_NAM: ent->type = EIO_DT_NAM; break;
1868 #endif
1869 #ifdef DT_BLK
1870 case DT_BLK: ent->type = EIO_DT_BLK; break;
1871 #endif
1872 #ifdef DT_MPB
1873 case DT_MPB: ent->type = EIO_DT_MPB; break;
1874 #endif
1875 #ifdef DT_REG
1876 case DT_REG: ent->type = EIO_DT_REG; break;
1877 #endif
1878 #ifdef DT_NWK
1879 case DT_NWK: ent->type = EIO_DT_NWK; break;
1880 #endif
1881 #ifdef DT_CMP
1882 case DT_CMP: ent->type = EIO_DT_CMP; break;
1883 #endif
1884 #ifdef DT_LNK
1885 case DT_LNK: ent->type = EIO_DT_LNK; break;
1886 #endif
1887 #ifdef DT_SOCK
1888 case DT_SOCK: ent->type = EIO_DT_SOCK; break;
1889 #endif
1890 #ifdef DT_DOOR
1891 case DT_DOOR: ent->type = EIO_DT_DOOR; break;
1892 #endif
1893 #ifdef DT_WHT
1894 case DT_WHT: ent->type = EIO_DT_WHT; break;
1895 #endif
1896 }
1897
1898 ent->score = 7;
1899
1900 if (flags & EIO_READDIR_DIRS_FIRST)
1901 {
1902 if (ent->type == EIO_DT_UNKNOWN)
1903 {
1904 if (*name == '.') /* leading dots are likely directories, and, in any case, rare */
1905 ent->score = 1;
1906 else if (!strchr (name, '.')) /* absense of dots indicate likely dirs */
1907 ent->score = len <= 2 ? 4 - len : len <= 4 ? 4 : len <= 7 ? 5 : 6; /* shorter == more likely dir, but avoid too many classes */
1908 }
1909 else if (ent->type == EIO_DT_DIR)
1910 ent->score = 0;
1911 }
1912 }
1913
1914 namesoffs += len; 1919 namesoffs += len;
1915 ++dentoffs; 1920 ++dentoffs;
1916 } 1921 }
1917 1922
1918 if (EIO_CANCELLED (req)) 1923 if (EIO_CANCELLED (req))
1919 { 1924 {
1920 errno = ECANCELED; 1925 errno = ECANCELED;
1921 break; 1926 break;
1922 } 1927 }
1923 1928
1924#ifdef _WIN32 1929#ifdef _WIN32
1925 if (!FindNextFile (dirp, &entp)) 1930 if (!FindNextFile (dirp, &entp))
1926 { 1931 {
1927 FindClose (dirp); 1932 FindClose (dirp);
1928 dirp = 0; 1933 dirp = 0;
1929 } 1934 }
1930#endif 1935#endif
1931 } 1936 }
1932} 1937}
1933 1938
1934/*****************************************************************************/ 1939/*****************************************************************************/
1935 1940
1936#define ALLOC(len) \ 1941#define ALLOC(len) \

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines