tools/include/nolibc/stdio.h

Source file repositories/reference/linux-study-clean/tools/include/nolibc/stdio.h

File Facts

System
Linux kernel
Corpus path
tools/include/nolibc/stdio.h
Extension
.h
Size
23718 bytes
Lines
1005
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct __nolibc_sprintf_cb_state {
	char *buf;
	size_t space;
};

static int __nolibc_sprintf_cb(void *v_state, const char *buf, size_t size)
{
	struct __nolibc_sprintf_cb_state *state = v_state;
	size_t space = state->space;
	char *tgt;

	/* Truncate the request to fit in the output buffer space.
	 * The last byte is reserved for the terminating '\0'.
	 * state->space can only be zero for snprintf(NULL, 0, fmt, args)
	 * so this normally lets through calls with 'size == 0'.
	 */
	if (size >= space) {
		if (space <= 1)
			return 0;
		size = space - 1;
	}
	tgt = state->buf;

	/* __nolibc_printf() ends with cb(state, NULL, 0) to request the output
	 * buffer be '\0' terminated.
	 * That will be the only cb() call for, eg, snprintf(buf, sz, "").
	 * Zero lengths can occur at other times (eg "%s" for an empty string).
	 * Unconditionally write the '\0' byte to reduce code size, it is
	 * normally overwritten by the data being output.
	 * There is no point adding a '\0' after copied data - there is always
	 * another call.
	 */
	*tgt = '\0';
	if (size) {
		state->space = space - size;
		state->buf = tgt + size;
		memcpy(tgt, buf, size);
	}

	return 0;
}

static __attribute__((unused, format(printf, 3, 0)))
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
	struct __nolibc_sprintf_cb_state state = { .buf = buf, .space = size };

	return __nolibc_printf(__nolibc_sprintf_cb, &state, fmt, args);
}

static __attribute__((unused, format(printf, 3, 4)))
int snprintf(char *buf, size_t size, const char *fmt, ...)
{
	va_list args;
	int ret;

	va_start(args, fmt);
	ret = vsnprintf(buf, size, fmt, args);
	va_end(args);

	return ret;
}

static __attribute__((unused, format(printf, 2, 0)))
int vsprintf(char *buf, const char *fmt, va_list args)
{
	return vsnprintf(buf, SIZE_MAX, fmt, args);
}

static __attribute__((unused, format(printf, 2, 3)))
int sprintf(char *buf, const char *fmt, ...)
{
	va_list args;
	int ret;

	va_start(args, fmt);
	ret = vsprintf(buf, fmt, args);
	va_end(args);

	return ret;
}

static __attribute__((unused, format(printf, 2, 0)))
int __nolibc_vasprintf(char **strp, const char *fmt, va_list args1, va_list args2)
{
	int len1, len2;
	char *buf;

	len1 = vsnprintf(NULL, 0, fmt, args1);
	if (len1 < 0)

Annotation

Implementation Notes