История изменений
Исправление beastie, (текущая версия) :
Annotated and patched version without boundary checking (it's homework to you) :)
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define ROOT_INODE 2
/* insert name with prefix '/' at beginning of path */
/* not really effectiv, but enough for our purposes */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
char *
insert(char *path, char *name)
{
size_t plen = strlen(path); /* len of path */
size_t nlen = strlen(name); /* len of name */
memmove(path + nlen + 1, path, plen + 1); /* move old content */
memcpy(path + 1, name, nlen); /* insert name */
path[0] = '/'; /* ensure prefix */
return path;
}
/* walk up a dir tree up to the root */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
/* homework: what happens if we don't find a right inode? fix it. */
char *
pwd(char *path)
{
struct stat st;
struct dirent *dp;
DIR *dirp;
stat(".", &st); /* get stats of current dir */
/* if we are in root, we are done */
if (st.st_ino == ROOT_INODE) { /* root's inode is always 2 */
path[0] = '/'; /* ensure there is a prefix */
return path;
}
chdir(".."); /* go up to the parent dir */
dirp = opendir("."); /* open it */
while ((dp = readdir(dirp)) != NULL) { /* walk through content */
if (st.st_ino == dp->d_ino) { /* looking for inode */
insert(path, dp->d_name); /* found name, add */
break; /* break the loop */
}
}
closedir(dirp); /* clean up */
return pwd(path); /* repeat */
}
int
main()
{
char path[PATH_MAX] = {}; /* zeroed buffer big enough */
puts(pwd(path)); /* do it and show it */
return 0;
}
Исправление beastie, :
Annotated and patched version without boundary checking (it's homework to you) :)
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define ROOT_INODE 2
/* insert name with prefix '/' at beginning of path */
/* not really effectiv, but enough for our purposes */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
char *
insert(char *path, char *name)
{
size_t plen = strlen(path); /* len of path */
size_t nlen = strlen(name); /* len of name */
memmove(path + nlen + 1, path, plen + 1); /* move old content */
memcpy(path + 1, name, nlen); /* insert name */
path[0] = '/'; /* ensure prefix */
return path;
}
/* walk up a dir tree up to the root */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
/* homework: what happens if we don't find a right inode? fix it. */
char *
pwd(char *path)
{
struct stat st;
struct dirent *dp;
DIR *dirp;
stat(".", &st); /* get stats of current dir */
/* if we are in root, we are done */
if (st.st_ino == ROOT_INODE) { /* root's inode is always 2 */
path[0] = '/'; /* ensure there is a prefix */
return path;
}
chdir(".."); /* go up to the parent dir */
dirp = opendir("."); /* open it */
while ((dp = readdir(dirp)) != NULL) { /* walk through content */
if (st.st_ino == dp->d_ino) { /* looking for inode */
insert(path, dp->d_name); /* found name, add */
break; /* break the loop */
}
}
closedir(dirp); /* clean up */
return pwd(path); /* repeat */
}
int
main()
{
char path[PATH_MAX] = {}; /* zeroed buffer big enough */
puts(pwd(path)); /* do it */
return 0;
}
Исправление beastie, :
Annotated and patched version without boundary checking (it's homework to you) :)
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define ROOT_INODE 2
/* insert name with prefix '/' at beginning of path */
/* not really effectiv, but enough for our purposes */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
/* homework: what happens if we don't find a right inode? fix it. */
char *
insert(char *path, char *name)
{
size_t plen = strlen(path); /* len of path */
size_t nlen = strlen(name); /* len of name */
memmove(path + nlen + 1, path, plen + 1); /* move old content */
memcpy(path + 1, name, nlen); /* insert name */
path[0] = '/'; /* ensure prefix */
return path;
}
/* walk up a dir tree up to the root */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
char *
pwd(char *path)
{
struct stat st;
struct dirent *dp;
DIR *dirp;
stat(".", &st); /* get stats of current dir */
/* if we are in root, we are done */
if (st.st_ino == ROOT_INODE) { /* root's inode is always 2 */
path[0] = '/'; /* ensure there is a prefix */
return path;
}
chdir(".."); /* go up to the parent dir */
dirp = opendir("."); /* open it */
while ((dp = readdir(dirp)) != NULL) { /* walk through content */
if (st.st_ino == dp->d_ino) { /* looking for inode */
insert(path, dp->d_name); /* found name, add */
break; /* break the loop */
}
}
closedir(dirp); /* clean up */
return pwd(path); /* repeat */
}
int
main()
{
char path[PATH_MAX] = {}; /* zeroed buffer big enough */
puts(pwd(path)); /* do it */
return 0;
}
Исправление beastie, :
Annotated and patched version without boundary checking (it's homework to you) :)
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define ROOT_INODE 2
/* insert name with prefix '/' at beginning of path */
/* not really effectiv, but enough for our purposes */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
char *
insert(char *path, char *name)
{
size_t plen = strlen(path); /* len of path */
size_t nlen = strlen(name); /* len of name */
memmove(path + nlen + 1, path, plen + 1); /* move old content */
memcpy(path + 1, name, nlen); /* insert name */
path[0] = '/'; /* ensure prefix */
return path;
}
/* walk up a dir tree up to the root */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
char *
pwd(char *path)
{
struct stat st;
struct dirent *dp;
DIR *dirp;
stat(".", &st); /* get stats of current dir */
/* if we are in root, we are done */
if (st.st_ino == ROOT_INODE) { /* root's inode is always 2 */
path[0] = '/'; /* ensure there is a prefix */
return path;
}
chdir(".."); /* go up to the parent dir */
dirp = opendir("."); /* open it */
while ((dp = readdir(dirp)) != NULL) { /* walk through content */
if (st.st_ino == dp->d_ino) { /* looking for inode */
insert(path, dp->d_name); /* found name, add */
break; /* break the loop */
}
}
closedir(dirp); /* clean up */
return pwd(path); /* repeat */
}
int
main()
{
char path[PATH_MAX] = {}; /* zeroed buffer big enough */
puts(pwd(path)); /* do it */
return 0;
}
Исходная версия beastie, :
Annotated and patched version without boundary checking (it's homework to you) :)
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define ROOT_INODE 2
/* insert name with prefix '/' at beginning of path */
/* not really effectiv, but enough for our purposes */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
char *
insert(char *path, char *name)
{
size_t plen = strlen(path); /* len of path */
size_t nlen = strlen(name); /* len of name */
memmove(path + nlen + 1, path, plen + 1); /* move old content */
memcpy(path + 1, name, nlen); /* insert name */
path[0] = '/'; /* ensure prefix */
return path;
}
/* walk up a dir tree up to the root */
/* caveats: no boundaries checks, assumimg buffer is big enough */
/* homework: add boundary checking */
char *
pwd(char *path)
{
struct stat st;
struct dirent *dp;
DIR *dirp;
stat(".", &st); /* get stats of current dir */
/* if we are in root, we are done */
if (st.st_ino == ROOT_INODE) { /* root's inode is always 2 */
path[0] = '/'; /* ensure there is a prefix */
return path;
}
chdir(".."); /* go up to the parent dir */
dirp = opendir("."); /* open it */
while ((dp = readdir(dirp)) != NULL) { /* walk though content */
if (st.st_ino == dp->d_ino) { /* looking for inode */
insert(path, dp->d_name); /* found name, add */
break; /* break the loop */
}
}
closedir(dirp); /* clean up */
return pwd(path); /* repeat */
}
int
main()
{
char path[PATH_MAX] = {}; /* zeroed buffer big enough */
puts(pwd(path)); /* do it */
return 0;
}