OS X El Capitan bug: PC/SC not usable after fork()
This is part of the series: "OS X El Capitan and smart cards: known bugs".
PC/SC is not unusable after fork()
SCardEstablishContext() returnsSCARD_E_NO_SERVICE
if called after fork(2) on El Capitan.I can agree that if you mix PC/SC calls from before and after the fork(2) call you can have problems, as in OS X Yosemite bug: PC/SC functions crash after a fork(2). But if you start all the PC/SC calls in the same (child) process I expected it to work.
From the fork(2) manpage I read:
CAVEATS
There are limits to what you can do in the child process. To be totally safe you should restrict yourself to only executing async-signal safe operations until such time as one of the exec functions is called. All APIs, including global data symbols, in any framework or library should be assumed to be unsafe after a fork() unless explicitly documented to be safe or async-signal safe. If you need to use these frameworks in the child process, you must exec. In this situation it is reasonable to exec yourself.
I expect Apple to just close this bug as it it the documented behaviour.
It is not a bug but a feature ☹.
See also
Apple bug report #23669488 "PC/SC is not unusable after fork()"Bug closed by Apple. See Update bellow.
Sample code
#include <stdio.h> #include <unistd.h> #ifdef __APPLE__ #include <PCSC/winscard.h> #include <PCSC/wintypes.h> #else #include <winscard.h> #endif int main(void) { int pid = fork(); if (0 == pid) { /* son process */ SCARDCONTEXT hContext; DWORD err = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); if (err != SCARD_S_SUCCESS) { printf("ScardEstablishedContext: %s (0x%08lx)\n", pcsc_stringify_error(err), (long)err); return -1; } else printf("OK\n"); SCardReleaseContext(hContext); } else /* give some time to the son */ sleep(1); return 0; }
Result (on El Capitan)
$ CFLAGS="-framework PCSC" make main cc -framework PCSC main.c -o main
$ ./main ScardEstablishedContext: Service not available. (0x8010001d)
Expected result (on Debian)
$ CFLAGS=`pkg-config --cflags libpcsclite` LDFLAGS=`pkg-config --libs libpcsclite` make main cc -pthread -I/usr/include/PCSC -lpcsclite main.c -o main
$ ./main OK
Known workaround
None known.Update 8th December 2015
As expected Apple closed the bug with:As documented in the quoted fork man page excerpt, it is quite expected that PC/SC does not work in forked child.