xv6, line by line
user/ulib.c

user/ulib.c

C · 162 lines · annotated 100% · user program / library · upstream

About this file

xv6 user programs have no standard C library. This file, with user/printf.c, user/umalloc.c and the system call stubs in user/usys.S, is everything they get instead: the four object files that the Makefile calls ULIB are linked into every program (Makefile:104 defines the list, Makefile:107 is the link command).

It contains:

  • start, the start-up code: where every program begins, and what calls main;
  • the string and memory functions programs need (strcpy, strcmp, strlen, memset, strchr, memmove, memcmp, memcpy), small versions of the standard ones with a few differences noted below;
  • two helpers built on system calls, gets (read a line) and stat (file information by name), and atoi (text to number);
  • sbrk and sbrklazy, two ways of growing a process’s memory through the one system call sys_sbrk.

The kernel has its own copies of the memory functions in kernel/string.c: kernel and user programs are linked separately and share no code.

Read before: kernel/exec.c (how a program is loaded and started). Read next: user/user.h, user/usys.S.

8//
9// wrapper so that it's OK if main() does not call exit().
10//
11void
12start(int argc, char **argv)
14 int r;
15 extern int main(int argc, char **argv);
20char *
21strcpy(char *s, const char *t)
23 char *os;
25 os = s;
26 while ((*s++ = *t++) != 0)
27 ;
28 return os;
31int
32strcmp(const char *p, const char *q)
34 while (*p && *p == *q)
35 p++, q++;
36 return (uchar)*p - (uchar)*q;
40strlen(const char *s)
42 int n;
44 for (n = 0; s[n]; n++)
45 ;
46 return n;
49void *
50memset(void *dst, int c, uint n)
52 char *cdst = (char *)dst;
53 int i;
54 for (i = 0; i < n; i++) {
55 cdst[i] = c;
56 }
57 return dst;
60char *
61strchr(const char *s, char c)
63 for (; *s; s++)
64 if (*s == c)
65 return (char *)s;
66 return 0;
69char *
70gets(char *buf, int max)
72 int i, cc;
73 char c;
75 for (i = 0; i + 1 < max;) {
76 cc = read(0, &c, 1);
77 if (cc < 1)
78 break;
79 buf[i++] = c;
80 if (c == '\n' || c == '\r')
81 break;
82 }
83 buf[i] = '\0';
84 return buf;
87int
88stat(const char *n, struct stat *st)
90 int fd;
91 int r;
94 if (fd < 0)
95 return -1;
96 r = fstat(fd, st);
98 return r;
101int
102atoi(const char *s)
104 int n;
106 n = 0;
107 while ('0' <= *s && *s <= '9')
108 n = n * 10 + *s++ - '0';
109 return n;
112void *
113memmove(void *vdst, const void *vsrc, int n)
115 char *dst;
116 const char *src;
120 if (src > dst) {
121 while (n-- > 0)
122 *dst++ = *src++;
123 } else {
124 dst += n;
125 src += n;
126 while (n-- > 0)
127 *--dst = *--src;
128 }
129 return vdst;
132int
133memcmp(const void *s1, const void *s2, uint n)
135 const char *p1 = s1, *p2 = s2;
136 while (n-- > 0) {
137 if (*p1 != *p2) {
138 return *p1 - *p2;
139 }
140 p1++;
141 p2++;
142 }
143 return 0;
146void *
147memcpy(void *dst, const void *src, uint n)
149 return memmove(dst, src, n);
152char *
153sbrk(int n)
158char *