11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved. 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions of source code must retain the above copyright 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the documentation and/or other materials provided with the 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * distribution. 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <unistd.h> 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <dirent.h> 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <memory.h> 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h> 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <fcntl.h> 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h> 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <pthread.h> 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h> 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct DIR 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int _DIR_fd; 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project size_t _DIR_avail; 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct dirent* _DIR_next; 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_t _DIR_lock; 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct dirent _DIR_buff[15]; 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}; 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint dirfd(DIR* dirp) 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return dirp->_DIR_fd; 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectDIR* opendir( const char* dirpath ) 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DIR* dir = malloc(sizeof(DIR)); 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!dir) 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto Exit; 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_fd = open(dirpath, O_RDONLY|O_DIRECTORY); 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (dir->_DIR_fd < 0) 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project free(dir); 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir = NULL; 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_avail = 0; 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_next = NULL; 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_init( &dir->_DIR_lock, NULL ); 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectExit: 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return dir; 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectDIR* fdopendir(int fd) 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DIR* dir = malloc(sizeof(DIR)); 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!dir) 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_fd = fd; 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_avail = 0; 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_next = NULL; 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_init( &dir->_DIR_lock, NULL ); 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return dir; 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct dirent* 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project_readdir_unlocked(DIR* dir) 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct dirent* entry; 951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ( !dir->_DIR_avail ) 971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { 981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int rc; 991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (;;) { 1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rc = getdents( dir->_DIR_fd, dir->_DIR_buff, sizeof(dir->_DIR_buff)); 1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (rc >= 0 || errno != EINTR) 1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project break; 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (rc <= 0) 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return NULL; 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_avail = rc; 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_next = dir->_DIR_buff; 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project entry = dir->_DIR_next; 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* perform some sanity checks here */ 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (((long)(void*)entry & 3) != 0) 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return NULL; 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ( (unsigned)entry->d_reclen > sizeof(*entry) || 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project entry->d_reclen <= offsetof(struct dirent, d_name) ) 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto Bad; 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ( (char*)entry + entry->d_reclen > (char*)dir->_DIR_buff + sizeof(dir->_DIR_buff) ) 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto Bad; 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if ( !memchr( entry->d_name, 0, entry->d_reclen - offsetof(struct dirent, d_name)) ) 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto Bad; 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_next = (struct dirent*)((char*)entry + entry->d_reclen); 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_avail -= entry->d_reclen; 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return entry; 1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project Bad: 1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = EINVAL; 1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return NULL; 1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct dirent* 1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectreaddir(DIR * dir) 1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct dirent *entry = NULL; 1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_lock( &dir->_DIR_lock ); 1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project entry = _readdir_unlocked(dir); 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock( &dir->_DIR_lock ); 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return entry; 1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint readdir_r(DIR* dir, struct dirent *entry, struct dirent **result) 1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct dirent* ent; 1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int save_errno = errno; 1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int retval; 1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *result = NULL; 1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = 0; 1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_lock( &dir->_DIR_lock ); 1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ent = _readdir_unlocked(dir); 1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project retval = errno; 1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (ent == NULL) { 1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!retval) { 1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = save_errno; 1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (!retval) { 1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project errno = save_errno; 1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *result = entry; 1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memcpy( entry, ent, ent->d_reclen ); 1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock( &dir->_DIR_lock ); 1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return retval; 1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint closedir(DIR *dir) 1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int rc; 1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rc = close(dir->_DIR_fd); 1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_fd = -1; 1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_destroy( &dir->_DIR_lock ); 1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project free(dir); 1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return rc; 1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid rewinddir(DIR *dir) 1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_lock( &dir->_DIR_lock ); 2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project lseek( dir->_DIR_fd, 0, SEEK_SET ); 2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project dir->_DIR_avail = 0; 2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project pthread_mutex_unlock( &dir->_DIR_lock ); 2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint alphasort(const void *a, const void *b) 2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct dirent **d1, **d2; 2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project d1 = (struct dirent **) a; 2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project d2 = (struct dirent **) b; 2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return strcmp((*d1)->d_name, (*d2)->d_name); 2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint scandir(const char *dir, struct dirent ***namelist, 2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int(*filter)(const struct dirent *), 2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int(*compar)(const struct dirent **, const struct dirent **)) 2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project DIR *d; 2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int n_elem = 0; 2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct dirent *this_de, *de; 2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct dirent **de_list = NULL; 2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int de_list_size = 0; 2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project d = opendir(dir); 2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (d == NULL) { 2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return -1; 2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project while ((this_de = readdir(d)) != NULL) { 2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (filter && (*filter)(this_de) == 0) { 2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project continue; 2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n_elem == 0) { 2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project de_list_size = 4; 2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project de_list = (struct dirent **) 2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project malloc(sizeof(struct dirent *)*de_list_size); 2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (de_list == NULL) { 2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return -1; 2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (n_elem == de_list_size) { 2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project struct dirent **de_list_new; 2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project de_list_size += 10; 2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project de_list_new = (struct dirent **) 2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project realloc(de_list, sizeof(struct dirent *)*de_list_size); 2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (de_list_new == NULL) { 2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project free(de_list); 2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return -1; 2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project de_list = de_list_new; 2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project de = (struct dirent *) malloc(sizeof(struct dirent)); 2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *de = *this_de; 2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project de_list[n_elem++] = de; 2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project closedir(d); 2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (n_elem && compar) { 2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project qsort(de_list, n_elem, sizeof(struct dirent *), 2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project (int (*)(const void *, const void *)) compar); 2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *namelist = de_list; 2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return n_elem; 2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 268