Problem/Motivation
When attempting to create a private file folder, I put in an invalid path and get one of two errors:
When making a directory that cannot be created by the webuser on OSX in the root dir
IE "/home/a/dev/files-private" (OSX has a home directory not writeable by webuser)
"Operation not supported in _drupal_mkdir_call()"
When making a directory that cannot be created due to permissions (OSX, Linux, Windows)
"Permission Denied in _drupal_mkdir_call()"
Followed by the correct error:
"The directory /home/i/dev/files-private does not exist and could not be created."

Proposed resolution
To use @mkdir() instead of mkdir().
Remaining tasks
Beta phase evaluation
Comments
Comment #1
fenstratThis patch gets rid of the icky error, but keeps the friendly "The directory %directory does not exist and could not be created." error.
Sitting here at the table with @chx at PNWDS who okayed this approach. He also waxed quite lyrically about how PHP's handling of errors like this is ... far from ideal.
Comment #2
fenstratThe fact that this passes suggests we need a test for this.
Also related #1068266: drupal_mkdir does not set permissions to directories it created recursively .
Comment #3
jhedstromNeeds tests as per #2. Patch still applies, and the approach makes sense to me as well.
Comment #4
fenstrat@jhedstrom Any pointers on how'd you go about writing a test for this? Happy to give it a shot, but not sure of the best approach.
Comment #5
jhedstrom@fenstrat, take a look at \Drupal\system\Tests\File\DirectoryTest -- that is testing
drupal_mkdir(). I'd guess you could create a directory, remove access to that directory, then calldrupal_mkdir()and ensure the icky errors don't appear?Comment #6
areke commentedComment #7
fenstratThanks @jhedstrom, here's a shot at that. The test-only patch should fail, but with an exception as mkdir() isn't silenced with @mkdir.
As DirectoryTest is a unit test (it extends from DrupalUnitTestBase (soon to be KernelTestBase I believe) and not WebTestBase) I'm not quite sure how to test the output of php warnings. So while the test will cause an exception if mkdir isn't silenced I'm not sure how to actually test there is no icky PHP warning?
Comment #8
fenstratHmm, hidden files aren't tested?
Comment #10
fenstratTrying again.
Comment #12
jhedstromI think failure by exception is a fine way to test. #7 is RTBC I think (#11 is just the test, which is expected to fail without the fix).
I've added the beta phase evaluation to the summary.
Comment #13
fenstratGreat, thanks @jhedstrom.
Comment #14
alexpottI think we should be adding the @ to the call to drupal_mkdir() in
system_check_directory()We rely on the errors in
LocalStream::mkdir()- which is obviously missing test coverage.With this change this logic is broken.
And we do this elsewhere.
From drupal_install_mkdir()
From file_prepare_directory().
Comment #15
fenstrat@alexpott in #14 is correct, the errors are relied upon in other locations. I've moved the @ into system_check_directory().
I've kept the test, and silence the call there, i.e. @drupal_mkdir().
Also, while #2050759: Move drupal_chmod and other code in file.inc to a Drupal\Core\File\FileSystem class deprecated drupal_mkdir() there are still calls all over core to it.
Comment #16
mile23Patch in #15 still applies.
DirectoryTestpasses locally.Retesting, and also here's a review:
Should use the
file_systemservice.Comment #18
fenstratHere's the changes as requested by @Mile23 in #16.
Comment #19
dawehnerI would be nice to be able to pass a silent as parameter to the method ... Is there a way to check beforehand whether a mkdir would fail?
Comment #20
fenstrat@dawehner It doesn't look like there is a way to check before hand if php's mkdir() will fail. As @alexpott noted in #14
LocalStream::mkdir()does calldrupal_mkdir()ifSTREAM_REPORT_ERRORSis set (and calls@drupal_mkdir()if it is not). However I think properly implementing a silent param inFileSystem::mkdir()would be best as a follow up.#18 fixes this bug and adds a test to prove it.
Comment #25
joelpittetShouldn't the patch be doing the silencing inside the service on the actual PHP call to mkdir?
Comment #30
quietone commentedThis is not reproducible in Drupal 8 because The private files directory is no longer configurable in the UI or available in config. However, it is reproducible in Drupal 7, so changing version.