2

I'm creating a directory inside a unit test like this:

// The directory which is going to be created next to unit test executable.
const DirName string = "test-files"

Creating directory:

    // Create the directory if doesn't already exist.
    err := os.MkdirAll(DirName, os.ModeDir)
    if err != nil {
        return err
    }

    // Compose a sample file path to double-check its existence.
    pth := DirName + string(os.PathSeparator) + "samplefile.txt"


    exists, err := doesExist(pth)
    if err != nil {
        return err
    }

And checking file existence:


// Does file exist?
func doesExist(pth string) (bool, error) {

    // Check file existence
    // https://stackoverflow.com/a/10510718/3405291
    if _, err := os.Stat(pth); err != nil {
        if os.IsNotExist(err) {
            return false, nil
        } else {
            return true, err
        }
    }

    // Above conditions are skipped,
    // therefore file exists.
    return true, nil
}

The above code returns this error:

os.Stat: permission denied

error(syscall.Errno) EACCES (13)

I can double-check that the directory is actually created. But the permissions are d---------:

> ls -lh
d--------- 2 m3 users    6 Dec 23 20:30 test-files

How can I create the directory with the appropriate permissions?

Megidd
  • 7,089
  • 6
  • 65
  • 142
  • 1
    You could use os.Mkdir where you also can set the permissions. – Spoofed Dec 23 '21 at 17:12
  • 2
    `MkDir` is already creating a directory, you don't need to set the directory mode bit. You do however need to set the correct permissions to access the directory. – JimB Dec 23 '21 at 17:14
  • Take a look at this https://golangbyexample.com/create-directory-folder-golang/ – Spoofed Dec 23 '21 at 17:15
  • @Spoofed Does `os.MkdirAll` have permission parameter? – Megidd Dec 23 '21 at 17:17
  • Are you aware of [`umask`](https://en.wikipedia.org/wiki/Umask)? It might be intervening here. While we're at it, please consider using `path/filepath.Join` instead of messing with the string concatenation using `+`. – kostix Dec 23 '21 at 17:19

1 Answers1

2

You're abusing the os.ModeDir constant. It's invented to serve as the bit mask to check whether the file's mode+permissions bits (returned by, say, os.(*File).Stat indicate it's a directory.

The default permission mode bits to create a directory are 0777 but they are subject to umask.

kostix
  • 51,517
  • 14
  • 93
  • 176
  • Right, the error got resolved by `syscall.Umask(0) err := os.MkdirAll(DirName, 0775)` as suggested here: https://stackoverflow.com/a/61645606/3405291 – Megidd Dec 23 '21 at 17:29
  • 2
    @user3405291: you generally *should not* **set** the umask, and *should* obey the existing umask while providing wide-open permissions. See [my answer to that same question](https://stackoverflow.com/a/59963154/1256452). – torek Dec 24 '21 at 09:36
  • @torek Thanks, I'm going study it :) – Megidd Dec 24 '21 at 12:03