3

I'm trying to familiarize myself with modifying Minix system calls and rebuilding the kernel.

I modified mkdir to print New dir -> <directory-name> <permissions> every time it was called, unless the directory already existed.

I edited /usr/src/servers/vfs/open.c, which contains the code for mkdir. I added this line of code to line 610:

    printf("New dir -> %s %o",fullpath,dirmode);

With this edit, mkdir printed correctly, except that if the folder already existed, I was getting the following message:

New Dir -> test 755 mkdir: test: file exists

I expected to see:

mkdir: test: file exists

I thought that by adding the printf to the last if-else body near line 610, it would not execute in this case, since this if-else structure checks if the new directory is valid (inode, permissions, etc), and the call should return if the directory already exists. I was mistaken.

What system function or variable should I check to see if the file already exists?

My edited version of open.c.

I'm using Minix version 3.2.1.

To test this, I rebuilt just the kernel, like this:

cd /usr/src/releasetools
make hdboot
Cel Skeggs
  • 1,827
  • 21
  • 38
solid.py
  • 2,782
  • 5
  • 23
  • 30

1 Answers1

2

As suggested by the commenters, you need to check one more thing.

The code near the section that you modified says:

/* Make sure that the object is a directory */
if (!S_ISDIR(vp->v_mode)) {
    r = ENOTDIR;
} else if ((r = forbidden(fp, vp, W_BIT|X_BIT)) == OK) {
    r = req_mkdir(vp->v_fs_e, vp->v_inode_nr, fullpath, fp->fp_effuid,
                  fp->fp_effgid, bits);
    printf("New dir -> %s %o",fullpath,dirmode);
}

The key here is that the branches check that the parent directory exists, and then check that the program has permission to create a new directory - but nothing about whether or not a directory already existed.

That check is done as part of req_mkdir, which returns an error code for whether or not it succeeded. You would want to check this error code:

/* Make sure that the object is a directory */
if (!S_ISDIR(vp->v_mode)) {
    r = ENOTDIR;
} else if ((r = forbidden(fp, vp, W_BIT|X_BIT)) == OK) {
    r = req_mkdir(vp->v_fs_e, vp->v_inode_nr, fullpath, fp->fp_effuid,
                  fp->fp_effgid, bits);
    if (r == OK) {
        printf("New dir -> %s %o\n", fullpath, dirmode);
    }
}

While I was at it, I also added the missing newline to the end of the printf format string so that it doesn't get strung together with the next line.

Disclaimer: I haven't actually tested this, and might have made a mistake.

Cel Skeggs
  • 1,827
  • 21
  • 38