1 /* This file is part of the KDE project
2 Copyright (C) 2000-2002 Alexander Neundorf <neundorf@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
22 #include <config-runtime.h>
25 #include <sys/ioctl.h>
27 #include <sys/types.h>
29 #include <sys/socket.h>
35 Program::Program(const QStringList
&args
)
56 ::waitpid(m_pid
,&s
,0);
58 ::waitpid(m_pid
,&s
,WNOHANG
);
64 if (mStarted
) return false;
65 if (pipe(mStdout
)==-1) return false;
66 if (pipe(mStdin
)==-1) return false;
67 if (pipe(mStderr
)==-1) return false;
69 int notificationPipe
[2];
70 if (pipe(notificationPipe
)==-1) return false;
80 ::close(notificationPipe
[1]);
84 FD_SET(notificationPipe
[0],¬ifSet
);
86 //wait up to five seconds
88 kDebug(7101)<<"**** waiting for notification";
92 int result
=::select(notificationPipe
[0]+1,¬ifSet
,0,0,&tv
);
95 kDebug(7101)<<"**** waiting for notification: failed "<<result;
102 result
=::read(notificationPipe
[0],buf
,256);
103 //if execvp() failed the child sends us "failed"
107 kDebug(7101)<<"**** waiting for notification: succeeded"<<result
;
117 ::close(notificationPipe
[0]);
128 fcntl(mStdin
[0], F_SETFD
, FD_CLOEXEC
);
129 fcntl(mStdout
[1], F_SETFD
, FD_CLOEXEC
);
130 fcntl(mStderr
[1], F_SETFD
, FD_CLOEXEC
);
132 char **arglist
=(char**)malloc((mArgs
.count()+1)*sizeof(char*));
135 for (QStringList::const_iterator it
=mArgs
.constBegin(); it
!=mArgs
.constEnd(); ++it
)
137 arglist
[c
]=(char*)malloc((*it
).length()+1);
138 strcpy(arglist
[c
], (*it
).toLatin1());
141 arglist
[mArgs
.count()]=0;
142 //make parsing easier
143 putenv(strdup("LANG=C"));
144 execvp(arglist
[0], arglist
);
145 //we only get here if execvp() failed
146 ::write(notificationPipe
[1],"failed",strlen("failed"));
147 ::close(notificationPipe
[1]);
153 bool Program::isRunning()
158 int Program::select(int secs
, int usecs
, bool& stdoutReceived
, bool& stderrReceived
/*, bool& stdinWaiting*/)
160 stdoutReceived
=false;
161 stderrReceived
=false;
169 FD_SET(stdoutFD(),&readFDs
);
170 FD_SET(stderrFD(),&readFDs
);
172 int maxFD
=stdoutFD();
173 if (stderrFD()>maxFD
) maxFD
=stderrFD();
177 FD_SET(stdinFD(),&writeFDs);
178 if (stdinFD()>maxFD) maxFD=stdinFD();*/
181 int result
=::select(maxFD
,&readFDs
,/*&writeFDs*/0,0,&tv
);
184 stdoutReceived
=FD_ISSET(stdoutFD(),&readFDs
);
185 stderrReceived
=FD_ISSET(stderrFD(),&readFDs
);
186 //stdinWaiting=(FD_ISSET(stdinFD(),&writeFDs));
195 return ::kill(m_pid
, SIGTERM
);
196 //::kill(m_pid, SIGKILL);