OS161中vfs_setbootfs函数冒号校验逻辑的技术疑问
strlen(s) > 0 Check in OS161's vfs_setbootfs Here's the relevant code from OS161's vfs_setbootfs function:
/* * Set bootfs_vnode. * * Bootfs_vnode is the vnode used for beginning path translation of * pathnames starting with /. * * It is also incidentally the system's first current directory. */ int vfs_setbootfs(const char *fsname) { char tmp[NAME_MAX+1]; char *s; int result; struct vnode *newguy; vfs_biglock_acquire(); snprintf(tmp, sizeof(tmp)-1, "%s", fsname); s = strchr(tmp, ':'); if (s) { /* If there's a colon, it must be at the end */ if (strlen(s)>0) { vfs_biglock_release(); return EINVAL; } } else { strcat(tmp, ":"); } result = vfs_chdir(tmp); if (result) { vfs_biglock_release(); return result; } result = vfs_getcurdir(&newguy); if (result) { vfs_biglock_release(); return result; } change_bootfs(newguy); vfs_biglock_release(); return 0; }
The Question
The comment states that if a colon exists, it must be at the end of the string. But why does the code return EINVAL when strlen(s) > 0? If the colon is at the end, strlen(s) would be 1 (not 0), which would trigger this error—this seems contradictory to the comment's intent.
The Explanation
Let's unpack this clearly, because there's a clear disconnect between the comment's intended behavior and the code's current condition:
First, remember what strchr(tmp, ':') does: it returns a pointer to the first occurrence of the colon in tmp. Let's look at two key scenarios:
- Valid scenario (trailing colon): If
fsnameis"bootfs:",spoints directly to that trailing colon. The substring starting atsis just":", sostrlen(s)equals 1. - Invalid scenario (colon with text after): If
fsnameis"bootfs:extra",spoints to the colon after "bootfs", and the substring starting atsis":extra"—sostrlen(s)equals 6.
The comment says the colon must be at the end (no characters after it), but the code checks if (strlen(s) > 0) and errors out. This is a bug in the condition logic:
- The check
strlen(s) > 0is always true if a colon exists (since the colon itself is one character), which would incorrectly reject valid inputs that end with a colon. - The intended check should verify that there are no characters after the colon. The correct conditions would be either:
if (*(s + 1) != '\0'): Directly check if the character right after the colon isn't the end of the string (meaning extra text exists).if (strlen(s) > 1): Sincestrlen(s)counts the colon plus any characters after it; a value greater than 1 means there's extra text following the colon.
Likely Root Cause
This is almost certainly a typo or logic mix-up by the developer. It's possible they intended to check for extra characters after the colon but accidentally used strlen(s) > 0 instead of strlen(s) > 1, or confused the pointer returned by strchr with the position relative to the end of the string.
内容的提问来源于stack exchange,提问作者Osama Ahmad

