mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 05:39:18 +02:00
Adding initial send-file interface.
This commit is contained in:
parent
a32edf7138
commit
7a27341ecd
5 changed files with 52 additions and 1 deletions
|
@ -641,6 +641,10 @@
|
|||
#define SEXP_USE_MAIN_HELP ! SEXP_USE_NO_FEATURES
|
||||
#endif
|
||||
|
||||
#ifndef SEXP_USE_SEND_FILE
|
||||
#define SEXP_USE_SEND_FILE (!defined(_WIN32) && !defined(PLAN9))
|
||||
#endif
|
||||
|
||||
#if SEXP_USE_NATIVE_X86
|
||||
#undef SEXP_USE_BOEHM
|
||||
#define SEXP_USE_BOEHM 1
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
make-filtered-input-port string-count
|
||||
open-input-bytevector open-output-bytevector get-output-bytevector
|
||||
string->utf8 utf8->string
|
||||
write-string write-u8 read-u8 peek-u8)
|
||||
write-string write-u8 read-u8 peek-u8 send-file
|
||||
is-a-socket?)
|
||||
(import (chibi) (chibi ast))
|
||||
(include-shared "io/io")
|
||||
(include "io/io.scm"))
|
||||
|
|
|
@ -164,6 +164,27 @@
|
|||
(port-line-set! in (+ (string-count #\newline str 0 n) (port-line in)))
|
||||
res))
|
||||
|
||||
;;> Sends the entire contents of a file or input port to an output port.
|
||||
|
||||
(define (send-file fd-port-or-filename . o)
|
||||
(let* ((in (if (string? fd-port-or-filename)
|
||||
(open-input-file fd-port-or-filename)
|
||||
fd-port-or-filename))
|
||||
(out (if (pair? o) (car o) (current-output-port)))
|
||||
(fd (if (port? in) (port-fileno in) in))
|
||||
(sock (if (port? out) (port-fileno out) out)))
|
||||
(if (and fd sock (is-a-socket? sock))
|
||||
(let lp ((start 0))
|
||||
(let ((res (%send-file fd sock start)))
|
||||
(cond
|
||||
((not res) (lp start))
|
||||
((not (zero? res)) (lp (+ start res))))))
|
||||
(let lp ()
|
||||
(let ((str (read-string 8192 in)))
|
||||
(cond ((not (eof-object? str))
|
||||
(display str out)
|
||||
(lp))))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; higher order port operations
|
||||
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
|
||||
(c-include "port.c")
|
||||
|
||||
(define-c boolean (is-a-socket? "sexp_is_a_socket_p") (fileno))
|
||||
|
||||
(define-c errno (%send-file "sexp_send_file")
|
||||
(fileno fileno off_t (default 0 off_t) (result off_t)))
|
||||
|
||||
(define-c sexp (%make-custom-input-port "sexp_make_custom_input_port")
|
||||
((value ctx sexp) (value self sexp) sexp sexp sexp))
|
||||
|
||||
|
|
|
@ -375,3 +375,23 @@ sexp sexp_peek_u8 (sexp ctx, sexp self, sexp in) {
|
|||
sexp_push_char(ctx, sexp_unbox_fixnum(res), in);
|
||||
return res;
|
||||
}
|
||||
|
||||
int sexp_is_a_socket_p (int fd) {
|
||||
#if defined(PLAN9) || defined(_WIN32)
|
||||
return 0;
|
||||
#else
|
||||
struct stat statbuf;
|
||||
fstat(fd, &statbuf);
|
||||
return S_ISSOCK(statbuf.st_mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
int sexp_send_file (int fd, int s, off_t offset, off_t len, off_t* res) {
|
||||
#if SEXP_USE_SEND_FILE
|
||||
*res = len;
|
||||
return sendfile(fd, s, offset, res, NULL, 0);
|
||||
#else
|
||||
*res = 0;
|
||||
return 22; /* EINVAL */
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue