LINUX.ORG.RU

История изменений

Исправление 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;
}