13
0

Add API to write raw data to child processes.

This commit is contained in:
Robin Gareus 2018-11-19 02:26:43 +01:00
parent 3977fbae51
commit 103ef2ba08
2 changed files with 28 additions and 21 deletions

View File

@ -164,12 +164,19 @@ class LIBPBD_API SystemExec
*/ */
void close_stdin (); void close_stdin ();
/** write into child-program's STDIN /** write into child-program's STDIN
* @param d data to write * @param d text to write
* @param len length of data to write, if it is 0 (zero), d.length() is * @param len length of data to write, if it is 0 (zero), d.length() is
* used to determine the number of bytes to transmit. * used to determine the number of bytes to transmit.
* @return number of bytes written. * @return number of bytes written.
*/ */
int write_to_stdin (std::string d, size_t len=0); size_t write_to_stdin (std::string const& d, size_t len=0);
/** write into child-program's STDIN
* @param data data to write
* @param bytes length of data to write
* @return number of bytes written.
*/
size_t write_to_stdin (const void* d, size_t bytes=0);
/** The ReadStdout signal is emitted when the application writes to STDOUT. /** The ReadStdout signal is emitted when the application writes to STDOUT.
* it passes the written data and its length in bytes as arguments to the bound * it passes the written data and its length in bytes as arguments to the bound

View File

@ -351,6 +351,16 @@ SystemExec::to_s () const
#endif #endif
} }
size_t
SystemExec::write_to_stdin (std::string const& d, size_t len)
{
const char *data = d.c_str();
if (len == 0) {
len = d.length();
}
return write_to_stdin ((const void*)data, len);
}
#ifdef PLATFORM_WINDOWS /* Windows Process */ #ifdef PLATFORM_WINDOWS /* Windows Process */
/* HELPER FUNCTIONS */ /* HELPER FUNCTIONS */
@ -582,21 +592,16 @@ SystemExec::close_stdin()
destroy_pipe(stdinP); destroy_pipe(stdinP);
} }
int size_t
SystemExec::write_to_stdin(std::string d, size_t len) SystemExec::write_to_stdin(const void* data, size_t bytes)
{ {
const char *data;
DWORD r,c; DWORD r,c;
::pthread_mutex_lock(&write_lock); ::pthread_mutex_lock(&write_lock);
data=d.c_str();
if (len == 0) {
len=(d.length());
}
c=0; c=0;
while (c < len) { while (c < bytes) {
if (!WriteFile(stdinP[1], data+c, len-c, &r, NULL)) { if (!WriteFile(stdinP[1], data+c, bytes-c, &r, NULL)) {
if (GetLastError() == 0xE8 /*NT_STATUS_INVALID_USER_BUFFER*/) { if (GetLastError() == 0xE8 /*NT_STATUS_INVALID_USER_BUFFER*/) {
Sleep(100); Sleep(100);
continue; continue;
@ -950,27 +955,22 @@ SystemExec::close_stdin()
close_fd(pout[1]); close_fd(pout[1]);
} }
int size_t
SystemExec::write_to_stdin(std::string d, size_t len) SystemExec::write_to_stdin(const void* data, size_t bytes)
{ {
const char *data;
ssize_t r; ssize_t r;
size_t c; size_t c;
::pthread_mutex_lock(&write_lock); ::pthread_mutex_lock(&write_lock);
data=d.c_str();
if (len == 0) {
len=(d.length());
}
c=0; c=0;
while (c < len) { while (c < bytes) {
for (;;) { for (;;) {
r=::write(pin[1], data+c, len-c); r=::write(pin[1], data+c, bytes-c);
if (r < 0 && (errno == EINTR || errno == EAGAIN)) { if (r < 0 && (errno == EINTR || errno == EAGAIN)) {
sleep(1); sleep(1);
continue; continue;
} }
if ((size_t) r != (len-c)) { if ((size_t) r != (bytes-c)) {
::pthread_mutex_unlock(&write_lock); ::pthread_mutex_unlock(&write_lock);
return c; return c;
} }