I'm not sure why you think fcntl() fits into this. To close an fd you use close().
It is absolutely required that a
daemon close fd's 0, 1, and 2. After that, as the lawyers say, "reasonable minds may disagree". In the days when we were limited to 64 fd's, it was reasonable to simply loop invoking close() on them all. If I was to write a
daemon, yes I guess that I would use get getconf(_SC_OPEN_MAX) to get the max possible fd and loop invoking close() on every last one. This could be thousands of close() calls that aren't needed, but close() fails very quickly when invoked against a non-open fd.
If they are closing stdin, stdout, and stderr, I would have to say that their stance is reasonable. But I do believe they would have a difficult time producing any language in
posix that supports them. The
posix standard is on-line and we have a link to it on our home page. Exactly which section do they cite?
It should be very easy to solve your problem though. Can't you change the app server to not leave extra fd's open?
Or if this
daemon is called, say, daemonx, just write a program that closes all fd's and then exec()'s daemonx. Call your program pre_daemonx. Have your app server call pre_daemonx.
Is the name "daemonx" hard-coded into an unchangable app server? No problem. Rename "daemonx" to "real.daemonx" and call your program "daemonx".
Whichever path you take here, fixing this should be a 10 minute problem.