Skip to content

Commit 9698d47

Browse files
committed
Chez Scheme: allowing loading from input paths that do not support seeking
Based on the approach by @rmolives in cisco/ChezScheme#966
1 parent 0f2c8df commit 9698d47

File tree

6 files changed

+33
-1
lines changed

6 files changed

+33
-1
lines changed

racket/src/ChezScheme/c/externs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ extern ptr S_put_byte(ptr file, INT byte, IBOOL gzflag);
266266

267267
extern ptr S_get_fd_pos(ptr file, IBOOL gzflag);
268268
extern ptr S_set_fd_pos(ptr file, ptr pos, IBOOL gzflag);
269+
extern ptr S_fd_can_set_pos(ptr file);
269270
extern ptr S_get_fd_non_blocking(ptr file, IBOOL gzflag);
270271
extern ptr S_set_fd_non_blocking(ptr file, IBOOL x, IBOOL gzflag);
271272
extern ptr S_get_fd_length(ptr file, IBOOL gzflag);

racket/src/ChezScheme/c/new-io.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,20 @@ ptr S_set_fd_pos(ptr file, ptr pos, IBOOL gzflag) {
703703
}
704704
}
705705

706+
ptr S_fd_can_set_pos(ptr file) {
707+
OFF_T offset = LSEEK(GET_FD(file), 0, SEEK_CUR);
708+
709+
if (offset != -1) {
710+
if (LSEEK(GET_FD(file), offset, SEEK_SET) == offset)
711+
return Strue;
712+
}
713+
714+
if (errno == ESPIPE)
715+
return Sfalse;
716+
717+
return S_strerror(errno);
718+
}
719+
706720
ptr S_get_fd_non_blocking(WIN32_UNUSED ptr file, WIN32_UNUSED IBOOL gzflag) {
707721
#ifdef WIN32
708722
return Sfalse;

racket/src/ChezScheme/c/prim5.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,6 +1828,7 @@ void S_prim5_init(void) {
18281828
Sforeign_symbol("(cs)put_byte", (void*)S_put_byte);
18291829
Sforeign_symbol("(cs)get_fd_pos", (void*)S_get_fd_pos);
18301830
Sforeign_symbol("(cs)set_fd_pos", (void*)S_set_fd_pos);
1831+
Sforeign_symbol("(cs)fd_can_set_position", (void*)S_fd_can_set_pos);
18311832
Sforeign_symbol("(cs)get_fd_non_blocking", (void*)S_get_fd_non_blocking);
18321833
Sforeign_symbol("(cs)set_fd_non_blocking", (void*)S_set_fd_non_blocking);
18331834
Sforeign_symbol("(cs)get_fd_length", (void*)S_get_fd_length);

racket/src/ChezScheme/s/7.ss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,12 @@
305305
(lambda (x) (run-outer x)))
306306

307307
(define (do-load who fn situation for-import? importer ksrc)
308-
(let ([ip ($open-file-input-port who fn)])
308+
(let* ([file-ip ($open-file-input-port who fn)]
309+
[ip (if ($fd-input-port-can-set-position? file-ip)
310+
file-ip
311+
(let ([bv-ip (open-bytevector-input-port (get-bytevector-all file-ip))])
312+
(close-port file-ip)
313+
bv-ip))])
309314
(on-reset (close-port ip)
310315
(let ([fp (let ([start-pos (port-position ip)])
311316
(if (and (eqv? (get-u8 ip) (char->integer #\#))

racket/src/ChezScheme/s/io.ss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ implementation notes:
310310
(define $get-fd-pos
311311
(foreign-procedure "(cs)get_fd_pos"
312312
(scheme-object boolean) scheme-object))
313+
(define $fd-can-set-position
314+
(foreign-procedure "(cs)fd_can_set_position"
315+
(scheme-object) scheme-object))
313316
(define $get-fd-nonblocking
314317
(foreign-procedure "(cs)get_fd_non_blocking"
315318
(scheme-object boolean) scheme-object))
@@ -3259,6 +3262,13 @@ implementation notes:
32593262
(transcoded-port binary-port maybe-transcoder)
32603263
binary-port))]))
32613264

3265+
(set-who! $fd-input-port-can-set-position?
3266+
(lambda (ip)
3267+
(let ([r ($fd-can-set-position ($port-info ip))])
3268+
(if (boolean? r)
3269+
r
3270+
(port-oops who ip r)))))
3271+
32623272
(let ()
32633273
(define s-process (foreign-procedure "(cs)s_process" (string boolean) scheme-object))
32643274
(define (subprocess-port who what fd pid b-mode maybe-transcoder)

racket/src/ChezScheme/s/primdata.ss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,7 @@
20162016
($fasl-table [flags single-valued])
20172017
($fasl-to-vfasl [flags single-valued])
20182018
($fasl-wrf-graph [flags single-valued])
2019+
($fd-input-port-can-set-position? [flags single-valued])
20192020
($filter-conv [flags single-valued])
20202021
($filter-foreign-type [flags single-valued])
20212022
($fixed-path? [sig [(string) -> (boolean)]] [flags pure safeongoodargs])

0 commit comments

Comments
 (0)