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

Comparing libeio/eio.c (file contents):
Revision 1.31 by root, Sat Jun 6 17:25:13 2009 UTC vs.
Revision 1.36 by root, Fri Jun 12 00:43:16 2009 UTC

80# include <signal.h> 80# include <signal.h>
81# include <dirent.h> 81# include <dirent.h>
82 82
83/* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */ 83/* POSIX_SOURCE is useless on bsd's, and XOPEN_SOURCE is unreliable there, too */
84# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 84# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
85# define _DIRENT_HAVE_D_TYPE /* sigh */
85# define D_INO(de) (de)->d_fileno 86# define D_INO(de) (de)->d_fileno
86# define _DIRENT_HAVE_D_TYPE /* sigh */ 87# define D_NAMLEN(de) (de)->d_namlen
87# elif defined(__linux) || defined(d_ino) || _XOPEN_SOURCE >= 600 88# elif defined(__linux) || defined(d_ino) || _XOPEN_SOURCE >= 600
88# define D_INO(de) (de)->d_ino 89# define D_INO(de) (de)->d_ino
89# endif 90# endif
91
92#ifdef _D_EXACT_NAMLEN
93# undef D_NAMLEN
94# define D_NAMLEN(de) _D_EXACT_NAMLEN (de)
95#endif
90 96
91# ifdef _DIRENT_HAVE_D_TYPE 97# ifdef _DIRENT_HAVE_D_TYPE
92# define D_TYPE(de) (de)->d_type 98# define D_TYPE(de) (de)->d_type
93# endif 99# endif
94 100
114#endif 120#endif
115 121
116#ifndef D_TYPE 122#ifndef D_TYPE
117# define D_TYPE(de) 0 123# define D_TYPE(de) 0
118#endif 124#endif
119
120#ifndef D_INO 125#ifndef D_INO
121# define D_INO(de) 0 126# define D_INO(de) 0
127#endif
128#ifndef D_NAMLEN
129# define D_NAMLEN(de) strlen ((de)->d_name)
122#endif 130#endif
123 131
124/* number of seconds after which an idle threads exit */ 132/* number of seconds after which an idle threads exit */
125#define IDLE_TIMEOUT 10 133#define IDLE_TIMEOUT 10
126 134
178 if (wrk->dirp) \ 186 if (wrk->dirp) \
179 { \ 187 { \
180 closedir (wrk->dirp); \ 188 closedir (wrk->dirp); \
181 wrk->dirp = 0; \ 189 wrk->dirp = 0; \
182 } 190 }
191
183#define ETP_WORKER_COMMON \ 192#define ETP_WORKER_COMMON \
184 void *dbuf; \ 193 void *dbuf; \
185 DIR *dirp; 194 DIR *dirp;
186 195
187/*****************************************************************************/ 196/*****************************************************************************/
1010 1019
1011 if (!(flags & EIO_READDIR_DENTS)) 1020 if (!(flags & EIO_READDIR_DENTS))
1012 flags &= ~(EIO_READDIR_DIRS_FIRST | EIO_READDIR_STAT_ORDER); 1021 flags &= ~(EIO_READDIR_DIRS_FIRST | EIO_READDIR_STAT_ORDER);
1013 1022
1014 X_LOCK (wrklock); 1023 X_LOCK (wrklock);
1015
1016 /* the corresponding closedir is in ETP_WORKER_CLEAR */ 1024 /* the corresponding closedir is in ETP_WORKER_CLEAR */
1017 self->dirp = dirp = opendir (req->ptr1); 1025 self->dirp = dirp = opendir (req->ptr1);
1018 req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE; 1026 req->flags |= EIO_FLAG_PTR1_FREE | EIO_FLAG_PTR2_FREE;
1019 req->ptr1 = names = malloc (namesalloc); 1027 req->ptr1 = names = malloc (namesalloc);
1020 req->ptr2 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0; 1028 req->ptr2 = dents = flags ? malloc (dentalloc * sizeof (eio_dirent)) : 0;
1021
1022 X_UNLOCK (wrklock); 1029 X_UNLOCK (wrklock);
1023 1030
1024 if (dirp && names && (!flags || dents)) 1031 if (dirp && names && (!flags || dents))
1025 for (;;) 1032 for (;;)
1026 { 1033 {
1034 1041
1035 /* sort etc. */ 1042 /* sort etc. */
1036 req->int1 = flags; 1043 req->int1 = flags;
1037 req->result = dentoffs; 1044 req->result = dentoffs;
1038 1045
1046 if (dents)
1047 {
1048 eio_dirent *ent = dents + dentoffs;
1049
1050 while (ent > dents)
1051 (--ent)->name = names + (size_t)ent->name;
1052 }
1053
1054 if (flags & EIO_READDIR_STAT_ORDER
1039 if (flags & EIO_READDIR_STAT_ORDER || !(~flags & (EIO_READDIR_DIRS_FIRST | EIO_READDIR_FOUND_UNKNOWN)) 1055 || !(~flags & (EIO_READDIR_DIRS_FIRST | EIO_READDIR_FOUND_UNKNOWN)))
1040 { 1056 {
1041 /* pray your qsort doesn't use quicksort */ 1057 /* pray your qsort doesn't use quicksort */
1042 qsort (dents, dentoffs, sizeof (*dents), eio_dent_cmp); /* score depends of DIRS_FIRST */ 1058 qsort (dents, dentoffs, sizeof (*dents), eio_dent_cmp); /* score depends of DIRS_FIRST */
1043 } 1059 }
1044 else if (flags & EIO_READDIR_DIRS_FIRST && !(flags & EIO_READDIR_FOUND_UNKNOWN)) 1060 else if (flags & EIO_READDIR_DIRS_FIRST)
1045 { 1061 {
1046 /* in this case, all is known, and we just put dirs first and sort them */ 1062 /* in this case, all is known, and we just put dirs first and sort them */
1047 eio_dirent *ent = dents + dentoffs; 1063 eio_dirent *ent = dents + dentoffs;
1048 eio_dirent *dir = dents; 1064 eio_dirent *dir = dents;
1049 1065
1066 /* now move dirs to the front, and non-dirs to the back */
1067 /* by walkign from both sides and swapping if necessary */
1050 while (ent > dir) 1068 while (ent > dir)
1051 { 1069 {
1052 if (dir->type == DT_DIR) 1070 if (dir->type == DT_DIR)
1053 ++dir; 1071 ++dir;
1054 else 1072 else
1068 1086
1069 /* now sort the dirs only */ 1087 /* now sort the dirs only */
1070 qsort (dents, dir - dents, sizeof (*dents), eio_dent_cmp); 1088 qsort (dents, dir - dents, sizeof (*dents), eio_dent_cmp);
1071 } 1089 }
1072 1090
1073 {int i; for(i=0;i<dentoffs;++i){eio_dirent *e=dents+i; printf ("%9ld %3d %s\n", e->inode,e->score,e->name);}}//D 1091 /* only provide the names array unless DENTS is specified */
1092 if (!(flags & EIO_READDIR_DENTS))
1093 {
1094 X_LOCK (wrklock);
1095 assert (!dents);
1096 req->ptr1 = 0;
1097 req->ptr2 = names;
1098 X_UNLOCK (wrklock);
1099 }
1074 1100
1075 break; 1101 break;
1076 } 1102 }
1077 1103
1104 /* now add the entry to our list(s) */
1078 name = entp->d_name; 1105 name = entp->d_name;
1079 1106
1107 /* skip . and .. entries */
1080 if (name [0] != '.' || (name [1] && (name [1] != '.' || name [2]))) 1108 if (name [0] != '.' || (name [1] && (name [1] != '.' || name [2])))
1081 { 1109 {
1082 int len = strlen (name) + 1; 1110 int len = D_NAMLEN (entp) + 1;
1083 1111
1084 while (expect_false (namesoffs + len > namesalloc)) 1112 while (expect_false (namesoffs + len > namesalloc))
1085 { 1113 {
1086 namesalloc *= 2; 1114 namesalloc *= 2;
1087 X_LOCK (wrklock); 1115 X_LOCK (wrklock);
1109 break; 1137 break;
1110 } 1138 }
1111 1139
1112 ent = dents + dentoffs; 1140 ent = dents + dentoffs;
1113 1141
1114 ent->name = names + namesoffs; 1142 ent->name = (char *)(size_t)namesoffs; /* rather dirtily we store the offset in the pointer */
1115 ent->namelen = len - 1; 1143 ent->namelen = len - 1;
1116 ent->inode = D_INO (entp); 1144 ent->inode = D_INO (entp);
1117 1145
1118 switch (D_TYPE (entp)) 1146 switch (D_TYPE (entp))
1119 { 1147 {
1126 case DT_FIFO: ent->type = EIO_DT_FIFO; break; 1154 case DT_FIFO: ent->type = EIO_DT_FIFO; break;
1127 #endif 1155 #endif
1128 #ifdef DT_CHR 1156 #ifdef DT_CHR
1129 case DT_CHR: ent->type = EIO_DT_CHR; break; 1157 case DT_CHR: ent->type = EIO_DT_CHR; break;
1130 #endif 1158 #endif
1159 #ifdef DT_MPC
1160 case DT_MPC: ent->type = EIO_DT_MPC; break;
1161 #endif
1131 #ifdef DT_DIR 1162 #ifdef DT_DIR
1132 case DT_DIR: ent->type = EIO_DT_DIR; break; 1163 case DT_DIR: ent->type = EIO_DT_DIR; break;
1133 #endif 1164 #endif
1165 #ifdef DT_NAM
1166 case DT_NAM: ent->type = EIO_DT_NAM; break;
1167 #endif
1134 #ifdef DT_BLK 1168 #ifdef DT_BLK
1135 case DT_BLK: ent->type = EIO_DT_BLK; break; 1169 case DT_BLK: ent->type = EIO_DT_BLK; break;
1136 #endif 1170 #endif
1171 #ifdef DT_MPB
1172 case DT_MPB: ent->type = EIO_DT_MPB; break;
1173 #endif
1137 #ifdef DT_REG 1174 #ifdef DT_REG
1138 case DT_REG: ent->type = EIO_DT_REG; break; 1175 case DT_REG: ent->type = EIO_DT_REG; break;
1139 #endif 1176 #endif
1177 #ifdef DT_NWK
1178 case DT_NWK: ent->type = EIO_DT_NWK; break;
1179 #endif
1180 #ifdef DT_CMP
1181 case DT_CMP: ent->type = EIO_DT_CMP; break;
1182 #endif
1140 #ifdef DT_LNK 1183 #ifdef DT_LNK
1141 case DT_LNK: ent->type = EIO_DT_LNK; break; 1184 case DT_LNK: ent->type = EIO_DT_LNK; break;
1142 #endif 1185 #endif
1143 #ifdef DT_SOCK 1186 #ifdef DT_SOCK
1144 case DT_SOCK: ent->type = EIO_DT_SOCK; break; 1187 case DT_SOCK: ent->type = EIO_DT_SOCK; break;
1188 #endif
1189 #ifdef DT_DOOR
1190 case DT_DOOR: ent->type = EIO_DT_DOOR; break;
1145 #endif 1191 #endif
1146 #ifdef DT_WHT 1192 #ifdef DT_WHT
1147 case DT_WHT: ent->type = EIO_DT_WHT; break; 1193 case DT_WHT: ent->type = EIO_DT_WHT; break;
1148 #endif 1194 #endif
1149 } 1195 }
1155 if (ent->type == EIO_DT_UNKNOWN) 1201 if (ent->type == EIO_DT_UNKNOWN)
1156 { 1202 {
1157 if (*name == '.') /* leading dots are likely directories, and, in any case, rare */ 1203 if (*name == '.') /* leading dots are likely directories, and, in any case, rare */
1158 ent->score = 98; 1204 ent->score = 98;
1159 else if (!strchr (name, '.')) /* absense of dots indicate likely dirs */ 1205 else if (!strchr (name, '.')) /* absense of dots indicate likely dirs */
1160 ent->score = len <= 4 ? 5 : len <= 7 ? 4 : 1; /* shorter == more likely dir, but avoid too many classes */ 1206 ent->score = len <= 2 ? len + 6 : len <= 4 ? 5 : len <= 7 ? 4 : 1; /* shorter == more likely dir, but avoid too many classes */
1161 } 1207 }
1162 else if (ent->type == DT_DIR) 1208 else if (ent->type == EIO_DT_DIR)
1163 ent->score = 100; 1209 ent->score = 100;
1164 } 1210 }
1165 } 1211 }
1166 1212
1167 namesoffs += len; 1213 namesoffs += len;
1168 ++dentoffs; 1214 ++dentoffs;
1169 } 1215 }
1216
1217 if (EIO_CANCELLED (req))
1218 {
1219 errno = ECANCELED;
1220 break;
1221 }
1170 } 1222 }
1171 else
1172 req->result = -1;
1173
1174 /* if user doesn't want the dents, do not provide it */
1175 if (!(flags & EIO_READDIR_DENTS))
1176 {
1177 X_LOCK (wrklock);
1178 free (dents);
1179 req->ptr2 = req->ptr1;
1180 req->ptr1 = 0;
1181 X_UNLOCK (wrklock);
1182 }
1183} 1223}
1184 1224
1185#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO) 1225#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO)
1186# undef msync 1226# undef msync
1187# define msync(a,b,c) ((errno = ENOSYS), -1) 1227# define msync(a,b,c) ((errno = ENOSYS), -1)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines