[Pcsclite-cvs-commit] r4969 - in /trunk/PCSC/src: pcscdaemon.c sys_unix.c

rousseau at users.alioth.debian.org rousseau at users.alioth.debian.org
Tue Jun 1 07:33:37 UTC 2010


Author: rousseau
Date: Tue Jun  1 07:33:36 2010
New Revision: 4969

URL: http://svn.debian.org/wsvn/pcsclite/?sc=1&rev=4969
Log:
pcscd: do not return before most of the initialisation are done
correctly. The idea is that pcscd can return an error code if the daemon
fails to start correctly (hald not started for example).

Before the patch pcscd became a daemon, then returned 0 (success) and
then continued with the initialisation. If the initialisation failed it
was too late to return an error code. The /etc/init.d/pcscd script was
not aware of the failure.

Closes https://bugzilla.redhat.com/show_bug.cgi?id=580321
"/usr/sbin/pcscd exit codes broken"

Modified:
    trunk/PCSC/src/pcscdaemon.c
    trunk/PCSC/src/sys_unix.c

Modified: trunk/PCSC/src/pcscdaemon.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/pcscdaemon.c?rev=4969&op=diff
==============================================================================
--- trunk/PCSC/src/pcscdaemon.c (original)
+++ trunk/PCSC/src/pcscdaemon.c Tue Jun  1 07:33:36 2010
@@ -56,6 +56,7 @@
 char AutoExit = FALSE;
 static int ExitValue = EXIT_FAILURE;
 int HPForceReaderPolling = 0;
+static int pipefd[] = {-1, -1};
 
 /*
  * Some internal functions
@@ -75,59 +76,13 @@
  * If the message is valid, \c CreateContextThread() is called to serve this
  * request.
  */
-static void SVCServiceRunLoop(int customMaxThreadCounter,
-	int customMaxThreadCardHandles)
+static void SVCServiceRunLoop(void)
 {
 	int rsp;
 	LONG rv;
 	uint32_t dwClientID;	/* Connection ID used to reference the Client */
 
-	rsp = 0;
 	rv = 0;
-
-	/*
-	 * Initialize the comm structure
-	 */
-	rsp = InitializeSocket();
-
-	if (rsp == -1)
-	{
-		Log1(PCSC_LOG_CRITICAL, "Error initializing pcscd.");
-		at_exit();
-	}
-
-	/*
-	 * Initialize the contexts structure
-	 */
-	rv = ContextsInitialize(customMaxThreadCounter, customMaxThreadCardHandles);
-
-	if (rv == -1)
-	{
-		Log1(PCSC_LOG_CRITICAL, "Error initializing pcscd.");
-		at_exit();
-	}
-
-	(void)signal(SIGPIPE, SIG_IGN);
-	(void)signal(SIGHUP, SIG_IGN);	/* needed for Solaris. The signal is sent
-				 * when the shell is existed */
-
-#if !defined(PCSCLITE_STATIC_DRIVER) && defined(USE_USB)
-	/*
-	 * Set up the search for USB/PCMCIA devices
-	 */
-	rsp = HPSearchHotPluggables();
-	if (rsp)
-		return;
-
-	rsp = HPRegisterForHotplugEvents();
-	if (rsp)
-		return;
-#endif
-
-	/*
-	 * Set up the power management callback routine
-	 */
-	(void)PMRegisterForPowerEvents();
 
 	while (TRUE)
 	{
@@ -407,21 +362,75 @@
 			return EXIT_FAILURE;
 		}
 
+	/* like in daemon(3): changes the current working directory to the
+	 * root ("/") */
+	(void)chdir("/");
+
 	if (AutoExit)
-		/* fork() so that pcscd always return in --auto-exit mode
-		 * but do not close stdout yet since we may need to send logs */
-		if (SYS_Daemon(1, 1))
-			Log2(PCSC_LOG_CRITICAL, "SYS_Daemon() failed: %s",
-					strerror(errno));
+	{
+		int pid;
+
+		/* fork() so that pcscd always return in --auto-exit mode */
+		pid = fork();
+		if (-1 == pid )
+			Log2(PCSC_LOG_CRITICAL, "fork() failed: %s", strerror(errno));
+
+		if (pid)
+			/* father */
+			return EXIT_SUCCESS;
+	}
 
 	/*
 	 * If this is set to one the user has asked it not to fork
 	 */
 	if (!setToForeground)
 	{
-		if (SYS_Daemon(0, 0))
-			Log2(PCSC_LOG_CRITICAL, "SYS_Daemon() failed: %s",
-				strerror(errno));
+		int pid;
+
+		if (pipe(pipefd) == -1)
+		{
+			Log2(PCSC_LOG_CRITICAL, "pipe() failed: %s", strerror(errno));
+			return EXIT_FAILURE;
+		}
+
+		pid = fork();
+		if (-1 == pid)
+		{
+			Log2(PCSC_LOG_CRITICAL, "fork() failed: %s", strerror(errno));
+			return EXIT_FAILURE;
+		}
+
+		/* like in daemon(3): redirect standard input, standard output
+		 * and standard error to /dev/null */
+		(void)close(0);
+		(void)close(1);
+		(void)close(2);
+
+		if (pid)
+		/* in the father */
+		{
+			char buf;
+			int ret;
+
+			/* close write side */
+			close(pipefd[1]);
+
+			/* wait for the son to write the return code */
+			ret = read(pipefd[0], &buf, 1);
+			if (ret <= 0)
+				return 2;
+
+			close(pipefd[0]);
+
+			/* exit code */
+			return buf;
+		}
+		else
+		/* in the son */
+		{
+			/* close read side */
+			close(pipefd[0]);
+		}
 	}
 
 	/*
@@ -528,7 +537,60 @@
 	 */
 	(void)signal(SIGUSR1, signal_reload);
 
-	SVCServiceRunLoop(customMaxThreadCounter, customMaxThreadCardHandles);
+	/*
+	 * Initialize the comm structure
+	 */
+	rv = InitializeSocket();
+	if (rv)
+	{
+		Log1(PCSC_LOG_CRITICAL, "Error initializing pcscd.");
+		at_exit();
+	}
+
+	/*
+	 * Initialize the contexts structure
+	 */
+	rv = ContextsInitialize(customMaxThreadCounter, customMaxThreadCardHandles);
+
+	if (rv == -1)
+	{
+		Log1(PCSC_LOG_CRITICAL, "Error initializing pcscd.");
+		at_exit();
+	}
+
+	(void)signal(SIGPIPE, SIG_IGN);
+	(void)signal(SIGHUP, SIG_IGN);	/* needed for Solaris. The signal is sent
+				 * when the shell is existed */
+
+#if !defined(PCSCLITE_STATIC_DRIVER) && defined(USE_USB)
+	/*
+	 * Set up the search for USB/PCMCIA devices
+	 */
+	rv = HPSearchHotPluggables();
+	if (rv)
+		at_exit();
+
+	rv = HPRegisterForHotplugEvents();
+	if (rv)
+		at_exit();
+#endif
+
+	/*
+	 * Set up the power management callback routine
+	 */
+	(void)PMRegisterForPowerEvents();
+
+	/* initialisation succeeded */
+	if (pipefd[1] >= 0)
+	{
+		char buf = 0;
+
+		/* write a 0 (success) to father process */
+		write(pipefd[1], &buf, 1);
+		close(pipefd[1]);
+	}
+
+	SVCServiceRunLoop();
 
 	Log1(PCSC_LOG_ERROR, "SVCServiceRunLoop returned");
 	return EXIT_FAILURE;
@@ -539,6 +601,16 @@
 	Log1(PCSC_LOG_INFO, "cleaning " PCSCLITE_IPC_DIR);
 
 	clean_temp_files();
+
+	if (pipefd[1] >= 0)
+	{
+		char buf;
+
+		/* write the error code to father process */
+		buf = ExitValue;
+		write(pipefd[1], &buf, 1);
+		close(pipefd[1]);
+	}
 
 	_exit(ExitValue);
 }

Modified: trunk/PCSC/src/sys_unix.c
URL: http://svn.debian.org/wsvn/pcsclite/trunk/PCSC/src/sys_unix.c?rev=4969&op=diff
==============================================================================
--- trunk/PCSC/src/sys_unix.c (original)
+++ trunk/PCSC/src/sys_unix.c Tue Jun  1 07:33:36 2010
@@ -75,85 +75,6 @@
 #endif
 }
 
-/**
- * @brief put the process to run in the background.
- *
- * @param[in] nochdir if zero, change the current directory to "/".
- * @param[in] noclose if zero, redirect standard imput/output/error to /dev/nulll.
- *
- * @return error code.
- * @retval 0 success.
- * @retval -1 an error ocurred.
- */
-INTERNAL int SYS_Daemon(int nochdir, int noclose)
-{
-#ifdef HAVE_DAEMON
-	return daemon(nochdir, noclose);
-#else
-
-#if defined(__SVR4) && defined(__sun)
-	pid_t pid;
-
-	pid = fork();
-	if (-1 == pid)
-	{
-		Log2(PCSC_LOG_CRITICAL, "main: fork() failed: %s", strerror(errno));
-		return -1;
-	}
-	else
-	{
-		if (pid != 0)
-			/* the father exits */
-			exit(0);
-	}
-
-	setsid();
-
-	pid = fork();
-	if (-1 == pid)
-	{
-		Log2(PCSC_LOG_CRITICAL, "main: fork() failed: %s", strerror(errno));
-		exit(1);
-	}
-	else
-	{
-		if (pid != 0)
-			/* the father exits */
-			exit(0);
-	}
-#else
-	switch (fork())
-	{
-	case -1:
-		return (-1);
-	case 0:
-		break;
-	default:
-		return (0);
-	}
-#endif
-
-	if (!noclose) {
-		if (close(0))
-			Log2(PCSC_LOG_ERROR, "close(0) failed: %s",
-				strerror(errno));
-
-		if (close(1))
-			Log2(PCSC_LOG_ERROR, "close(1) failed: %s",
-				strerror(errno));
-
-		if (close(2))
-			Log2(PCSC_LOG_ERROR, "close(2) failed: %s",
-				strerror(errno));
-	}
-	if (!nochdir) {
-		if (chdir("/"))
-			Log2(PCSC_LOG_ERROR, "chdir() failed: %s", strerror(errno));
-	}
-	return 0;
-#endif
-}
-
 INTERNAL int SYS_RandomInt(int fStart, int fEnd)
 {
 	static int iInitialized = 0;




More information about the Pcsclite-cvs-commit mailing list