Re: libchipcard3-3.0.2: Unknown argument "tapi/@[email protected]"
Martin Preuss <[email protected]>
| Newsgroups | gmane.comp.lib.libchipcard.devel |
|---|---|
| Message-ID | <[email protected]> |
On Monday 12 March 2007 12:30, Martin Preuss wrote: [...] > Stimmt, der entsprechende Code in Gwen hat bisher mit Puffern von 128 Bytes > gearbeitet. Das da jemand mit so einem langen Pfad kommt... :-) > > Ich habe das hier mal geaendert, sodass die Laenge der Argumente nun nicht > mehr begrenzt ist. > > Werde das erst mal testen und dann ins SVN von Gwen einchecken. [...] Ok, ist drin (in trunk und im neuen 3er-Branch). Die naechste Release von Gwen wird diesen fix also enthalten. Wenn Du nicht darauf warten willst, kannst Du einfach die angehaengte Datei nach src/os/posix/ kopieren und neu kompilieren. Gruss Martin -- "Things are only impossible until they're not" AqBanking - http://www.aqbanking.de/ LibChipcard - http://www.libchipcard.de/ ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Libchipcard-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libchipcard-devel
process.c
(text/x-csrc, 12.2 KB)
/***************************************************************************
$RCSfile$
-------------------
cvs : $Id: process.c 1179 2007-03-12 11:31:57Z martin $
begin : Sat Dec 27 2003
copyright : (C) 2003 by Martin Preuss
email : [email protected]
***************************************************************************
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
* MA 02111-1307 USA *
* *
***************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "process_p.h"
#include <gwenhywfar/misc.h>
#include <gwenhywfar/debug.h>
#include <gwenhywfar/text.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
static GWEN_PROCESS *GWEN_Process_ProcessList=0;
GWEN_ERRORCODE GWEN_Process_ModuleInit(){
return 0;
}
GWEN_ERRORCODE GWEN_Process_ModuleFini(){
GWEN_PROCESS *pr, *prnext;
pr=GWEN_Process_ProcessList;
while(pr) {
prnext=pr->next;
pr->usage=1;
GWEN_Process_free(pr);
pr=prnext;
} /* while */
return 0;
}
GWEN_PROCESS *GWEN_Process_FindProcess(pid_t pid){
GWEN_PROCESS *pr;
pr=GWEN_Process_ProcessList;
while(pr) {
if (pr->pid==pid)
return pr;
pr=pr->next;
} /* while */
return 0;
}
void GWEN_Process_SignalHandler(int s) {
int status;
pid_t pid;
switch(s) {
case SIGCHLD:
/* try to get the status */
pid=waitpid(0, &status, WNOHANG);
if (pid==-1) {
DBG_DEBUG(GWEN_LOGDOMAIN, "waitdpid(%d): %s", 0, strerror(errno));
}
else if (pid==0) {
/* process still running ?! */
DBG_DEBUG(GWEN_LOGDOMAIN, "Got a SIGCHLD but no child terminated ??");
}
else {
GWEN_PROCESS *pr;
/* som process terminated */
pr=GWEN_Process_FindProcess(pid);
if (!pr) {
DBG_NOTICE(GWEN_LOGDOMAIN, "No infomation about process \"%d\" available", (int)pid);
}
else {
GWEN_Process_MakeState(pr, status);
/* remove from list. If this process data is not used by the
* aplication it will now be freed, otherwise only the usage
* counter is decremented */
GWEN_Process_free(pr);
}
}
break;
default:
DBG_ERROR(GWEN_LOGDOMAIN, "Got unhandled signal \"%d\"", s);
break;
} /* switch */
}
GWEN_PROCESS *GWEN_Process_new(){
GWEN_PROCESS *pr;
GWEN_NEW_OBJECT(GWEN_PROCESS, pr);
pr->state=GWEN_ProcessStateNotStarted;
pr->pid=-1;
pr->pflags=GWEN_PROCESS_FLAGS_DEFAULT;
pr->usage=1;
GWEN_LIST_ADD(GWEN_PROCESS, pr, &GWEN_Process_ProcessList);
return pr;
}
void GWEN_Process_free(GWEN_PROCESS *pr){
if (pr) {
assert(pr->usage);
if (--(pr->usage)==0) {
/* unlink from list */
GWEN_LIST_DEL(GWEN_PROCESS, pr, &GWEN_Process_ProcessList);
GWEN_BufferedIO_free(pr->stdIn);
GWEN_BufferedIO_free(pr->stdOut);
GWEN_BufferedIO_free(pr->stdErr);
GWEN_FREE_OBJECT(pr);
}
}
}
GWEN_PROCESS_STATE GWEN_Process_Start(GWEN_PROCESS *pr,
const char *prg,
const char *args){
pid_t pid;
char *argv[32];
int argc;
const char *p, *p2;
GWEN_BUFFER *wbuf;
assert(pr);
if (GWEN_Process_Redirect(pr)) {
DBG_ERROR(GWEN_LOGDOMAIN, "Could not setup redirections");
pr->state=GWEN_ProcessStateNotStarted;
pr->pid=-1;
return GWEN_ProcessStateNotStarted;
}
pid=fork();
if (pid==-1) {
/* error in fork */
pr->state=GWEN_ProcessStateNotStarted;
pr->pid=-1;
/* close all pipes */
if (pr->filesStdin[0]!=-1) {
close(pr->filesStdin[0]);
close(pr->filesStdin[1]);
}
if (pr->filesStdout[0]!=-1) {
close(pr->filesStdout[0]);
close(pr->filesStdout[1]);
}
if (pr->filesStderr[0]!=-1) {
close(pr->filesStderr[0]);
close(pr->filesStderr[1]);
}
return GWEN_ProcessStateNotStarted;
}
else if (pid!=0) {
/* parent */
DBG_INFO(GWEN_LOGDOMAIN, "Process started with id %d", (int)pid);
pr->state=GWEN_ProcessStateRunning;
pr->pid=pid;
/* setup redirections */
if (pr->filesStdin[0]!=-1) {
close(pr->filesStdin[1]);
pr->stdIn=GWEN_BufferedIO_File_new(pr->filesStdin[0]);
GWEN_BufferedIO_SetWriteBuffer(pr->stdIn, 0, 128);
}
if (pr->filesStdout[0]!=-1) {
close(pr->filesStdout[1]);
pr->stdOut=GWEN_BufferedIO_File_new(pr->filesStdout[0]);
GWEN_BufferedIO_SetReadBuffer(pr->stdOut, 0, 128);
}
if (pr->filesStderr[0]!=-1) {
close(pr->filesStderr[1]);
pr->stdErr=GWEN_BufferedIO_File_new(pr->filesStdout[0]);
GWEN_BufferedIO_SetReadBuffer(pr->stdErr, 0, 128);
}
return GWEN_ProcessStateRunning;
}
/* child, build arguments */
argc=0;
DBG_DEBUG(GWEN_LOGDOMAIN, "I'm the child process");
/* setup redirections */
if (pr->filesStdin[0]!=-1) {
close(pr->filesStdin[0]);
close(0);
if (dup(pr->filesStdin[1])==-1) {
DBG_ERROR(GWEN_LOGDOMAIN, "Could not setup redirection");
}
}
if (pr->filesStdout[0]!=-1) {
close(pr->filesStdout[0]);
close(1);
if (dup(pr->filesStdout[1])==-1) {
DBG_ERROR(GWEN_LOGDOMAIN, "Could not setup redirection");
}
}
if (pr->filesStderr[0]!=-1) {
close(pr->filesStderr[0]);
close(2);
if (dup(pr->filesStderr[1])==-1) {
DBG_ERROR(GWEN_LOGDOMAIN, "Could not setup redirection");
}
}
argv[0]=strdup(prg);
argc++;
p=args;
wbuf=GWEN_Buffer_new(0, 256, 0, 1);
while(argc<32 && *p) {
while(*p && isspace((int)*p))
p++;
if (!(*p))
break;
if (GWEN_Text_GetWordToBuffer(p, " ",
wbuf,
GWEN_TEXT_FLAGS_NULL_IS_DELIMITER |
GWEN_TEXT_FLAGS_DEL_QUOTES |
GWEN_TEXT_FLAGS_CHECK_BACKSLASH,
&p))
break;
p2=GWEN_Buffer_GetStart(wbuf);
argv[argc]=strdup(p2);
GWEN_Buffer_Reset(wbuf);
argc++;
} /* while */
GWEN_Buffer_free(wbuf);
argv[argc]=0;
/* parameters ready, exec */
execvp(prg, argv);
/* if we reach this point an error occurred */
DBG_ERROR(GWEN_LOGDOMAIN, "Could not start program \"%s\": %s",
prg, strerror(errno));
exit(EXIT_FAILURE);
}
GWEN_PROCESS_STATE GWEN_Process_GetState(GWEN_PROCESS *pr, int w){
int rv;
int status;
assert(pr);
/* try to get the status */
rv=waitpid(pr->pid, &status, w?0:WNOHANG);
if (rv==-1) {
DBG_ERROR(GWEN_LOGDOMAIN, "waitdpid(%d): %s", (int)pr->pid, strerror(errno));
return GWEN_ProcessStateUnknown;
}
else if (rv==0) {
/* process still running */
return GWEN_ProcessStateRunning;
}
else {
return GWEN_Process_MakeState(pr, status);
}
}
GWEN_PROCESS_STATE GWEN_Process_MakeState(GWEN_PROCESS *pr, int status){
/* process has terminated for any reason */
if (WIFEXITED(status)) {
/* normal termination */
DBG_INFO(GWEN_LOGDOMAIN, "Process %d exited with %d",
(int)pr->pid, WEXITSTATUS(status));
pr->state=GWEN_ProcessStateExited;
pr->pid=-1;
/* store result code */
pr->result=WEXITSTATUS(status);
return pr->state;
} /* if exited normally */
else if (WIFSIGNALED(status)) {
/* uncaught signal */
DBG_ERROR(GWEN_LOGDOMAIN, "Process %d terminated by signal %d",
(int)pr->pid, WTERMSIG(status));
pr->state=GWEN_ProcessStateAborted;
pr->pid=-1;
return pr->state;
} /* if terminated by signal */
else if (WIFSTOPPED(status)) {
/* process stopped by signal */
DBG_ERROR(GWEN_LOGDOMAIN, "Process %d stopped by signal %d",
(int)pr->pid, WSTOPSIG(status));
pr->state=GWEN_ProcessStateStopped;
pr->pid=-1;
return pr->state;
}
else {
DBG_ERROR(GWEN_LOGDOMAIN, "Unhandled status, assume process %d isn't running (%08x)",
(int)pr->pid, (unsigned int)status);
return GWEN_ProcessStateUnknown;
}
}
GWEN_PROCESS_STATE GWEN_Process_CheckState(GWEN_PROCESS *pr){
assert(pr);
if (pr->pid==-1)
/* we already know the state, return it */
return pr->state;
/* otherwise try to get the status */
return GWEN_Process_GetState(pr, 0);
}
int GWEN_Process_GetResult(GWEN_PROCESS *pr){
assert(pr);
if (GWEN_Process_CheckState(pr)==GWEN_ProcessStateExited)
return pr->result;
else
return -1;
}
int GWEN_Process_Wait(GWEN_PROCESS *pr){
GWEN_PROCESS_STATE pst;
assert(pr);
if (pr->state!=GWEN_ProcessStateRunning)
/* process is not running, so return */
return 0;
if (pr->pid==-1) {
/* process is running, but we have no pid ?! */
DBG_ERROR(GWEN_LOGDOMAIN, "Process is running but we don't have its pid");
return -1;
}
pst=GWEN_Process_GetState(pr, 1);
if (pst==GWEN_ProcessStateUnknown)
return -1;
return 0;
}
int GWEN_Process_Terminate(GWEN_PROCESS *pr){
assert(pr);
if (pr->state!=GWEN_ProcessStateRunning) {
/* process is not running, so return */
DBG_INFO(GWEN_LOGDOMAIN, "Process is not running, doing nothing");
return 0;
}
if (pr->pid==-1) {
/* process is running, but we have no pid ?! */
DBG_ERROR(GWEN_LOGDOMAIN, "Process is running but we don't have its pid");
return -1;
}
/* kill process */
if (kill(pr->pid, SIGKILL)) {
DBG_ERROR(GWEN_LOGDOMAIN, "Error on kill(%d, SIGKILL): %s",
(int)pr->pid, strerror(errno));
return -1;
}
/* wait for process to respond to kill signal (should not take long) */
return GWEN_Process_Wait(pr);
}
GWEN_TYPE_UINT32 GWEN_Process_GetFlags(const GWEN_PROCESS *pr){
assert(pr);
return pr->pflags;
}
void GWEN_Process_SetFlags(GWEN_PROCESS *pr, GWEN_TYPE_UINT32 f){
assert(pr);
pr->pflags=f;
}
void GWEN_Process_AddFlags(GWEN_PROCESS *pr, GWEN_TYPE_UINT32 f){
assert(pr);
pr->pflags|=f;
}
void GWEN_Process_SubFlags(GWEN_PROCESS *pr, GWEN_TYPE_UINT32 f){
assert(pr);
pr->pflags&=~f;
}
GWEN_BUFFEREDIO *GWEN_Process_GetStdin(const GWEN_PROCESS *pr){
assert(pr);
return pr->stdIn;
}
GWEN_BUFFEREDIO *GWEN_Process_GetStdout(const GWEN_PROCESS *pr){
assert(pr);
return pr->stdOut;
}
GWEN_BUFFEREDIO *GWEN_Process_GetStderr(const GWEN_PROCESS *pr){
assert(pr);
return pr->stdErr;
}
int GWEN_Process_Redirect(GWEN_PROCESS *pr) {
assert(pr);
pr->filesStdin[0]=-1;
pr->filesStdout[0]=-1;
pr->filesStderr[0]=-1;
if (pr->pflags & GWEN_PROCESS_FLAGS_REDIR_STDIN) {
int filedes[2];
DBG_DEBUG(GWEN_LOGDOMAIN, "Redirecting stdin");
if (pipe(filedes)) {
DBG_ERROR(GWEN_LOGDOMAIN, "pipe(): %s", strerror(errno));
return -1;
}
pr->filesStdin[0]=filedes[1];
pr->filesStdin[1]=filedes[0];
}
if (pr->pflags & GWEN_PROCESS_FLAGS_REDIR_STDOUT) {
int filedes[2];
DBG_DEBUG(GWEN_LOGDOMAIN, "Redirecting stdout");
if (pipe(filedes)) {
DBG_ERROR(GWEN_LOGDOMAIN, "pipe(): %s", strerror(errno));
return -1;
}
pr->filesStdout[0]=filedes[0];
pr->filesStdout[1]=filedes[1];
}
if (pr->pflags & GWEN_PROCESS_FLAGS_REDIR_STDERR) {
int filedes[2];
DBG_DEBUG(GWEN_LOGDOMAIN, "Redirecting stderr");
if (pipe(filedes)) {
DBG_ERROR(GWEN_LOGDOMAIN, "pipe(): %s", strerror(errno));
return -1;
}
pr->filesStderr[0]=filedes[0];
pr->filesStderr[1]=filedes[1];
}
return 0;
}