rktio: further improve header declarations
Also, add variants of `rktio_read` and `rktio_write` that can be more convenient to use through an FFI.
This commit is contained in:
parent
316df0af7a
commit
990a1d7154
|
@ -1,10 +1,32 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
(require racket/cmdline
|
(require racket/cmdline
|
||||||
racket/pretty
|
racket/pretty
|
||||||
|
racket/list
|
||||||
|
racket/match
|
||||||
parser-tools/lex
|
parser-tools/lex
|
||||||
(prefix-in : parser-tools/lex-sre)
|
(prefix-in : parser-tools/lex-sre)
|
||||||
parser-tools/yacc)
|
parser-tools/yacc)
|
||||||
|
|
||||||
|
;; Parse "rktio.h" to produce a seqeuence
|
||||||
|
;; (define-constant <id> <const>) ...
|
||||||
|
;; <type-def> ...
|
||||||
|
;; <func-def> ...
|
||||||
|
;;
|
||||||
|
;; where
|
||||||
|
;; <type-def> = (define-type <id> <id>)
|
||||||
|
;; | (define-struct-type <id> ([<type> <name>] ...))
|
||||||
|
;;
|
||||||
|
;; <func-def> = (define-function <type> <id> ([<type> <arg-name>] ...))
|
||||||
|
;; => never fails
|
||||||
|
;; | (define-function/errno <err-v> <type> <id> ([<type> <arg-name>] ...))
|
||||||
|
;; => fails when result equals <err-v>
|
||||||
|
;; | (define-function/errno+step <err-v> <type> <id> ([<type> <arg-name>] ...))
|
||||||
|
;; => fails when result equals <err-v>, keep step
|
||||||
|
;;
|
||||||
|
;; <type> = <prim-type>
|
||||||
|
;; | (ref <type>) ; opaque, needs to be deallocated somehow
|
||||||
|
;; | (* <type>) ; transparent argument, can be represented by a byte string
|
||||||
|
|
||||||
(define output-file #f)
|
(define output-file #f)
|
||||||
|
|
||||||
(define input-file
|
(define input-file
|
||||||
|
@ -22,7 +44,7 @@
|
||||||
(define-empty-tokens delim-tokens
|
(define-empty-tokens delim-tokens
|
||||||
(EOF WHITESPACE
|
(EOF WHITESPACE
|
||||||
OPEN CLOSE COPEN CCLOSE SEMI COMMA STAR LSHIFT EQUAL
|
OPEN CLOSE COPEN CCLOSE SEMI COMMA STAR LSHIFT EQUAL
|
||||||
__RKTIO_H__ EXTERN EXTERN/NOERR EXTERN/STEP
|
__RKTIO_H__ EXTERN EXTERN/NOERR EXTERN/STEP EXTERN/ERR
|
||||||
DEFINE TYPEDEF ENUM STRUCT VOID UNSIGNED SHORT INT CONST))
|
DEFINE TYPEDEF ENUM STRUCT VOID UNSIGNED SHORT INT CONST))
|
||||||
|
|
||||||
(define lex
|
(define lex
|
||||||
|
@ -50,6 +72,7 @@
|
||||||
["RKTIO_EXTERN" 'EXTERN]
|
["RKTIO_EXTERN" 'EXTERN]
|
||||||
["RKTIO_EXTERN_NOERR" 'EXTERN/NOERR]
|
["RKTIO_EXTERN_NOERR" 'EXTERN/NOERR]
|
||||||
["RKTIO_EXTERN_STEP" 'EXTERN/STEP]
|
["RKTIO_EXTERN_STEP" 'EXTERN/STEP]
|
||||||
|
["RKTIO_EXTERN_ERR" 'EXTERN/ERR]
|
||||||
[(:seq (:or #\_ (:/ #\A #\Z #\a #\z))
|
[(:seq (:or #\_ (:/ #\A #\Z #\a #\z))
|
||||||
(:* (:or #\_ (:/ #\A #\Z #\a #\z #\0 #\9))))
|
(:* (:or #\_ (:/ #\A #\Z #\a #\z #\0 #\9))))
|
||||||
(token-ID (string->symbol lexeme))]
|
(token-ID (string->symbol lexeme))]
|
||||||
|
@ -77,11 +100,12 @@
|
||||||
(grammar
|
(grammar
|
||||||
(<prog> [() null]
|
(<prog> [() null]
|
||||||
[(<decl> <prog>) (cons $1 $2)])
|
[(<decl> <prog>) (cons $1 $2)])
|
||||||
(<decl> [(DEFINE ID <expr>) `(define ,$2 ,$3)]
|
(<decl> [(DEFINE ID <expr>) `(define-constant ,$2 ,$3)]
|
||||||
[(DEFINE __RKTIO_H__ <expr>) #f]
|
[(DEFINE __RKTIO_H__ <expr>) #f]
|
||||||
[(DEFINE EXTERN ID) #f]
|
[(DEFINE EXTERN ID) #f]
|
||||||
[(DEFINE EXTERN/NOERR EXTERN) #f]
|
[(DEFINE EXTERN/NOERR EXTERN) #f]
|
||||||
[(DEFINE EXTERN/STEP EXTERN) #f]
|
[(DEFINE EXTERN/STEP EXTERN) #f]
|
||||||
|
[(DEFINE EXTERN/ERR OPEN ID CLOSE EXTERN) #f]
|
||||||
[(STRUCT ID SEMI) #f]
|
[(STRUCT ID SEMI) #f]
|
||||||
[(TYPEDEF <type> <id> SEMI)
|
[(TYPEDEF <type> <id> SEMI)
|
||||||
(if (eq? $2 $3)
|
(if (eq? $2 $3)
|
||||||
|
@ -92,12 +116,14 @@
|
||||||
`(define-struct-type ,$2 ,$4)
|
`(define-struct-type ,$2 ,$4)
|
||||||
(error 'parse "typedef struct names don't match at ~s" $5))]
|
(error 'parse "typedef struct names don't match at ~s" $5))]
|
||||||
[(<extern> <return-type> <id> OPEN <params> SEMI)
|
[(<extern> <return-type> <id> OPEN <params> SEMI)
|
||||||
(let ([r-type (shift-stars $3 $2)])
|
(let ([r-type (shift-stars $3 $2)]
|
||||||
`(,(adjust-errno $1 r-type) ,r-type ,(unstar $3) ,$5))]
|
[id (unstar $3)])
|
||||||
|
`(,@(adjust-errno $1 r-type id) ,r-type ,id ,$5))]
|
||||||
[(ENUM COPEN <enumeration> SEMI) `(begin . ,(enum-definitions $3))])
|
[(ENUM COPEN <enumeration> SEMI) `(begin . ,(enum-definitions $3))])
|
||||||
(<extern> [(EXTERN) 'define-function/errno]
|
(<extern> [(EXTERN) 'define-function/errno]
|
||||||
[(EXTERN/STEP) 'define-function/errno+step]
|
[(EXTERN/STEP) 'define-function/errno+step]
|
||||||
[(EXTERN/NOERR) 'define-function])
|
[(EXTERN/NOERR) 'define-function]
|
||||||
|
[(EXTERN/ERR OPEN ID CLOSE) `(define-function/errno ,$3)])
|
||||||
(<params> [(VOID CLOSE) null]
|
(<params> [(VOID CLOSE) null]
|
||||||
[(<paramlist>) $1])
|
[(<paramlist>) $1])
|
||||||
(<paramlist> [(<type> <id> CLOSE) `((,(shift-stars $2 $1) ,(unstar $2)))]
|
(<paramlist> [(<type> <id> CLOSE) `((,(shift-stars $2 $1) ,(unstar $2)))]
|
||||||
|
@ -130,11 +156,15 @@
|
||||||
[(STRUCT ID) $2])
|
[(STRUCT ID) $2])
|
||||||
(<return-type> [(<type>) $1]))))
|
(<return-type> [(<type>) $1]))))
|
||||||
|
|
||||||
(define (adjust-errno def-kind r)
|
(define (adjust-errno def-kind r id)
|
||||||
(cond
|
(cond
|
||||||
[(eq? r 'rktio_bool_t) 'define-function]
|
[(eq? id 'rktio_init) '(define-function)] ; init is special, because we can't get an error
|
||||||
[(eq? r 'void) 'define-function]
|
[(eq? r 'rktio_bool_t) '(define-function)]
|
||||||
[else def-kind]))
|
[(eq? r 'void) '(define-function)]
|
||||||
|
[(pair? def-kind) def-kind]
|
||||||
|
[(pair? r) '(define-function/errno NULL)]
|
||||||
|
[(eq? r 'rktio_ok_t) '(define-function/errno #f)]
|
||||||
|
[else (list def-kind)]))
|
||||||
|
|
||||||
(define (shift-stars from to)
|
(define (shift-stars from to)
|
||||||
(if (and (pair? from)
|
(if (and (pair? from)
|
||||||
|
@ -155,16 +185,16 @@
|
||||||
[(pair? (car l))
|
[(pair? (car l))
|
||||||
(let ([i (cadar l)])
|
(let ([i (cadar l)])
|
||||||
(cons
|
(cons
|
||||||
`(define ,(caar l) ,i)
|
`(define-constant ,(caar l) ,i)
|
||||||
(loop (cdr l) (add1 i))))]
|
(loop (cdr l) (add1 i))))]
|
||||||
[else
|
[else
|
||||||
(cons
|
(cons
|
||||||
`(define ,(car l) ,i)
|
`(define-constant ,(car l) ,i)
|
||||||
(loop (cdr l) (add1 i)))])))
|
(loop (cdr l) (add1 i)))])))
|
||||||
|
|
||||||
;; ----------------------------------------
|
;; ----------------------------------------
|
||||||
|
|
||||||
(define content
|
(define unsorted-unflattened-content
|
||||||
(call-with-input-file input-file
|
(call-with-input-file input-file
|
||||||
(lambda (i)
|
(lambda (i)
|
||||||
(port-count-lines! i)
|
(port-count-lines! i)
|
||||||
|
@ -175,14 +205,84 @@
|
||||||
[(eq? (position-token-token v) 'WHITESPACE) (loop)]
|
[(eq? (position-token-token v) 'WHITESPACE) (loop)]
|
||||||
[else v]))))))))
|
[else v]))))))))
|
||||||
|
|
||||||
|
(define unsorted-content
|
||||||
|
(for*/list ([l (in-list unsorted-unflattened-content)]
|
||||||
|
[e (in-list (if (and (pair? l)
|
||||||
|
(eq? 'begin (car l)))
|
||||||
|
(cdr l)
|
||||||
|
(list l)))])
|
||||||
|
e))
|
||||||
|
|
||||||
|
(define (constant-defn? e)
|
||||||
|
(and (pair? e)
|
||||||
|
(eq? (car e) 'define-constant)))
|
||||||
|
|
||||||
|
(define (type-defn? e)
|
||||||
|
(and (pair? e)
|
||||||
|
(or (eq? (car e) 'define-type)
|
||||||
|
(eq? (car e) 'define-struct-type))))
|
||||||
|
|
||||||
|
(define constant-content
|
||||||
|
(filter constant-defn? unsorted-content))
|
||||||
|
|
||||||
|
(define type-content
|
||||||
|
(filter type-defn? unsorted-content))
|
||||||
|
|
||||||
|
(define defined-types
|
||||||
|
(let ([ht (for/hash ([e (in-list type-content)])
|
||||||
|
(values (cadr e) #t))])
|
||||||
|
(for/fold ([ht ht]) ([t (in-list '(char int unsigned-short
|
||||||
|
intptr_t rktio_int64_t))])
|
||||||
|
(hash-set ht t #t))))
|
||||||
|
|
||||||
|
;; A pointer to a defined type in an argument position
|
||||||
|
;; is transparent, and it make sense to pass a byte
|
||||||
|
;; string directly (possibly to be filled in).
|
||||||
|
;; A pointer to an undefined type is opaque, and a pointer
|
||||||
|
;; to a defined type is "opaque" in a result position in
|
||||||
|
;; the sense that it should be explicitly dereferenced and
|
||||||
|
;; explicitly freed.
|
||||||
|
(define (update-type t #:as-argument? [as-argument? #f])
|
||||||
|
(cond
|
||||||
|
[(and (pair? t) (eq? (car t) '*))
|
||||||
|
(let ([s (update-type (cadr t))])
|
||||||
|
(if (and as-argument?
|
||||||
|
(or (pair? s)
|
||||||
|
(hash-ref defined-types s #f)))
|
||||||
|
`(* ,s)
|
||||||
|
`(ref ,s)))]
|
||||||
|
[else t]))
|
||||||
|
|
||||||
|
(define (update-bind a #:as-argument? [as-argument? #f])
|
||||||
|
`(,(update-type (car a) #:as-argument? as-argument?) ,(cadr a)))
|
||||||
|
|
||||||
|
(define (update-types e)
|
||||||
|
(match e
|
||||||
|
[`(,def ,ret ,name ,args)
|
||||||
|
`(,def ,(update-type ret) ,name
|
||||||
|
,(map (lambda (a) (update-bind a #:as-argument? #t)) args))]
|
||||||
|
[else e]))
|
||||||
|
|
||||||
|
(define (update-type-types e)
|
||||||
|
(match e
|
||||||
|
[`(define-struct-type ,name ,fields)
|
||||||
|
`(define-struct-type ,name ,(map update-bind fields))]
|
||||||
|
[else e]))
|
||||||
|
|
||||||
|
(define content
|
||||||
|
(append
|
||||||
|
constant-content
|
||||||
|
(map update-type-types type-content)
|
||||||
|
(map update-types
|
||||||
|
(filter (lambda (e) (not (or (constant-defn? e) (type-defn? e))))
|
||||||
|
unsorted-content))))
|
||||||
|
|
||||||
(define (show-content)
|
(define (show-content)
|
||||||
|
(printf "(begin\n")
|
||||||
(for ([e (in-list content)]
|
(for ([e (in-list content)]
|
||||||
#:when e)
|
#:when e)
|
||||||
(if (and (pair? e)
|
|
||||||
(eq? 'begin (car e)))
|
|
||||||
(for ([e (in-list (cdr e))])
|
|
||||||
(pretty-write e))
|
(pretty-write e))
|
||||||
(pretty-write e))))
|
(printf ")\n"))
|
||||||
|
|
||||||
(if output-file
|
(if output-file
|
||||||
(with-output-to-file output-file
|
(with-output-to-file output-file
|
||||||
|
|
|
@ -30,9 +30,10 @@ Return type conventions:
|
||||||
- A return type `rktio_tri_t` (alias for `int`) means that 0 is
|
- A return type `rktio_tri_t` (alias for `int`) means that 0 is
|
||||||
returned for an expected failuree, some `RKTIO_...` (alias for 1)
|
returned for an expected failuree, some `RKTIO_...` (alias for 1)
|
||||||
is returned for success, and `RKTIO_...ERROR` (alias for -2) is
|
is returned for success, and `RKTIO_...ERROR` (alias for -2) is
|
||||||
returned for some error. Use `rktio_get_last_error_kind` and
|
returned for some error. The function will be annotated with
|
||||||
`rktio_get_last_error` for more information about a
|
`RKTIO_EXTERN_ERR(...)` to indicate the error value. Use
|
||||||
`RKTIO_...ERROR` result.
|
`rktio_get_last_error_kind` and `rktio_get_last_error` for more
|
||||||
|
information about a `RKTIO_...ERROR` result.
|
||||||
|
|
||||||
- A return type `rktio_bool_t` means that the result is a simple 0 or
|
- A return type `rktio_bool_t` means that the result is a simple 0 or
|
||||||
1, and no error is possible.
|
1, and no error is possible.
|
||||||
|
@ -82,6 +83,7 @@ Thread and signal conventions:
|
||||||
# define RKTIO_EXTERN extern
|
# define RKTIO_EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define RKTIO_EXTERN_ERR(n) RKTIO_EXTERN
|
||||||
#define RKTIO_EXTERN_NOERR RKTIO_EXTERN
|
#define RKTIO_EXTERN_NOERR RKTIO_EXTERN
|
||||||
#define RKTIO_EXTERN_STEP RKTIO_EXTERN
|
#define RKTIO_EXTERN_STEP RKTIO_EXTERN
|
||||||
|
|
||||||
|
@ -95,7 +97,9 @@ typedef struct rktio_t rktio_t;
|
||||||
RKTIO_EXTERN rktio_t *rktio_init(void);
|
RKTIO_EXTERN rktio_t *rktio_init(void);
|
||||||
/* Call `rktio_init` before anything else. The first call to
|
/* Call `rktio_init` before anything else. The first call to
|
||||||
`rktio_init` must return before any additional calls (in other
|
`rktio_init` must return before any additional calls (in other
|
||||||
threads), but there's no ordering requirement after that. */
|
threads), but there's no ordering requirement after that.
|
||||||
|
If the result is NULL, then there's no way to get an error
|
||||||
|
code, so assume `RKTIO_ERROR_INIT_FAILED`. */
|
||||||
|
|
||||||
RKTIO_EXTERN void rktio_destroy(rktio_t *rktio);
|
RKTIO_EXTERN void rktio_destroy(rktio_t *rktio);
|
||||||
/* Call `rktio_destroy` as the last thing. Everything else must be
|
/* Call `rktio_destroy` as the last thing. Everything else must be
|
||||||
|
@ -232,7 +236,8 @@ RKTIO_EXTERN rktio_fd_t *rktio_std_fd(rktio_t *rktio, int which);
|
||||||
#define RKTIO_STDOUT 1
|
#define RKTIO_STDOUT 1
|
||||||
#define RKTIO_STDERR 2
|
#define RKTIO_STDERR 2
|
||||||
|
|
||||||
RKTIO_EXTERN intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len);
|
RKTIO_EXTERN_ERR(RKTIO_READ_ERROR)
|
||||||
|
intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len);
|
||||||
/* Returns the number of bytes read, possibly 0, in non-blocking mode.
|
/* Returns the number of bytes read, possibly 0, in non-blocking mode.
|
||||||
Alternatively, the result can be `RKTIO_READ_EOF` for end-of-file
|
Alternatively, the result can be `RKTIO_READ_EOF` for end-of-file
|
||||||
or `RKTIO_READ_ERROR` for an error. Although rktio_read is intended
|
or `RKTIO_READ_ERROR` for an error. Although rktio_read is intended
|
||||||
|
@ -242,7 +247,8 @@ RKTIO_EXTERN intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *fd, char *buffer, i
|
||||||
#define RKTIO_READ_EOF (-1)
|
#define RKTIO_READ_EOF (-1)
|
||||||
#define RKTIO_READ_ERROR (-2)
|
#define RKTIO_READ_ERROR (-2)
|
||||||
|
|
||||||
RKTIO_EXTERN intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *fd, const char *buffer, intptr_t len);
|
RKTIO_EXTERN_ERR(RKTIO_WRITE_ERROR)
|
||||||
|
intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *fd, const char *buffer, intptr_t len);
|
||||||
/* Returns the number of bytes written, possibly 0, in non-blocking
|
/* Returns the number of bytes written, possibly 0, in non-blocking
|
||||||
mode. Alternatively, the result can be `RKTIO_WRITE_ERROR` for an
|
mode. Alternatively, the result can be `RKTIO_WRITE_ERROR` for an
|
||||||
error. Although `rktio_write` is intended to write only bytes that
|
error. Although `rktio_write` is intended to write only bytes that
|
||||||
|
@ -253,32 +259,45 @@ RKTIO_EXTERN intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *fd, const char *bu
|
||||||
|
|
||||||
#define RKTIO_WRITE_ERROR (-2)
|
#define RKTIO_WRITE_ERROR (-2)
|
||||||
|
|
||||||
RKTIO_EXTERN intptr_t rktio_read_converted(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len,
|
RKTIO_EXTERN_ERR(RKTIO_READ_ERROR)
|
||||||
|
intptr_t rktio_read_converted(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len,
|
||||||
char *is_converted);
|
char *is_converted);
|
||||||
/* Like `rktio_read`, but also reports whether each character was
|
/* Like `rktio_read`, but also reports whether each character was
|
||||||
originally two characters that were converted to a single newline for
|
originally two characters that were converted to a single newline for
|
||||||
text mode. */
|
text mode. */
|
||||||
|
|
||||||
|
RKTIO_EXTERN_ERR(RKTIO_READ_ERROR)
|
||||||
|
intptr_t rktio_read_in(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t start, intptr_t end);
|
||||||
|
RKTIO_EXTERN_ERR(RKTIO_WRITE_ERROR)
|
||||||
|
intptr_t rktio_write_in(rktio_t *rktio, rktio_fd_t *fd, const char *buffer, intptr_t start, intptr_t end);
|
||||||
|
/* Like `rktio_read` and `rktio_write`, but accepting start and end
|
||||||
|
positions within `buffer`. */
|
||||||
|
|
||||||
RKTIO_EXTERN_NOERR intptr_t rktio_buffered_byte_count(rktio_t *rktio, rktio_fd_t *fd);
|
RKTIO_EXTERN_NOERR intptr_t rktio_buffered_byte_count(rktio_t *rktio, rktio_fd_t *fd);
|
||||||
/* Reports the number of bytes that are buffered from the file descriptor.
|
/* Reports the number of bytes that are buffered from the file descriptor.
|
||||||
The result is normally zero, but text-mode conversion and the rare
|
The result is normally zero, but text-mode conversion and the rare
|
||||||
uncooperative corner of an OS can make the result 1 byte. */
|
uncooperative corner of an OS can make the result 1 byte. */
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_poll_read_ready(rktio_t *rktio, rktio_fd_t *rfd);
|
RKTIO_EXTERN_ERR(RKTIO_POLL_ERROR)
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_poll_write_ready(rktio_t *rktio, rktio_fd_t *rfd);
|
rktio_tri_t rktio_poll_read_ready(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
|
RKTIO_EXTERN_ERR(RKTIO_POLL_ERROR)
|
||||||
|
rktio_tri_t rktio_poll_write_ready(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
/* Each polling function returns one of the following: */
|
/* Each polling function returns one of the following: */
|
||||||
#define RKTIO_POLL_NOT_READY 0
|
#define RKTIO_POLL_NOT_READY 0
|
||||||
#define RKTIO_POLL_READY 1
|
#define RKTIO_POLL_READY 1
|
||||||
#define RKTIO_POLL_ERROR (-2)
|
#define RKTIO_POLL_ERROR (-2)
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_poll_write_flushed(rktio_t *rktio, rktio_fd_t *rfd);
|
RKTIO_EXTERN_ERR(RKTIO_POLL_ERROR)
|
||||||
|
rktio_tri_t rktio_poll_write_flushed(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
/* See `rktio_write` above. Currently, the result is `RKTIO_POLL_NO_READY`
|
/* See `rktio_write` above. Currently, the result is `RKTIO_POLL_NO_READY`
|
||||||
only on Windows, and only for a pipe or similar non-regular file.
|
only on Windows, and only for a pipe or similar non-regular file.
|
||||||
A pipe counts as "flushed" when the other end has received the data
|
A pipe counts as "flushed" when the other end has received the data
|
||||||
(because the sent data doesn't persist beyond closing the pipe). */
|
(because the sent data doesn't persist beyond closing the pipe). */
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_file_lock_try(rktio_t *rktio, rktio_fd_t *rfd, int excl);
|
RKTIO_EXTERN_ERR(RKTIO_LOCK_ERROR)
|
||||||
RKTIO_EXTERN rktio_ok_t rktio_file_unlock(rktio_t *rktio, rktio_fd_t *rfd);
|
rktio_tri_t rktio_file_lock_try(rktio_t *rktio, rktio_fd_t *rfd, int excl);
|
||||||
|
RKTIO_EXTERN_ERR(RKTIO_LOCK_ERROR)
|
||||||
|
rktio_ok_t rktio_file_unlock(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
/* Advisory file locks, where `excl` attempts to claim an exclusive
|
/* Advisory file locks, where `excl` attempts to claim an exclusive
|
||||||
lock. Whether these work in various situations depend on many OS
|
lock. Whether these work in various situations depend on many OS
|
||||||
details, where the differences involve promoting from non-exlcusive
|
details, where the differences involve promoting from non-exlcusive
|
||||||
|
@ -335,7 +354,8 @@ RKTIO_EXTERN rktio_addrinfo_lookup_t *rktio_start_addrinfo_lookup(rktio_t *rktio
|
||||||
#define RKTIO_FAMILY_ANY (-1)
|
#define RKTIO_FAMILY_ANY (-1)
|
||||||
RKTIO_EXTERN_NOERR int rktio_get_ipv4_family(rktio_t *rktio);
|
RKTIO_EXTERN_NOERR int rktio_get_ipv4_family(rktio_t *rktio);
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_poll_addrinfo_lookup_ready(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
|
RKTIO_EXTERN_ERR(RKTIO_POLL_ERROR)
|
||||||
|
rktio_tri_t rktio_poll_addrinfo_lookup_ready(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
|
||||||
/* Check whether an address is available for a lookup request. */
|
/* Check whether an address is available for a lookup request. */
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_addrinfo_t *rktio_addrinfo_lookup_get(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
|
RKTIO_EXTERN rktio_addrinfo_t *rktio_addrinfo_lookup_get(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
|
||||||
|
@ -358,7 +378,8 @@ RKTIO_EXTERN rktio_listener_t *rktio_listen(rktio_t *rktio, rktio_addrinfo_t *lo
|
||||||
RKTIO_EXTERN void rktio_listen_stop(rktio_t *rktio, rktio_listener_t *l);
|
RKTIO_EXTERN void rktio_listen_stop(rktio_t *rktio, rktio_listener_t *l);
|
||||||
/* Stops a listener. */
|
/* Stops a listener. */
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_poll_accept_ready(rktio_t *rktio, rktio_listener_t *listener);
|
RKTIO_EXTERN_ERR(RKTIO_POLL_ERROR)
|
||||||
|
rktio_tri_t rktio_poll_accept_ready(rktio_t *rktio, rktio_listener_t *listener);
|
||||||
/* Returns one of `RKTIO_POLL_READY`, etc. */
|
/* Returns one of `RKTIO_POLL_READY`, etc. */
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_fd_t *rktio_accept(rktio_t *rktio, rktio_listener_t *listener);
|
RKTIO_EXTERN rktio_fd_t *rktio_accept(rktio_t *rktio, rktio_listener_t *listener);
|
||||||
|
@ -377,7 +398,8 @@ RKTIO_EXTERN rktio_fd_t *rktio_connect_finish(rktio_t *rktio, rktio_connect_t *c
|
||||||
RKTIO_EXTERN void rktio_connect_stop(rktio_t *rktio, rktio_connect_t *conn);
|
RKTIO_EXTERN void rktio_connect_stop(rktio_t *rktio, rktio_connect_t *conn);
|
||||||
/* Stops a connection whose result or error has not been received. */
|
/* Stops a connection whose result or error has not been received. */
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_poll_connect_ready(rktio_t *rktio, rktio_connect_t *conn);
|
RKTIO_EXTERN_ERR(RKTIO_POLL_ERROR)
|
||||||
|
rktio_tri_t rktio_poll_connect_ready(rktio_t *rktio, rktio_connect_t *conn);
|
||||||
/* Returns one of `RKTIO_POLL_READY`, etc. */
|
/* Returns one of `RKTIO_POLL_READY`, etc. */
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_fd_t *rktio_connect_trying(rktio_t *rktio, rktio_connect_t *conn);
|
RKTIO_EXTERN rktio_fd_t *rktio_connect_trying(rktio_t *rktio, rktio_connect_t *conn);
|
||||||
|
@ -405,7 +427,8 @@ RKTIO_EXTERN rktio_ok_t rktio_udp_bind(rktio_t *rktio, rktio_fd_t *rfd, rktio_ad
|
||||||
rktio_bool_t reuse);
|
rktio_bool_t reuse);
|
||||||
RKTIO_EXTERN rktio_ok_t rktio_udp_connect(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr);
|
RKTIO_EXTERN rktio_ok_t rktio_udp_connect(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr);
|
||||||
|
|
||||||
RKTIO_EXTERN intptr_t rktio_udp_sendto(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr,
|
RKTIO_EXTERN_ERR(RKTIO_WRITE_ERROR)
|
||||||
|
intptr_t rktio_udp_sendto(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr,
|
||||||
const char *buffer, intptr_t len);
|
const char *buffer, intptr_t len);
|
||||||
/* Extends `rktio_write` to accept a destination `addr`, and binds `rfd` if it
|
/* Extends `rktio_write` to accept a destination `addr`, and binds `rfd` if it
|
||||||
is not bound aready. The `addr` can be NULL if the socket is connected. */
|
is not bound aready. The `addr` can be NULL if the socket is connected. */
|
||||||
|
@ -421,10 +444,9 @@ RKTIO_EXTERN rktio_length_and_addrinfo_t *rktio_udp_recvfrom(rktio_t *rktio, rkt
|
||||||
be `RKTIO_ERROR_TRY_AGAIN` or `RKTIO_ERROR_INFO_TRY_AGAIN`, where
|
be `RKTIO_ERROR_TRY_AGAIN` or `RKTIO_ERROR_INFO_TRY_AGAIN`, where
|
||||||
the latter can happen if the sock claims to be ready to read. */
|
the latter can happen if the sock claims to be ready to read. */
|
||||||
|
|
||||||
/* The following accessors return `RKTIO_PROP_ERROR` on failure */
|
RKTIO_EXTERN_ERR(RKTIO_PROP_ERROR) rktio_tri_t rktio_udp_get_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_udp_get_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd);
|
|
||||||
RKTIO_EXTERN rktio_ok_t rktio_udp_set_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd, rktio_bool_t on);
|
RKTIO_EXTERN rktio_ok_t rktio_udp_set_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd, rktio_bool_t on);
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_udp_get_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd);
|
RKTIO_EXTERN_ERR(RKTIO_PROP_ERROR) rktio_tri_t rktio_udp_get_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd);
|
||||||
RKTIO_EXTERN rktio_ok_t rktio_udp_set_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd, int ttl_val);
|
RKTIO_EXTERN rktio_ok_t rktio_udp_set_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd, int ttl_val);
|
||||||
|
|
||||||
#define RKTIO_PROP_ERROR (-2)
|
#define RKTIO_PROP_ERROR (-2)
|
||||||
|
@ -487,7 +509,7 @@ RKTIO_EXTERN char *rktio_envvars_get(rktio_t *rktio, rktio_envvars_t *envvars, c
|
||||||
RKTIO_EXTERN void rktio_envvars_set(rktio_t *rktio, rktio_envvars_t *envvars, const char *name, const char *value);
|
RKTIO_EXTERN void rktio_envvars_set(rktio_t *rktio, rktio_envvars_t *envvars, const char *name, const char *value);
|
||||||
/* Access/update environment-variables record by name. */
|
/* Access/update environment-variables record by name. */
|
||||||
|
|
||||||
RKTIO_EXTERN intptr_t rktio_envvars_count(rktio_t *rktio, rktio_envvars_t *envvars);
|
RKTIO_EXTERN_NOERR intptr_t rktio_envvars_count(rktio_t *rktio, rktio_envvars_t *envvars);
|
||||||
RKTIO_EXTERN char *rktio_envvars_name_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
|
RKTIO_EXTERN char *rktio_envvars_name_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
|
||||||
RKTIO_EXTERN char *rktio_envvars_value_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
|
RKTIO_EXTERN char *rktio_envvars_value_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
|
||||||
/* Access/update environment-variables record by index. */
|
/* Access/update environment-variables record by index. */
|
||||||
|
@ -576,7 +598,8 @@ RKTIO_EXTERN rktio_fs_change_t *rktio_fs_change(rktio_t *rktio, const char *path
|
||||||
|
|
||||||
RKTIO_EXTERN void rktio_fs_change_forget(rktio_t *rktio, rktio_fs_change_t *fc);
|
RKTIO_EXTERN void rktio_fs_change_forget(rktio_t *rktio, rktio_fs_change_t *fc);
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_tri_t rktio_poll_fs_change_ready(rktio_t *rktio, rktio_fs_change_t *fc);
|
RKTIO_EXTERN_ERR(RKTIO_POLL_ERROR)
|
||||||
|
rktio_tri_t rktio_poll_fs_change_ready(rktio_t *rktio, rktio_fs_change_t *fc);
|
||||||
/* Returns one of `RKTIO_POLL_READY`, etc. */
|
/* Returns one of `RKTIO_POLL_READY`, etc. */
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
|
@ -703,7 +726,7 @@ RKTIO_EXTERN rktio_bool_t rktio_directory_exists(rktio_t *rktio, const char *dir
|
||||||
RKTIO_EXTERN rktio_bool_t rktio_link_exists(rktio_t *rktio, const char *filename);
|
RKTIO_EXTERN rktio_bool_t rktio_link_exists(rktio_t *rktio, const char *filename);
|
||||||
RKTIO_EXTERN rktio_bool_t rktio_is_regular_file(rktio_t *rktio, const char *filename);
|
RKTIO_EXTERN rktio_bool_t rktio_is_regular_file(rktio_t *rktio, const char *filename);
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_ok_t rktio_delete_file(rktio_t *rktio, const char *fn, int enable_write_on_fail);
|
RKTIO_EXTERN rktio_ok_t rktio_delete_file(rktio_t *rktio, const char *fn, rktio_bool_t enable_write_on_fail);
|
||||||
|
|
||||||
RKTIO_EXTERN rktio_ok_t rktio_rename_file(rktio_t *rktio, const char *dest, const char *src, int exists_ok);
|
RKTIO_EXTERN rktio_ok_t rktio_rename_file(rktio_t *rktio, const char *dest, const char *src, int exists_ok);
|
||||||
/* Can report `RKTIO_ERROR_EXISTS`. */
|
/* Can report `RKTIO_ERROR_EXISTS`. */
|
||||||
|
@ -757,7 +780,8 @@ RKTIO_EXTERN rktio_identity_t *rktio_path_identity(rktio_t *rktio, const char *p
|
||||||
|
|
||||||
#define RKTIO_PERMISSION_ERROR (-1)
|
#define RKTIO_PERMISSION_ERROR (-1)
|
||||||
|
|
||||||
RKTIO_EXTERN int rktio_get_file_or_directory_permissions(rktio_t *rktio, const char *filename, int all_bits);
|
RKTIO_EXTERN_ERR(RKTIO_PERMISSION_ERROR)
|
||||||
|
int rktio_get_file_or_directory_permissions(rktio_t *rktio, const char *filename, int all_bits);
|
||||||
/* Result is `RKTIO_PERMISSION_ERROR` for error, otherwise a combination of
|
/* Result is `RKTIO_PERMISSION_ERROR` for error, otherwise a combination of
|
||||||
bits. If not `all_bits`, then use constants above. */
|
bits. If not `all_bits`, then use constants above. */
|
||||||
|
|
||||||
|
@ -973,7 +997,8 @@ RKTIO_EXTERN rktio_converter_t *rktio_converter_open(rktio_t *rktio, const char
|
||||||
RKTIO_EXTERN void rktio_converter_close(rktio_t *rktio, rktio_converter_t *cvt);
|
RKTIO_EXTERN void rktio_converter_close(rktio_t *rktio, rktio_converter_t *cvt);
|
||||||
/* Destroys an encoding converter. */
|
/* Destroys an encoding converter. */
|
||||||
|
|
||||||
RKTIO_EXTERN intptr_t rktio_convert(rktio_t *rktio,
|
RKTIO_EXTERN_ERR(RKTIO_CONVERT_ERROR)
|
||||||
|
intptr_t rktio_convert(rktio_t *rktio,
|
||||||
rktio_converter_t *cvt,
|
rktio_converter_t *cvt,
|
||||||
char **in, intptr_t *in_left,
|
char **in, intptr_t *in_left,
|
||||||
char **out, intptr_t *out_left);
|
char **out, intptr_t *out_left);
|
||||||
|
@ -1005,12 +1030,12 @@ RKTIO_EXTERN rktio_char16_t *rktio_recase_utf16(rktio_t *rktio,
|
||||||
Takes and optionally returns a length (`olen` can be NULL), but the
|
Takes and optionally returns a length (`olen` can be NULL), but the
|
||||||
UTF-16 sequence is expected to have no nuls. */
|
UTF-16 sequence is expected to have no nuls. */
|
||||||
|
|
||||||
RKTIO_EXTERN int rktio_locale_strcoll(rktio_t *rktio, char *s1, char *s2);
|
RKTIO_EXTERN_NOERR int rktio_locale_strcoll(rktio_t *rktio, char *s1, char *s2);
|
||||||
/* Returns -1 if `s1` is less than `s2` by the current locale's
|
/* Returns -1 if `s1` is less than `s2` by the current locale's
|
||||||
comparison, positive is `s1` is greater, and 0 if the strings
|
comparison, positive is `s1` is greater, and 0 if the strings
|
||||||
are equal. */
|
are equal. */
|
||||||
|
|
||||||
RKTIO_EXTERN int rktio_strcoll_utf16(rktio_t *rktio,
|
RKTIO_EXTERN_NOERR int rktio_strcoll_utf16(rktio_t *rktio,
|
||||||
rktio_char16_t *s1, intptr_t l1,
|
rktio_char16_t *s1, intptr_t l1,
|
||||||
rktio_char16_t *s2, intptr_t l2,
|
rktio_char16_t *s2, intptr_t l2,
|
||||||
rktio_bool_t cvt_case);
|
rktio_bool_t cvt_case);
|
||||||
|
|
|
@ -853,6 +853,16 @@ intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len)
|
||||||
return rktio_read_converted(rktio, rfd, buffer, len, NULL);
|
return rktio_read_converted(rktio, rfd, buffer, len, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intptr_t rktio_read_in(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t start, intptr_t end)
|
||||||
|
{
|
||||||
|
return rktio_read_converted(rktio, rfd, buffer+start, end-start, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
intptr_t rktio_write_in(rktio_t *rktio, rktio_fd_t *rfd, const char *buffer, intptr_t start, intptr_t end)
|
||||||
|
{
|
||||||
|
return rktio_write(rktio, rfd, buffer+start, end-start);
|
||||||
|
}
|
||||||
|
|
||||||
RKTIO_EXTERN intptr_t rktio_buffered_byte_count(rktio_t *rktio, rktio_fd_t *fd)
|
RKTIO_EXTERN intptr_t rktio_buffered_byte_count(rktio_t *rktio, rktio_fd_t *fd)
|
||||||
{
|
{
|
||||||
#ifdef RKTIO_SYSTEM_UNIX
|
#ifdef RKTIO_SYSTEM_UNIX
|
||||||
|
|
Loading…
Reference in New Issue
Block a user