PIP Bugfixes #207

Merged
peri4 merged 12 commits from bugfixes into master 2026-08-05 13:32:11 +03:00
6 changed files with 66 additions and 41 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ endif()
project(PIP) project(PIP)
set(PIP_MAJOR 5) set(PIP_MAJOR 5)
set(PIP_MINOR 8) set(PIP_MINOR 8)
set(PIP_REVISION 0) set(PIP_REVISION 1)
set(PIP_SUFFIX _beta) set(PIP_SUFFIX _beta)
set(PIP_COMPANY SHS) set(PIP_COMPANY SHS)
set(PIP_DOMAIN org.SHS) set(PIP_DOMAIN org.SHS)
+1 -1
View File
@@ -880,7 +880,7 @@ bool PITerminal::initialize() {
execvp(argv[0], argv); execvp(argv[0], argv);
delete[] argv[0]; delete[] argv[0];
delete[] argv; delete[] argv;
exit(0); exit(errno);
} else { } else {
if (fr < 0 || PRIVATE->fd < 0) { if (fr < 0 || PRIVATE->fd < 0) {
piCoutObj << "forkpty error," << errorString(); piCoutObj << "forkpty error," << errorString();
+5 -4
View File
@@ -89,12 +89,13 @@ bool PIWaitEvent::wait(int fd, CheckRole role) {
FD_SET(pipe_fd[ReadEnd], &(fds[CheckRead])); FD_SET(pipe_fd[ReadEnd], &(fds[CheckRead]));
FD_SET(fd, &(fds[CheckExeption])); FD_SET(fd, &(fds[CheckExeption]));
if (fd_index != CheckExeption) FD_SET(fd, &(fds[fd_index])); if (fd_index != CheckExeption) FD_SET(fd, &(fds[fd_index]));
int sr = ::select(nfds, &(fds[CheckRead]), &(fds[CheckWrite]), &(fds[CheckExeption]), nullptr); int sr = ::select(nfds, &(fds[CheckRead]), &(fds[CheckWrite]), &(fds[CheckExeption]), nullptr);
if (sr < 0) return false;
errorClear();
int buf = 0; int buf = 0;
while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0) while (::read(pipe_fd[ReadEnd], &buf, sizeof(buf)) > 0) {}
;
// piCout << "wait result" << sr << FD_ISSET(fd, &(fds[CheckExeption])) << FD_ISSET(fd, &(fds[fd_index])); // piCout << "wait result" << sr << FD_ISSET(fd, &(fds[CheckExeption])) << FD_ISSET(fd, &(fds[fd_index]));
if (sr == EBADF || sr == EINTR) return false; if (errno == EBADF || errno == EINTR) return false;
if (FD_ISSET(fd, &(fds[CheckExeption]))) return true; if (FD_ISSET(fd, &(fds[CheckExeption]))) return true;
return FD_ISSET(fd, &(fds[fd_index])); return FD_ISSET(fd, &(fds[fd_index]));
#endif #endif
+24 -10
View File
@@ -102,7 +102,11 @@
#ifndef WINDOWS #ifndef WINDOWS
PIString getSockAddr(sockaddr * s) { PIString getSockAddr(sockaddr * s) {
return s == 0 ? PIString() : PIStringAscii(inet_ntoa(((sockaddr_in *)s)->sin_addr)); if (!s) return PIString();
char buf[INET_ADDRSTRLEN];
piZeroMemory(buf, sizeof(buf));
const char * r = inet_ntop(AF_INET, &((sockaddr_in *)s)->sin_addr, buf, sizeof(buf));
return r ? PIStringAscii(r) : PIString();
} }
#endif #endif
@@ -861,6 +865,7 @@ ssize_t PIEthernet::writeDevice(const void * data, ssize_t max_size) {
return -1; return -1;
} }
} }
ret += sr;
remain_data += sr; remain_data += sr;
remain_size -= sr; remain_size -= sr;
} }
@@ -1175,13 +1180,19 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
# else # else
# ifdef ANDROID # ifdef ANDROID
struct ifconf ifc; struct ifconf ifc;
int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP); int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (s == -1) {
piCout << "[PIEthernet]"
<< "Can`t create socket: %1"_tr("PIEthernet").arg(errorString());
return il;
}
ifc.ifc_len = 256; ifc.ifc_len = 256;
ifc.ifc_buf = new char[ifc.ifc_len]; ifc.ifc_buf = new char[ifc.ifc_len];
if (ioctl(s, SIOCGIFCONF, &ifc) < 0) { if (ioctl(s, SIOCGIFCONF, &ifc) < 0) {
piCout << "[PIEthernet]" piCout << "[PIEthernet]"
<< "Can`t get interfaces: %1"_tr("PIEthernet").arg(errorString()); << "Can`t get interfaces: %1"_tr("PIEthernet").arg(errorString());
delete[] ifc.ifc_buf; delete[] ifc.ifc_buf;
::close(s);
return il; return il;
} }
int icnt = ifc.ifc_len / sizeof(ifreq); int icnt = ifc.ifc_len / sizeof(ifreq);
@@ -1200,7 +1211,8 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
if (ci.address == "127.0.0.1") ci.flags |= PIEthernet::ifLoopback; if (ci.address == "127.0.0.1") ci.flags |= PIEthernet::ifLoopback;
il << ci; il << ci;
} }
delete ifc.ifc_buf; delete[] ifc.ifc_buf;
::close(s);
# else # else
struct ifaddrs *ret, *cif = 0; struct ifaddrs *ret, *cif = 0;
int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP); int s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
@@ -1291,8 +1303,10 @@ PINetworkAddress PIEthernet::interfaceAddress(const PIString & interface_) {
piZeroMemory(ifr); piZeroMemory(ifr);
strcpy(ifr.ifr_name, interface_.dataAscii()); strcpy(ifr.ifr_name, interface_.dataAscii());
int s = ::socket(AF_INET, SOCK_DGRAM, 0); int s = ::socket(AF_INET, SOCK_DGRAM, 0);
ioctl(s, SIOCGIFADDR, &ifr); if (s != -1) {
::close(s); ioctl(s, SIOCGIFADDR, &ifr);
::close(s);
}
struct sockaddr_in * sa = (struct sockaddr_in *)&ifr.ifr_addr; struct sockaddr_in * sa = (struct sockaddr_in *)&ifr.ifr_addr;
return PINetworkAddress(uint(sa->sin_addr.s_addr)); return PINetworkAddress(uint(sa->sin_addr.s_addr));
#endif #endif
@@ -1413,13 +1427,13 @@ void PIEthernet::ethClosesocket(int sock, bool shutdown) {
int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * optval, int optlen) { int PIEthernet::ethSetsockopt(int sock, int level, int optname, const void * optval, int optlen) {
if (sock < 0) return -1; if (sock < 0) return -1;
auto ret = setsockopt(sock, auto ret = setsockopt(sock,
level, level,
optname, optname,
#ifdef WINDOWS #ifdef WINDOWS
(char *) (char *)
#endif #endif
optval, optval,
optlen); optlen);
if (ret != 0) piCout << "setsockopt error:" << ethErrorString(); if (ret != 0) piCout << "setsockopt error:" << ethErrorString();
return ret; return ret;
} }
+28 -18
View File
@@ -56,17 +56,17 @@
#else #else
# define BINARY_STREAM_FRIEND(T) \ # define BINARY_STREAM_FRIEND(T) \
template<typename P> \ template<typename P> \
friend PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const T & v); \ friend PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const T & v); \
template<typename P> \ template<typename P> \
friend PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, T & v); friend PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, T & v);
# define BINARY_STREAM_WRITE(T) \ # define BINARY_STREAM_WRITE(T) \
template<typename P> \ template<typename P> \
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const T & v) inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const T & v)
# define BINARY_STREAM_READ(T) \ # define BINARY_STREAM_READ(T) \
template<typename P> \ template<typename P> \
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, T & v) inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, T & v)
#endif #endif
@@ -410,7 +410,7 @@ template<typename P,
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector trivial default"; // piCout << ">> vector trivial default";
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError() || sz < 0) {
fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
@@ -433,7 +433,7 @@ template<typename P,
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
// piCout << ">> vector trivial custom"; // piCout << ">> vector trivial custom";
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError() || sz < 0) {
fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
@@ -462,7 +462,7 @@ template<typename P,
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque trivial default"; // piCout << ">> deque trivial default";
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError() || sz < 0) {
fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
@@ -485,7 +485,7 @@ template<typename P,
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
// piCout << ">> deque trivial custom"; // piCout << ">> deque trivial custom";
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError() || sz < 0) {
fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
@@ -516,7 +516,7 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v)
int r, c; int r, c;
r = s.binaryStreamTakeInt(); r = s.binaryStreamTakeInt();
c = s.binaryStreamTakeInt(); c = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError() || r < 0 || c < 0) {
fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
@@ -542,6 +542,11 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v)
PIVector<T> tmp; PIVector<T> tmp;
r = s.binaryStreamTakeInt(); r = s.binaryStreamTakeInt();
c = s.binaryStreamTakeInt(); c = s.binaryStreamTakeInt();
if (s.wasReadError() || r < 0 || c < 0) {
fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
s >> tmp; s >> tmp;
if (s.wasReadError()) { if (s.wasReadError()) {
fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
@@ -618,7 +623,7 @@ template<typename P, typename T, typename std::enable_if<!std::is_trivially_copy
//! \~russian Восстанавливает %PIVector из нетривиальных элементов по одному. //! \~russian Восстанавливает %PIVector из нетривиальных элементов по одному.
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector<T> & v) {
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError() || sz < 0) {
fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
@@ -641,7 +646,7 @@ template<typename P, typename T, typename std::enable_if<!std::is_trivially_copy
//! \~russian Восстанавливает %PIDeque из нетривиальных элементов по одному. //! \~russian Восстанавливает %PIDeque из нетривиальных элементов по одному.
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIDeque<T> & v) {
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError() || sz < 0) {
fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIDeque<%s>\n", __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
@@ -667,6 +672,11 @@ inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIVector2D<T> & v)
PIVector<T> tmp; PIVector<T> tmp;
r = s.binaryStreamTakeInt(); r = s.binaryStreamTakeInt();
c = s.binaryStreamTakeInt(); c = s.binaryStreamTakeInt();
if (s.wasReadError() || r < 0 || c < 0) {
fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
v.clear();
return s;
}
s >> tmp; s >> tmp;
if (s.wasReadError()) { if (s.wasReadError()) {
fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIVector2D<%s>\n", __PIP_TYPENAME__(T));
@@ -700,7 +710,7 @@ template<typename P, typename Key, typename T>
//! \~russian Восстанавливает ключи и значения %PIMap. //! \~russian Восстанавливает ключи и значения %PIMap.
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key, T> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PIMap<Key, T> & v) {
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError() || sz < 0) {
fprintf(stderr, "error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T)); fprintf(stderr, "error with PIMap<%s, %s>\n", __PIP_TYPENAME__(Key), __PIP_TYPENAME__(T));
v.clear(); v.clear();
return s; return s;
@@ -749,7 +759,7 @@ template<typename P, typename Key>
//! \~russian Восстанавливает ключи %PISet. //! \~russian Восстанавливает ключи %PISet.
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PISet<Key> & v) { inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, PISet<Key> & v) {
int sz = s.binaryStreamTakeInt(); int sz = s.binaryStreamTakeInt();
if (s.wasReadError()) { if (s.wasReadError() || sz < 0) {
fprintf(stderr, "error with PISet<%s>\n", __PIP_TYPENAME__(Key)); fprintf(stderr, "error with PISet<%s>\n", __PIP_TYPENAME__(Key));
v.clear(); v.clear();
return s; return s;
+7 -7
View File
@@ -215,10 +215,10 @@ PRIVATE_DEFINITION_START(PIProcess)
PeekNamedPipe(pipes[pipe_type][PipeRead], nullptr, 0, nullptr, &available, nullptr); PeekNamedPipe(pipes[pipe_type][PipeRead], nullptr, 0, nullptr, &available, nullptr);
if (available > 0) { if (available > 0) {
BOOL ok = ReadFile(pipes[pipe_type][PipeRead], BOOL ok = ReadFile(pipes[pipe_type][PipeRead],
read_buffer.data(offset), read_buffer.data(offset),
piMini(available, read_buffer.size() - offset), piMini(available, read_buffer.size() - offset),
&bytes_read, &bytes_read,
nullptr); nullptr);
if (!ok) bytes_read = 0; if (!ok) bytes_read = 0;
} }
# else # else
@@ -293,10 +293,10 @@ void PIProcess::startProc(bool detached) {
si.dwFlags |= STARTF_USESTDHANDLES; si.dwFlags |= STARTF_USESTDHANDLES;
const auto cmd = convertWindowsCmd(args); const auto cmd = convertWindowsCmd(args);
if (CreateProcessA(0, // No module name (use command line) if (CreateProcessA(0, // No module name (use command line)
(LPSTR)cmd.data(), // Command line (LPSTR)cmd.data(), // Command line
0, // Process handle not inheritable 0, // Process handle not inheritable
0, // Thread handle not inheritable 0, // Thread handle not inheritable
true, // Set handle inheritance to FALSE true, // Set handle inheritance to FALSE
detached ? DETACHED_PROCESS /*CREATE_NEW_CONSOLE*/ : 0, // Creation flags detached ? DETACHED_PROCESS /*CREATE_NEW_CONSOLE*/ : 0, // Creation flags
0, // Use environment 0, // Use environment
wd.isEmpty() ? 0 : wd.data(), // Use working directory wd.isEmpty() ? 0 : wd.data(), // Use working directory
@@ -322,7 +322,7 @@ void PIProcess::startProc(bool detached) {
if (!detached) PRIVATE->pid = pid_; if (!detached) PRIVATE->pid = pid_;
if (pid_ == 0) { if (pid_ == 0) {
if (!wd.isEmpty()) { if (!wd.isEmpty()) {
if (!chdir(wd.data())) piCoutObj << "Error while set working directory"; if (chdir(wd.data()) != 0) piCoutObj << "Error while set working directory";
} }
PRIVATE->closePipe(StdIn, PipeWrite); PRIVATE->closePipe(StdIn, PipeWrite);
PRIVATE->closePipe(StdOut, PipeRead); PRIVATE->closePipe(StdOut, PipeRead);