1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* bstack — persistent, fsync-durable binary stack backed by a single file.
*
* File format (16-byte header followed by payload):
* [0..8) magic: "BSTK" + major(1) + minor(1) + patch(1) + reserved(1)
* [8..16) committed payload length, little-endian uint64
* [16..) payload bytes
*
* All logical offsets are 0-based from the start of the payload region.
*
* Error handling
* --------------
* bstack_open returns NULL on failure; errno is set by the failing syscall,
* or to EINVAL for bad/short headers, or to EWOULDBLOCK when
* another process holds the exclusive lock.
* All other functions return 0 on success, -1 on failure with errno set.
*
* Thread safety
* -------------
* A pthread_rwlock protects each handle. bstack_push / bstack_pop /
* bstack_set hold a write lock; bstack_peek / bstack_get / bstack_len hold
* a read lock and may run concurrently with each other.
*
* Multi-process safety
* --------------------
* bstack_open acquires an exclusive advisory flock(LOCK_EX|LOCK_NB).
* The lock is released when bstack_close is called (fd is closed).
*
* Feature flags
* -------------
* Compile with -DBSTACK_FEATURE_SET to enable bstack_set.
*/
typedef struct bstack bstack_t;
/* Open or create a stack file at path. Returns NULL on failure (errno set). */
bstack_t *;
/* Close the handle and release all resources (flock, rwlock, fd, memory). */
void ;
/*
* Append len bytes from data to the stack.
* If out_offset is non-NULL it receives the logical byte offset where data
* begins (i.e. the payload size before the write).
* An empty slice (len == 0) is valid and returns the current end offset.
*/
int ;
/*
* Remove and copy the last n bytes of the stack into buf.
* The caller must ensure buf has room for n bytes; no overflow check is done.
* If written is non-NULL it receives n on success.
* Returns EINVAL if n exceeds the current payload size.
*/
int ;
/*
* Copy bytes from logical offset to end-of-payload into buf.
* The caller must ensure buf is large enough; no overflow check is done.
* If written is non-NULL it receives the number of bytes copied.
* offset == bstack_len is valid and copies 0 bytes.
* Returns EINVAL if offset exceeds the payload size.
*/
int ;
/*
* Copy the half-open logical byte range [start, end) into buf.
* The caller must ensure buf has room for (end - start) bytes.
* Returns EINVAL if end < start or end exceeds the payload size.
*/
int ;
/*
* Write the current logical payload size (excluding the 16-byte header)
* into *out_len. Takes the read lock; concurrent calls are allowed.
*/
int ;
/*
* Overwrite len bytes in place starting at logical offset.
* The file size is never changed. An empty slice is a valid no-op.
* Returns EINVAL if offset + len would exceed the payload size or overflow
* uint64_t.
*
* Only available when compiled with -DBSTACK_FEATURE_SET.
*/
int ;
/* BSTACK_FEATURE_SET */
/* BSTACK_H */