Subject: Re: odb_mkstemp's 0444 permission broke write/delete access on AFP

From: Junio C Hamano <[email-masked]>
Date: Wed, 18 Feb 2015 09:31:43 -0800

Junio C Hamano <[email-masked]> writes:

> Matthieu Moy <[email-masked]> writes:
>
>> Junio C Hamano <[email-masked]> writes:
>>
>>> in compat/broken-unlink.c and something like this
>>>
>>> 	#ifdef BROKEN_UNLINK
>>> 	#define unlink(x) workaround_broken_unlink(x)
>>>         #endif
>>>
>>> in git-compat-util.h instead? 
>>
>> That means we have to know BROKEN_UNLINK at compile-time. I had never
>> heard about AFP before this thread, but they seem mountable on Linux and
>> Windows. I don't know whether these platforms will have the same issue,
>> but I suspect they will (if the server rejects the unlink).
>>
>> So, if my suspicion is right, we'd have to activate it on any platform
>> able to mount AFP, i.e. essentially everywhere.
>
> Sigh.

That is "Sigh.  It is unfortunate but you are correct.".

Perhaps we would need to do something ugly like this:

 * add "core.brokenUnlink" configuration (or whatever we end up
   calling this filesystem trait) and add "int broken_unlink" in
   environment.c (declare it in cache.h).

 * in init-db.c, autoprobe by doing something like this:

    create a test file with 0444 permission bits;
    if (unlink(that test file)) {
	chmod(that test file, 0644);
        if (!unlink(that test file)) {
		broken_unlink = 1;
		git_config_set("core.brokenunlink", broken_unlink);
	} else {
        	die("aaargh");
	}
    }

 * Do your unlink_or_chmod() thing in wrapper.c, but perhaps call it
   xunlink(), like this:

        int xunlink(...) {
		int ret = unlink(...);
		if (broken_unlink && ret) {
                        chmod(..., 0644);
                        ret = unlink(...);
                }
                return ret;
        }

We probably need something similar for xrename()?