> ## Documentation Index
> Fetch the complete documentation index at: https://zinc.ossl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# C ABI Reference

> The complete specification of the C ABI surface that all language adapters call

The C ABI is the contract between the Rust core and every language adapter. It is defined by `include/zinc.h`, which is generated by cbindgen during the core build. Never edit this header by hand.

## Types

```c theme={null}
typedef void *ZincHandle;
```

`ZincHandle` is an opaque pointer to an internal `SharedRegion` object. It is created by `zinc_create` or `zinc_open`, passed by value to all other functions, and freed by `zinc_close`. A null handle is safe to pass to all functions (they return zero or null).

## Function reference

### zinc\_create

```c theme={null}
int32_t zinc_create(const char *name,
                    uintptr_t capacity,
                    ZincHandle *out);
```

Creates a new shared memory region. The `name` must be a null-terminated C string matching `[a-zA-Z0-9_-]+`. The `capacity` must be a multiple of the system page size. On success, `*out` receives a new `ZincHandle`. The caller owns this handle and must eventually call `zinc_close`.

Returns 0 on success, or a negative error code.

### zinc\_open

```c theme={null}
int32_t zinc_open(const char *name,
                  ZincHandle *out);
```

Opens an existing shared region by name. On success, `*out` receives a new `ZincHandle`. The caller owns this handle.

Returns 0 on success, or a negative error code on failure (typically `-2` for not found).

### zinc\_ptr

```c theme={null}
uint8_t *zinc_ptr(ZincHandle h);
```

Returns a raw pointer to the usable data area of the region (byte 64, just after the header). The pointer is valid as long as the handle is not closed. Returns null if the handle is null.

The returned pointer points directly into the `mmap`'d memory. Writes through this pointer are immediately visible to all processes mapping the same region.

### zinc\_capacity

```c theme={null}
uintptr_t zinc_capacity(ZincHandle h);
```

Returns the usable size of the region in bytes (total mapping size minus the 64-byte header). Returns 0 if the handle is null.

### zinc\_close

```c theme={null}
void zinc_close(ZincHandle h);
```

Closes a handle obtained from `zinc_create` or `zinc_open`. Decrements the internal reference count. If the closing handle is the creator handle and the reference count reaches zero, the shared memory segment is unlinked. Safe to call with a null handle (no-op).

After calling `zinc_close`, the handle is invalid and must not be passed to any other function.

### zinc\_notify

```c theme={null}
void zinc_notify(ZincHandle h);
```

Atomically increments the notification sequence counter and wakes all threads waiting on this region via `zinc_wait`. On Linux, this calls `FUTEX_WAKE`. On other platforms, it increments the counter. Safe to call with a null handle (no-op).

### zinc\_wait

```c theme={null}
int32_t zinc_wait(ZincHandle h,
                  uint32_t timeout_ms);
```

Blocks the calling thread until the notification sequence counter changes, or until `timeout_ms` milliseconds elapse. Uses a per-handle `last_seq` value to determine the expected counter value.

Returns 0 if the counter changed (data is available), `-110` (`ETIMEDOUT`) if the timeout expired before any notification, or another negative error code. Returns `-22` (`EINVAL`) if the handle is null.

### zinc\_version

```c theme={null}
uint32_t zinc_version(void);
```

Returns the library version encoded as `(major << 16) | minor`. Currently returns `0x00010001` (major 1, minor 1). Adapters should call this at initialization to verify binary compatibility with the loaded library.

## Error return convention

All functions that can fail return `int32_t`. Zero means success. Negative values are POSIX error codes negated:

| Constant    | Value | Meaning                                   |
| ----------- | ----- | ----------------------------------------- |
| `EEXIST`    | -17   | Region name already exists                |
| `ENOENT`    | -2    | Region name not found                     |
| `EINVAL`    | -22   | Invalid name, size, or handle             |
| `EAGAIN`    | -11   | Ring buffer is full                       |
| `ETIMEDOUT` | -110  | Wait timed out                            |
| `EBADMSG`   | -74   | Corrupted region (magic/version mismatch) |
| `EPERM`     | -1    | Permission denied                         |

Platform I/O errors are returned as the negated OS error code.

## Thread safety

All functions are thread-safe. The internal `SharedRegion` operations use atomic operations for reference counting and notification. The handle itself is not synchronized. Passing the same handle to two threads concurrently is safe as long as neither calls `zinc_close` while the other uses it.
