Author: jsuchome
Date: Wed Jul 18 15:37:21 2007
New Revision: 39505
URL: http://svn.opensuse.org/viewcvs/yast?rev=39505&view=rev
Log:
use fork instead of threads and communicate with a pipe
Modified:
trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.cc
trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.h
trunk/fingerprint-reader/src/UsersPluginFingerprintReader.pm
trunk/fingerprint-reader/src/users_plugin_fingerprint_reader.ycp
Modified: trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.cc?rev=39505&r1=39504&r2=39505&view=diff
==============================================================================
--- trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.cc (original)
+++ trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.cc Wed Jul 18 15:37:21 2007
@@ -11,69 +11,22 @@
#define PC(n) (path->component_str(n))
-/*
-libthinkfinger_state global_state; // save the last state
-
-s_tfdata swipes; // save the nubmer of (un)succ. swipes globally
-*/
-
-
//FIXME remove unused parts...
typedef struct {
char bir[MAX_PATH];
- int swipe_success;
- int swipe_failed;
- ThinkFingerAgent *tfagent;
+ int write_fd;
} s_tfdata;
/**
- * set the current status, for which YaST can query
+ * callback function to be called from libthinkfinger_acquire
+ * @param state current device status
+ * @param data void pointer to user data
*/
-static void set_status (int swipe_success, int swiped_required, int swipe_failed)
-{
- y2milestone ("Please swipe your finger (successful swipes %i/%i, failed swipes: %i)...",
- swipe_success, swiped_required, swipe_failed);
-}
-
-
-//void ThinkFingerAgent::callback (libthinkfinger_state state, void *data)
static void callback (libthinkfinger_state state, void *data)
{
s_tfdata *tfdata = (s_tfdata *) data;
- switch (state) {
- case TF_STATE_ACQUIRE_SUCCESS:
- y2milestone (" done - success");
- break;
- case TF_STATE_ACQUIRE_FAILED:
- y2milestone (" failed");
- break;
- case TF_STATE_ENROLL_SUCCESS:
- set_status (tfdata->swipe_success, 3, tfdata->swipe_failed);
- y2milestone (" done.\nStoring data (%s)...", tfdata->bir);
- break;
- case TF_STATE_SWIPE_FAILED:
- y2milestone (" TF_STATE_SWIPE_FAILED");
- set_status (tfdata->swipe_success, 3, ++tfdata->swipe_failed);
- break;
- case TF_STATE_SWIPE_SUCCESS:
- y2milestone (" TF_STATE_SWIPE_SUCCESS");
- set_status (++tfdata->swipe_success, 3, tfdata->swipe_failed);
- break;
- case TF_STATE_SWIPE_0:
- y2milestone (" TF_STATE_SWIPE_0");
- set_status (tfdata->swipe_success, 3, tfdata->swipe_failed);
- break;
- default:
- break;
- }
- /*
- global_state = state;
- swipes.swipe_failed = tfdata->swipe_failed;
- swipes.swipe_success = tfdata->swipe_success;
- */
- tfdata->tfagent->global_state = state;
- tfdata->tfagent->swipe_success = tfdata->swipe_success;
- tfdata->tfagent->swipe_failed = tfdata->swipe_failed;
+ if (write (tfdata->write_fd, &state, sizeof (libthinkfinger_state)) == -1)
+ y2error("write to pipe failed: %d (%m)", errno);
}
/**
@@ -81,11 +34,7 @@
*/
ThinkFingerAgent::ThinkFingerAgent() : SCRAgent()
{
- tf = NULL;
- initialized = false;
- global_state = TF_STATE_UNDEFINED;
- swipe_success = 0;
- swipe_failed = 0;
+ child_pid = -1;
}
/**
@@ -110,15 +59,9 @@
*/
YCPValue ThinkFingerAgent::Read(const YCPPath &path, const YCPValue& arg, const YCPValue& opt) {
- y2debug("Path in Read(): %s", path->toString().c_str());
+ y2debug ("Path in Read(): %s", path->toString().c_str());
YCPValue ret = YCPVoid();
- if (!initialized)
- {
- y2error ("ThinkFinger not initialized yet!");
- return ret;
- }
-
if (path->length() == 0) {
ret = YCPString("0");
}
@@ -129,45 +72,36 @@
ret = YCPString ("error_message");
}
else if (PC(0) == "state") {
- YCPMap retmap;
- if (global_state != TF_STATE_UNDEFINED)
+ if (!child_pid)
{
- retmap->add (YCPString ("swipe_success"), YCPInteger (swipe_success));
- retmap->add (YCPString ("swipe_failed"), YCPInteger (swipe_failed));
- switch (global_state) {
- case TF_STATE_ACQUIRE_SUCCESS:
- retmap->add (YCPString ("state"), YCPString ("TF_STATE_ACQUIRE_SUCCESS"));
- break;
- case TF_STATE_ACQUIRE_FAILED:
- retmap->add (YCPString ("state"), YCPString ("TF_STATE_ACQUIRE_FAILED"));
- break;
- case TF_STATE_ENROLL_SUCCESS:
- retmap->add (YCPString ("state"), YCPString ("TF_STATE_ENROLL_SUCCESS"));
- break;
- case TF_STATE_SWIPE_FAILED:
- retmap->add (YCPString ("state"), YCPString ("TF_STATE_SWIPE_FAILED"));
- break;
- case TF_STATE_SWIPE_SUCCESS:
- retmap->add (YCPString ("state"), YCPString ("TF_STATE_SWIPE_SUCCESS"));
- break;
- case TF_STATE_SWIPE_0:
- retmap->add (YCPString ("state"), YCPString ("TF_STATE_SWIPE_0"));
- break;
- default:
- break;
- }
- global_state = TF_STATE_UNDEFINED;
+ y2error ("ThinkFinger not initialized yet!");
+ return ret;
+ }
+ YCPMap retmap;
+ int state;
+ size_t size = sizeof (libthinkfinger_state);
+ int retval = read (data_pipe[0], &state, size);
+ if (retval == -1)
+ {
+ if (errno != EINTR && errno != EAGAIN)
+ y2error ("error reading from pipe: %d (%m)", errno);
+ }
+ else {
+ retmap->add (YCPString ("state"), YCPInteger (state));
+y2internal ("retval from read %d, state is %d", retval, state);
}
return retmap;
}
- // wait for thread exit
+ // wait for child exit
else if (PC(0) == "exit_status" ) {
- int *retval;
- ret = YCPBoolean(false);
- if ( pthread_join( pt, (void**)&retval ) == 0 )
- if ( *retval == 0 )
- ret = YCPBoolean(true);
- libthinkfinger_free (tf);
+y2internal ("waiting for child exit...");
+ int status;
+ int retval = 255;
+ wait (&status);
+ if (WIFEXITED (status))
+ retval = WEXITSTATUS (status);
+ ret = YCPInteger (retval);
+ close (data_pipe[0]); // close FD for reading
}
else {
y2error ("Unknown path in Read(): %s", path->toString().c_str());
@@ -189,11 +123,6 @@
y2debug("Path in Write(): %s", path->toString().c_str());
YCPBoolean ret = YCPBoolean(false);
- if (!initialized) {
- y2error ("ThinkFinger not initialized yet!");
- return ret;
- }
-
if (path->length() == 0) {
ret = YCPBoolean(true);
}
@@ -205,70 +134,98 @@
*/
YCPValue ThinkFingerAgent::Execute(const YCPPath &path, const YCPValue& val, const YCPValue& arg)
{
- y2debug ("Path in Execute(): %s", path->toString().c_str());
+ y2milestone ("Path in Execute(): %s", path->toString().c_str());
YCPValue ret = YCPBoolean(false);
if (path->length() == 1) {
- if (PC(0) == "add-user") {
- string username = "";
+ if (PC(0) == "cancel") {
+y2internal ("killing child process with pid %d", child_pid);
+ if (child_pid)
+ kill (child_pid, 15);
+ // TODO wait and kill -9?
+ child_pid = -1;
+ ret = YCPBoolean (true);
+ }
+ else if (PC(0) == "add-user") {
+ string user;
if (!val.isNull())
{
- username = val->asString()->value();
+ user = val->asString()->value();
}
else
{
- y2error ("username missing");
+ y2error ("username is missing");
return ret;
}
-y2internal ("username is '%s'", username.c_str());
-// TODO check username length?
-// TODO check if user exists? (should be done above...)
- user = username;
-
-y2internal ("thinkfinger agent initialization...");
- libthinkfinger_init_status init_status;
- tf = libthinkfinger_new (&init_status);
- if (init_status != TF_INIT_SUCCESS) {
- y2error ("init failed");
+ if (pipe (data_pipe) == -1) {
+ y2error ("pipe creation failed");
return ret;
}
-y2internal ("... succeeded");
-
- initialized = true;
-
- /*
- s_tfdata tfdata;
-
- tfdata.swipe_success = 0;
- tfdata.swipe_failed = 0;
-// tfdata.tfagent = this;
- snprintf (tfdata.bir, MAX_PATH-1, "%s/%s%s", PAM_BIRDIR, username.c_str(), BIR_EXTENSION);
-y2internal ("data file is '%s'", tfdata.bir);
-
- libthinkfinger_set_file (tf, tfdata.bir);
-
- if (libthinkfinger_set_file (tf, tfdata.bir) < 0)
+ long arg;
+ arg = fcntl (data_pipe[0], F_GETFL);
+ if (fcntl (data_pipe[0], F_SETFL, arg | O_NONBLOCK ) < 0)
+ {
+ y2error ("Couldn't set O_NONBLOCK: errno=%d: %m", errno);
+ close (data_pipe[0]);
+ close (data_pipe[1]);
+ return ret;
+ }
+ child_pid = fork ();
+ if (child_pid == -1)
{
- y2error ("... set_file failed");
- libthinkfinger_free (tf);
- return ret;//TODO free?
+ y2error ("fork failed");
+ return ret;
}
- if (libthinkfinger_set_callback (tf, callback, &tfdata) < 0)
+ else if (child_pid == 0)
{
- y2error ("... set_callback failed");
+ // child: call the acquire function, callback gives the
+ // actual information to parent
+
+ close (data_pipe[0]); // close the read-only FD
+
+ static int retval = 255;
+ s_tfdata tfdata;
+ tfdata.write_fd = data_pipe[1];
+
+ libthinkfinger_init_status init_status;
+ libthinkfinger *tf;
+ tf = libthinkfinger_new (&init_status);
+ if (init_status != TF_INIT_SUCCESS) {
+ y2error ("libthinkfinger_new failed");
+ exit (retval);//FIXME handle sigchld
+ }
+
+ snprintf (tfdata.bir, MAX_PATH-1, "%s/%s%s", PAM_BIRDIR, user.c_str(), BIR_EXTENSION);
+y2internal ("data file is '%s'", tfdata.bir);//FIXME
+// 1. create bir.file in tmpdir
+// 2. move it (and possible rename) in Write
+// 3. remove the old bir file if present in PAM_BIRDIR with org_uid
+// (4. but do not remove the new one of added user of the same name!)
+
+ if (libthinkfinger_set_file (tf, tfdata.bir) < 0)
+ {
+ y2error ("libthinkfinger_set_file failed");
+ libthinkfinger_free (tf);
+ exit (retval);
+ }
+ if (libthinkfinger_set_callback (tf, callback, &tfdata) < 0)
+ {
+ y2error ("libthinkfinger_set_callback failed");
+ libthinkfinger_free (tf);
+ exit (retval);
+ }
+ int tf_state = libthinkfinger_acquire (tf);
+ y2milestone ("acquire done with state %d", tf_state);
+ close (data_pipe[1]);
libthinkfinger_free (tf);
- return ret;//TODO free?
+ exit (tf_state);
}
- */
- if (pthread_create (&pt, NULL, (void*(*)(void*))&call_acquire, this) != 0)
+ else // parent -> return
{
- y2error ("pthread_create failed");
-// libthinkfinger_free (tf);
+ close (data_pipe[1]); // close FD for writing
+ ret = YCPBoolean(true);
}
- else
- ret = YCPBoolean (true);
-
}
}
return ret;
@@ -289,73 +246,3 @@
return YCPNull();
}
-
-//void *ThinkFingerAgent::call_acquire (libthinkfinger *my_tf)
-void *ThinkFingerAgent::call_acquire (ThinkFingerAgent *ag)
-{
- static int retval;
-
- retval = -1;
-
- /*
-y2internal ("thinkfinger agent initialization...");
- libthinkfinger_init_status init_status;
- tf = libthinkfinger_new (&init_status);
- if (init_status != TF_INIT_SUCCESS) {
- y2error ("init failed");
- return ret;
- }
-y2internal ("... succeeded");
-
- initialized = true;
-
- */
- s_tfdata tfdata;
-
- tfdata.swipe_success = 0;
- tfdata.swipe_failed = 0;
- tfdata.tfagent = ag;
- snprintf (tfdata.bir, MAX_PATH-1, "%s/%s%s", PAM_BIRDIR, ag->user.c_str(), BIR_EXTENSION);
-y2internal ("data file is '%s'", tfdata.bir);
-
-// libthinkfinger_set_file (ag->tf, tfdata.bir);
-
- if (libthinkfinger_set_file (ag->tf, tfdata.bir) < 0)
- {
- y2error ("... set_file failed");
-// libthinkfinger_free (ag->tf);
- pthread_exit((void*)&retval);
- }
- if (libthinkfinger_set_callback (ag->tf, callback, &tfdata) < 0)
- {
- y2error ("... set_callback failed");
-// libthinkfinger_free (ag->tf);
- pthread_exit((void*)&retval);
- }
-
-
-y2internal ("acquiring...");
- int tf_state = libthinkfinger_acquire (ag->tf);
-y2internal ("acquire done");
- switch (tf_state) {
- case TF_STATE_ACQUIRE_SUCCESS:
- y2internal ("TF_STATE_ACQUIRE_SUCCESS!");
- retval = 0;
- break;
- case TF_STATE_ACQUIRE_FAILED:
- y2error ("TF_STATE_ACQUIRE_FAILED");
- break;
- case TF_STATE_USB_ERROR:
- y2error ("Could not acquire fingerprint (USB error).");
- break;
- case TF_RESULT_COMM_FAILED:
- y2error ("Could not acquire fingerprint (communication with fingerprint reader failed).");
- break;
- default:
- y2error ("Undefined error occured (%i).", tf_state);
- break;
- }
-// TODO it is possible that libthinkfinger_acquire ends without providing TF_STATE_ACQUIRE_SUCCESS/TF_STATE_ACQUIRE_FAILED
- y2internal ("retval is %i", retval);
- pthread_exit((void*)&retval);
-}
Modified: trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.h?rev=39505&r1=39504&r2=39505&view=diff
==============================================================================
--- trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.h (original)
+++ trunk/fingerprint-reader/agent-thinkfinger/src/ThinkFingerAgent.h Wed Jul 18 15:37:21 2007
@@ -15,23 +15,15 @@
using namespace std;
-#include <iostream>
#include