xv6, line by line
kernel/string.c

kernel/string.c

C · 106 lines · annotated 100% · kernel · upstream

About this file

The kernel’s own versions of the C library’s memory and string functions. A freestanding (vs. hosted) C kernel has no C library, so anything it needs from <string.h> it must write itself. These eight functions are short loops, but they are used everywhere: memset clears pages and structures, memmove copies disk blocks and data between user and kernel memory, and the string functions handle file names and process names.

They follow the standard C functions of the same names closely, with a few differences worth knowing:

  • sizes are uint (32-bit) or int, not size_t (64-bit on RV64);
  • memcpy is memmove, so it is safe even when the two areas overlap;
  • safestrcpy has no standard counterpart: it is strncpy that always terminates the result;
  • strlen returns int.

The Makefile passes -fno-builtin-memset and similar flags (-fno-builtin-NAME) so that the compiler does not substitute its own built-in versions for these names. User programs have a separate set in user/ulib.c.

Read next: any caller, for example kernel/fs.c (names) or kernel/vm.c (copyout and copyin use memmove).

1#include "types.h"
3void *
4memset(void *dst, int c, uint n)
5{
6 char *cdst = (char *)dst;
7 int i;
8 for (i = 0; i < n; i++) {
9 cdst[i] = c;
10 }
11 return dst;
14int
15memcmp(const void *v1, const void *v2, uint n)
17 const uchar *s1, *s2;
19 s1 = v1;
20 s2 = v2;
21 while (n-- > 0) {
22 if (*s1 != *s2)
23 return *s1 - *s2;
24 s1++, s2++;
25 }
27 return 0;
30void *
31memmove(void *dst, const void *src, uint n)
33 const char *s;
34 char *d;
36 if (n == 0)
37 return dst;
39 s = src;
40 d = dst;
41 if (s < d && s + n > d) {
42 s += n;
43 d += n;
44 while (n-- > 0)
45 *--d = *--s;
46 } else
47 while (n-- > 0)
48 *d++ = *s++;
50 return dst;
53// memcpy exists to placate GCC. Use memmove.
54void *
55memcpy(void *dst, const void *src, uint n)
57 return memmove(dst, src, n);
60int
61strncmp(const char *p, const char *q, uint n)
63 while (n > 0 && *p && *p == *q)
64 n--, p++, q++;
65 if (n == 0)
66 return 0;
67 return (uchar)*p - (uchar)*q;
70char *
71strncpy(char *s, const char *t, int n)
73 char *os;
75 os = s;
76 while (n-- > 0 && (*s++ = *t++) != 0)
77 ;
78 while (n-- > 0)
79 *s++ = 0;
80 return os;
83// Like strncpy but guaranteed to NUL-terminate.
84char *
85safestrcpy(char *s, const char *t, int n)
87 char *os;
89 os = s;
90 if (n <= 0)
91 return os;
92 while (--n > 0 && (*s++ = *t++) != 0)
93 ;
94 *s = 0;
95 return os;
98int
99strlen(const char *s)
101 int n;
103 for (n = 0; s[n]; n++)
104 ;
105 return n;