… | |
… | |
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> |
28 | # else |
30 | # else |
29 | # error sendfile support requested but not available |
31 | # error sendfile support requested but not available |
30 | # endif |
32 | # endif |
31 | #endif |
33 | #endif |
32 | |
34 | |
… | |
… | |
358 | create_pipe (); |
360 | create_pipe (); |
359 | |
361 | |
360 | atfork_parent (); |
362 | atfork_parent (); |
361 | } |
363 | } |
362 | |
364 | |
|
|
365 | /* currently noops */ |
|
|
366 | #define LOCK_FD(fd) do { } while (0) |
|
|
367 | #define UNLOCK_FD(fd) do { } while (0) |
|
|
368 | |
363 | /*****************************************************************************/ |
369 | /*****************************************************************************/ |
364 | /* work around various missing functions */ |
370 | /* work around various missing functions */ |
365 | |
371 | |
366 | #if !HAVE_PREADWRITE |
372 | #if !HAVE_PREADWRITE |
367 | # define pread aio_pread |
373 | # define pread aio_pread |
… | |
… | |
378 | pread (int fd, void *buf, size_t count, off_t offset) |
384 | pread (int fd, void *buf, size_t count, off_t offset) |
379 | { |
385 | { |
380 | ssize_t res; |
386 | ssize_t res; |
381 | off_t ooffset; |
387 | off_t ooffset; |
382 | |
388 | |
383 | pthread_mutex_lock (&iolock); |
389 | LOCK_FD (fd); |
|
|
390 | pthread_mutex_lock (&iolock); /* replace by LOCK_FD and private buffer */ |
384 | ooffset = lseek (fd, 0, SEEK_CUR); |
391 | ooffset = lseek (fd, 0, SEEK_CUR); |
385 | lseek (fd, offset, SEEK_SET); |
392 | lseek (fd, offset, SEEK_SET); |
386 | res = read (fd, buf, count); |
393 | res = read (fd, buf, count); |
387 | lseek (fd, ooffset, SEEK_SET); |
394 | lseek (fd, ooffset, SEEK_SET); |
388 | pthread_mutex_unlock (&iolock); |
395 | pthread_mutex_unlock (&iolock); |
|
|
396 | UNLOCK_FD (d); |
389 | |
397 | |
390 | return res; |
398 | return res; |
391 | } |
399 | } |
392 | |
400 | |
393 | static ssize_t |
401 | static ssize_t |
394 | pwrite (int fd, void *buf, size_t count, off_t offset) |
402 | pwrite (int fd, void *buf, size_t count, off_t offset) |
395 | { |
403 | { |
396 | ssize_t res; |
404 | ssize_t res; |
397 | off_t ooffset; |
405 | off_t ooffset; |
398 | |
406 | |
399 | pthread_mutex_lock (&iolock); |
407 | LOCK_FD (fd); |
|
|
408 | pthread_mutex_lock (&iolock); /* replace by LOCK_FD and private buffer */ |
400 | ooffset = lseek (fd, 0, SEEK_CUR); |
409 | ooffset = lseek (fd, 0, SEEK_CUR); |
401 | lseek (fd, offset, SEEK_SET); |
410 | lseek (fd, offset, SEEK_SET); |
402 | res = write (fd, buf, count); |
411 | res = write (fd, buf, count); |
403 | lseek (fd, offset, SEEK_SET); |
412 | lseek (fd, offset, SEEK_SET); |
404 | pthread_mutex_unlock (&iolock); |
413 | pthread_mutex_unlock (&iolock); |
|
|
414 | UNLOCK_FD (d); |
405 | |
415 | |
406 | return res; |
416 | return res; |
407 | } |
417 | } |
408 | #endif |
418 | #endif |
409 | |
419 | |
… | |
… | |
439 | ssize_t res; |
449 | ssize_t res; |
440 | |
450 | |
441 | if (!count) |
451 | if (!count) |
442 | return 0; |
452 | return 0; |
443 | |
453 | |
|
|
454 | LOCK_FD (ofd); |
|
|
455 | |
|
|
456 | #if HAVE_SENDFILE |
444 | #if __linux |
457 | # if __linux |
445 | res = sendfile (ofd, ifd, &offset, count); |
458 | res = sendfile (ofd, ifd, &offset, count); |
446 | |
459 | |
447 | #elif __freebsd |
460 | # elif __freebsd |
448 | /* |
461 | /* |
449 | * 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 |
450 | * wasted on making it similar to other i/o functions. |
463 | * wasted on making it similar to other I/O functions. |
451 | */ |
464 | */ |
452 | { |
465 | { |
453 | off_t sbytes; |
466 | off_t sbytes; |
454 | res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0); |
467 | res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0); |
455 | |
468 | |
456 | if (!res && errno == EAGAIN) |
469 | if (res < 0 && sbytes) |
457 | /* maybe on others, too, as usual, the manpage leaves you guessing */ |
470 | /* maybe only on EAGAIN only: as usual, the manpage leaves you guessing */ |
458 | res = sbytes; |
471 | res = sbytes; |
459 | } |
472 | } |
460 | |
473 | |
461 | #elif __hpux |
474 | # elif __hpux |
462 | res = sendfile (ofd, ifd, offset, count, 0, 0); |
475 | res = sendfile (ofd, ifd, offset, count, 0, 0); |
463 | |
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 | |
464 | #else |
493 | # else |
465 | res = -1; |
494 | res = -1; |
466 | errno = ENOSYS; |
495 | errno = ENOSYS; |
|
|
496 | # endif |
467 | #endif |
497 | #endif |
468 | |
498 | |
|
|
499 | if (res < 0 |
469 | 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 | ) |
470 | { |
506 | { |
471 | /* emulate sendfile. this is a major pain in the ass */ |
507 | /* emulate sendfile. this is a major pain in the ass */ |
472 | char *buf = malloc (4096); |
508 | char *buf = malloc (4096); |
473 | res = 0; |
509 | res = 0; |
474 | |
510 | |
… | |
… | |
500 | int errorno = errno; |
536 | int errorno = errno; |
501 | free (buf); |
537 | free (buf); |
502 | errno = errorno; |
538 | errno = errorno; |
503 | } |
539 | } |
504 | } |
540 | } |
|
|
541 | |
|
|
542 | UNLOCK_FD (ofd); |
505 | |
543 | |
506 | return res; |
544 | return res; |
507 | } |
545 | } |
508 | |
546 | |
509 | /*****************************************************************************/ |
547 | /*****************************************************************************/ |