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

Comparing libeio/eio.c (file contents):
Revision 1.77 by root, Tue Jul 5 14:02:15 2011 UTC vs.
Revision 1.78 by root, Tue Jul 5 14:38:53 2011 UTC

1243{ 1243{
1244 char *rel = req->ptr1; 1244 char *rel = req->ptr1;
1245 char *res; 1245 char *res;
1246 char *tmp1, *tmp2; 1246 char *tmp1, *tmp2;
1247#if SYMLOOP_MAX > 32 1247#if SYMLOOP_MAX > 32
1248 int links = SYMLOOP_MAX; 1248 int symlinks = SYMLOOP_MAX;
1249#else 1249#else
1250 int links = 32; 1250 int symlinks = 32;
1251#endif 1251#endif
1252 1252
1253 req->result = -1; 1253 req->result = -1;
1254 1254
1255 errno = EINVAL; 1255 errno = EINVAL;
1273 } 1273 }
1274 1274
1275 res = req->ptr2; 1275 res = req->ptr2;
1276 tmp1 = res + PATH_MAX; 1276 tmp1 = res + PATH_MAX;
1277 tmp2 = tmp1 + PATH_MAX; 1277 tmp2 = tmp1 + PATH_MAX;
1278
1279#if 0 /* disabled, the musl way to do things is just too racy */
1280#if __linux && defined(O_NONBLOCK) && defined(O_NOATIME)
1281 /* on linux we may be able to ask the kernel */
1282 {
1283 int fd = open (rel, O_RDONLY | O_NONBLOCK | O_NOCTTY | O_NOATIME);
1284
1285 if (fd >= 0)
1286 {
1287 sprintf (tmp1, "/proc/self/fd/%d", fd);
1288 req->result = readlink (tmp1, res, PATH_MAX);
1289 close (fd);
1290
1291 /* here we should probably stat the open file and the disk file, to make sure they still match */
1292
1293 if (req->result > 0)
1294 goto done;
1295 }
1296 else if (errno == ELOOP || errno == ENAMETOOLONG || errno == ENOENT || errno == ENOTDIR || errno == EIO)
1297 return;
1298 }
1299#endif
1300#endif
1278 1301
1279 if (*rel != '/') 1302 if (*rel != '/')
1280 { 1303 {
1281 if (!getcwd (res, PATH_MAX)) 1304 if (!getcwd (res, PATH_MAX))
1282 return; 1305 return;
1347 1370
1348 errno = ENAMETOOLONG; 1371 errno = ENAMETOOLONG;
1349 if (linklen + 1 + rellen >= PATH_MAX) 1372 if (linklen + 1 + rellen >= PATH_MAX)
1350 return; 1373 return;
1351 1374
1375 errno = ELOOP;
1376 if (!--symlinks)
1377 return;
1378
1352 if (*tmp1 == '/') 1379 if (*tmp1 == '/')
1353 res = req->ptr2; /* symlink resolves to an absolute path */ 1380 res = req->ptr2; /* symlink resolves to an absolute path */
1354 1381
1355 /* we need to be careful, as rel might point into tmp2 already */ 1382 /* we need to be careful, as rel might point into tmp2 already */
1356 memmove (tmp2 + linklen + 1, rel, rellen + 1); 1383 memmove (tmp2 + linklen + 1, rel, rellen + 1);
1364 /* special case for the lone root path */ 1391 /* special case for the lone root path */
1365 if (res == req->ptr2) 1392 if (res == req->ptr2)
1366 *res++ = '/'; 1393 *res++ = '/';
1367 1394
1368 req->result = res - (char *)req->ptr2; 1395 req->result = res - (char *)req->ptr2;
1396
1397done:
1369 req->ptr2 = realloc (req->ptr2, req->result); /* trade time for space savings */ 1398 req->ptr2 = realloc (req->ptr2, req->result); /* trade time for space savings */
1370} 1399}
1371 1400
1372static signed char 1401static signed char
1373eio_dent_cmp (const eio_dirent *a, const eio_dirent *b) 1402eio_dent_cmp (const eio_dirent *a, const eio_dirent *b)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines