Skip to content

Safe Runtime Skill

Safe Runtime memory management, string functions, fiber scheduling, timers, and logging. All Ioto C code must use Safe Runtime functions instead of standard C equivalents.

Invoke with: /runtime

Mandatory Substitution Table

Standard CSafe RuntimeNotes
malloc(n)rAlloc(n)Never check for NULL — handled globally
realloc(p,n)rRealloc(p, n)
free(p)rFree(p)Null-tolerant
strlen(s)slen(s)Null-tolerant, returns 0 for NULL
strcpy(d,s)scopy(d, n, s)Bounded copy
strcmp(a,b)scmp(a, b)Null-tolerant
strdup(s)sclone(s)R-managed allocation, returns "" for NULL
strndup(s,n)snclone(s, n)R-managed allocation
printf(f,...)rPrintf(f, ...)Output to stdout
sprintf(d,f,...)sfmtbuf(d, n, f, ...)Bounded format
n/asfmt(f, ...)Allocates formatted string, caller frees
strcmp(a,b)==0smatch(a, b)Returns true if strings match

Scheduled Background Tasks

c
static void sensorPoll(void *arg)
{
    double temp = readSensor();
    rTrace("sensor", "Temperature: %.1f", temp);
}

/* In ioStart(): start polling every 5 seconds */
REvent *timer = rStartEvent(sensorPoll, NULL, 0, 5000);

/* In ioStop(): stop polling */
rStopEvent(timer);

Spawning a Fiber

c
static void backgroundTask(void *arg)
{
    while (running) {
        processQueue();
        rSleep(100);   /* yield control for 100ms */
    }
}

/* In ioStart(): */
rSpawnFiber(backgroundTask, NULL);

Logging

c
rTrace("tag", "Debug message: %s", detail);       /* level 4 - verbose */
rInfo("tag", "Informational: %d items", count);    /* level 2 */
rError("tag", "Failed: %s", reason);               /* level 0 */

Dynamic Buffers

c
RBuf *buf = rAllocBuf(1024);
rPutToBuf(buf, data, dataLen);
rGrowBuf(buf, needed);
/* use buf->start (data pointer) and rGetBufLength(buf) */
rFreeBuf(buf);

Memory Rules

  • Never mix malloc/free with rAlloc/rFree
  • Never check rAlloc return for NULL — global handler manages failures
  • rFree(NULL) is safe (null-tolerant)
  • sclone(NULL) returns "" (empty string), not NULL
  • dbField() returns pointer into item — copy with sclone() if persisting