… | |
… | |
23 | # elif __freebsd |
23 | # elif __freebsd |
24 | # include <sys/socket.h> |
24 | # include <sys/socket.h> |
25 | # include <sys/uio.h> |
25 | # include <sys/uio.h> |
26 | # elif __hpux |
26 | # elif __hpux |
27 | # include <sys/socket.h> |
27 | # include <sys/socket.h> |
|
|
28 | # elif __solaris /* not yet */ |
|
|
29 | # include <sys/sendfile.h> |
|
|
30 | # else |
|
|
31 | # error sendfile support requested but not available |
28 | # endif |
32 | # endif |
29 | #endif |
33 | #endif |
30 | |
34 | |
31 | #if __ia64 |
35 | #if __ia64 |
32 | # define STACKSIZE 65536 |
36 | # define STACKSIZE 65536 |
… | |
… | |
356 | create_pipe (); |
360 | create_pipe (); |
357 | |
361 | |
358 | atfork_parent (); |
362 | atfork_parent (); |
359 | } |
363 | } |
360 | |
364 | |
|
|
365 | /* currently noops */ |
|
|
366 | #define LOCK_FD(fd) do { } while (0) |
|
|
367 | #define UNLOCK_FD(fd) do { } while (0) |
|
|
368 | |
361 | /*****************************************************************************/ |
369 | /*****************************************************************************/ |
362 | /* work around various missing functions */ |
370 | /* work around various missing functions */ |
363 | |
371 | |
364 | #if !HAVE_PREADWRITE |
372 | #if !HAVE_PREADWRITE |
365 | # define pread aio_pread |
373 | # define pread aio_pread |
… | |
… | |
376 | pread (int fd, void *buf, size_t count, off_t offset) |
384 | pread (int fd, void *buf, size_t count, off_t offset) |
377 | { |
385 | { |
378 | ssize_t res; |
386 | ssize_t res; |
379 | off_t ooffset; |
387 | off_t ooffset; |
380 | |
388 | |
381 | pthread_mutex_lock (&iolock); |
389 | LOCK_FD (fd); |
|
|
390 | pthread_mutex_lock (&iolock); /* replace by LOCK_FD and private buffer */ |
382 | ooffset = lseek (fd, 0, SEEK_CUR); |
391 | ooffset = lseek (fd, 0, SEEK_CUR); |
383 | lseek (fd, offset, SEEK_SET); |
392 | lseek (fd, offset, SEEK_SET); |
384 | res = read (fd, buf, count); |
393 | res = read (fd, buf, count); |
385 | lseek (fd, ooffset, SEEK_SET); |
394 | lseek (fd, ooffset, SEEK_SET); |
386 | pthread_mutex_unlock (&iolock); |
395 | pthread_mutex_unlock (&iolock); |
|
|
396 | UNLOCK_FD (d); |
387 | |
397 | |
388 | return res; |
398 | return res; |
389 | } |
399 | } |
390 | |
400 | |
391 | static ssize_t |
401 | static ssize_t |
392 | pwrite (int fd, void *buf, size_t count, off_t offset) |
402 | pwrite (int fd, void *buf, size_t count, off_t offset) |
393 | { |
403 | { |
394 | ssize_t res; |
404 | ssize_t res; |
395 | off_t ooffset; |
405 | off_t ooffset; |
396 | |
406 | |
397 | pthread_mutex_lock (&iolock); |
407 | LOCK_FD (fd); |
|
|
408 | pthread_mutex_lock (&iolock); /* replace by LOCK_FD and private buffer */ |
398 | ooffset = lseek (fd, 0, SEEK_CUR); |
409 | ooffset = lseek (fd, 0, SEEK_CUR); |
399 | lseek (fd, offset, SEEK_SET); |
410 | lseek (fd, offset, SEEK_SET); |
400 | res = write (fd, buf, count); |
411 | res = write (fd, buf, count); |
401 | lseek (fd, offset, SEEK_SET); |
412 | lseek (fd, offset, SEEK_SET); |
402 | pthread_mutex_unlock (&iolock); |
413 | pthread_mutex_unlock (&iolock); |
|
|
414 | UNLOCK_FD (d); |
403 | |
415 | |
404 | return res; |
416 | return res; |
405 | } |
417 | } |
406 | #endif |
418 | #endif |
407 | |
419 | |
… | |
… | |
437 | ssize_t res; |
449 | ssize_t res; |
438 | |
450 | |
439 | if (!count) |
451 | if (!count) |
440 | return 0; |
452 | return 0; |
441 | |
453 | |
|
|
454 | LOCK_FD (ofd); |
|
|
455 | |
|
|
456 | #if HAVE_SENDFILE |
442 | #if __linux |
457 | # if __linux |
443 | res = sendfile (ofd, ifd, &offset, count); |
458 | res = sendfile (ofd, ifd, &offset, count); |
444 | |
459 | |
445 | #elif __freebsd |
460 | # elif __freebsd |
446 | /* |
461 | /* |
447 | * Of course, the freebsd sendfile is a dire hack with no thoughts |
462 | * Of course, the freebsd sendfile is a dire hack with no thoughts |
448 | * wasted on making it similar to other i/o functions. |
463 | * wasted on making it similar to other I/O functions. |
449 | */ |
464 | */ |
450 | { |
465 | { |
451 | off_t sbytes; |
466 | off_t sbytes; |
452 | res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0); |
467 | res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0); |
453 | |
468 | |
454 | if (!res && errno == EAGAIN) |
469 | if (res < 0 && sbytes) |
455 | /* maybe on others, too, as usual, the manpage leaves you guessing */ |
470 | /* maybe only on EAGAIN only: as usual, the manpage leaves you guessing */ |
456 | res = sbytes; |
471 | res = sbytes; |
457 | } |
472 | } |
458 | |
473 | |
459 | #elif __hpux |
474 | # elif __hpux |
460 | res = sendfile (ofd, ifd, offset, count, 0, 0); |
475 | res = sendfile (ofd, ifd, offset, count, 0, 0); |
461 | |
476 | |
|
|
477 | # elif __solaris |
|
|
478 | { |
|
|
479 | struct sendfilevec vec; |
|
|
480 | size_t sbytes; |
|
|
481 | |
|
|
482 | vec.sfv_fd = ifd; |
|
|
483 | vec.sfv_flag = 0; |
|
|
484 | vec.sfv_off = offset; |
|
|
485 | vec.sfv_len = count; |
|
|
486 | |
|
|
487 | res = sendfilev (ofd, &vec, 1, &sbytes); |
|
|
488 | |
|
|
489 | if (res < 0 && sbytes) |
|
|
490 | res = sbytes; |
|
|
491 | } |
|
|
492 | |
462 | #else |
493 | # else |
463 | res = -1; |
494 | res = -1; |
464 | errno = ENOSYS; |
495 | errno = ENOSYS; |
|
|
496 | # endif |
465 | #endif |
497 | #endif |
466 | |
498 | |
|
|
499 | if (res < 0 |
467 | if (res < 0 && (errno == ENOSYS || errno == EINVAL || errno == ENOTSOCK)) |
500 | && (errno == ENOSYS || errno == EINVAL || errno == ENOTSOCK |
|
|
501 | #if __solaris |
|
|
502 | || errno == EAFNOSUPPORT || errno == EPROTOTYPE |
|
|
503 | #endif |
|
|
504 | ) |
|
|
505 | ) |
468 | { |
506 | { |
469 | /* emulate sendfile. this is a major pain in the ass */ |
507 | /* emulate sendfile. this is a major pain in the ass */ |
470 | char *buf = malloc (4096); |
508 | char *buf = malloc (4096); |
471 | res = 0; |
509 | res = 0; |
472 | |
510 | |
… | |
… | |
498 | int errorno = errno; |
536 | int errorno = errno; |
499 | free (buf); |
537 | free (buf); |
500 | errno = errorno; |
538 | errno = errorno; |
501 | } |
539 | } |
502 | } |
540 | } |
|
|
541 | |
|
|
542 | UNLOCK_FD (ofd); |
503 | |
543 | |
504 | return res; |
544 | return res; |
505 | } |
545 | } |
506 | |
546 | |
507 | /*****************************************************************************/ |
547 | /*****************************************************************************/ |