diff options
author | Mike Buland <eichlan@xagasoft.com> | 2007-11-30 16:02:04 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2007-11-30 16:02:04 +0000 |
commit | 4d0a7466320e54f45f413efef09ef8e6ad21bb3e (patch) | |
tree | 8b2d7d6dc4454b44aa23e189bf46dcee968964c3 | |
parent | ed402db706488ab910b7c810684379cc2d7b7662 (diff) | |
download | libbu++-4d0a7466320e54f45f413efef09ef8e6ad21bb3e.tar.gz libbu++-4d0a7466320e54f45f413efef09ef8e6ad21bb3e.tar.bz2 libbu++-4d0a7466320e54f45f413efef09ef8e6ad21bb3e.tar.xz libbu++-4d0a7466320e54f45f413efef09ef8e6ad21bb3e.zip |
Added some helpers to fstring, and fixed a bug in Bu::Process, it wasn't closing
the pipes properly, resulting in the child process going defunct and not dying,
it also wasn't buffering properly, it now collects as much data as it can before
returning from a read operation.
-rw-r--r-- | src/fstring.h | 33 | ||||
-rw-r--r-- | src/process.cpp | 56 | ||||
-rw-r--r-- | src/process.h | 1 | ||||
-rw-r--r-- | src/tests/procs.cpp | 6 |
4 files changed, 93 insertions, 3 deletions
diff --git a/src/fstring.h b/src/fstring.h index 666480c..82e8b34 100644 --- a/src/fstring.h +++ b/src/fstring.h | |||
@@ -731,6 +731,39 @@ namespace Bu | |||
731 | } | 731 | } |
732 | return -1; | 732 | return -1; |
733 | } | 733 | } |
734 | |||
735 | /** | ||
736 | * Find the index of the first occurrance of cChar | ||
737 | *@param sText (const chr *) The string to search for. | ||
738 | *@returns (long) The index of the first occurrance. -1 for not found. | ||
739 | */ | ||
740 | long find( long iStart, const chr cChar ) const | ||
741 | { | ||
742 | flatten(); | ||
743 | for( long j = iStart; j < pFirst->nLength; j++ ) | ||
744 | { | ||
745 | if( pFirst->pData[j] == cChar ) | ||
746 | return j; | ||
747 | } | ||
748 | return -1; | ||
749 | } | ||
750 | |||
751 | /** | ||
752 | * Find the index of the first occurrance of sText | ||
753 | *@param cChar (const chr) The character to search for. | ||
754 | *@returns (long) The index of the first occurrance. -1 for not found. | ||
755 | */ | ||
756 | long find( long iStart, const chr *sText ) const | ||
757 | { | ||
758 | long nTLen = strlen( sText ); | ||
759 | flatten(); | ||
760 | for( long j = iStart; j < pFirst->nLength-nTLen; j++ ) | ||
761 | { | ||
762 | if( !strncmp( sText, pFirst->pData+j, nTLen ) ) | ||
763 | return j; | ||
764 | } | ||
765 | return -1; | ||
766 | } | ||
734 | 767 | ||
735 | /** | 768 | /** |
736 | * Do a reverse search for (sText) | 769 | * Do a reverse search for (sText) |
diff --git a/src/process.cpp b/src/process.cpp index 8fe98f3..c554e1a 100644 --- a/src/process.cpp +++ b/src/process.cpp | |||
@@ -7,8 +7,11 @@ | |||
7 | 7 | ||
8 | #include "process.h" | 8 | #include "process.h" |
9 | #include <sys/types.h> | 9 | #include <sys/types.h> |
10 | #include <sys/wait.h> | ||
10 | #include <unistd.h> | 11 | #include <unistd.h> |
11 | #include <stdarg.h> | 12 | #include <stdarg.h> |
13 | #include <signal.h> | ||
14 | #include <fcntl.h> | ||
12 | 15 | ||
13 | Bu::Process::Process( const char *sName, char *const argv[] ) | 16 | Bu::Process::Process( const char *sName, char *const argv[] ) |
14 | { | 17 | { |
@@ -22,12 +25,17 @@ Bu::Process::Process( const char *sName, const char *argv, ...) | |||
22 | va_start( ap, argv ); | 25 | va_start( ap, argv ); |
23 | for(; va_arg( ap, const char *); iCnt++ ); | 26 | for(; va_arg( ap, const char *); iCnt++ ); |
24 | va_end( ap ); | 27 | va_end( ap ); |
28 | printf("Params: %d\n", iCnt ); | ||
25 | 29 | ||
26 | char const **list = new char const *[iCnt+2]; | 30 | char const **list = new char const *[iCnt+2]; |
27 | va_start( ap, argv ); | 31 | va_start( ap, argv ); |
28 | list[0] = argv; | 32 | list[0] = argv; |
29 | for( int j = 1; j < iCnt; j++ ) | 33 | printf("list[0] = \"%s\"\n", argv ); |
34 | for( int j = 1; j <= iCnt; j++ ) | ||
35 | { | ||
30 | list[j] = va_arg( ap, const char *); | 36 | list[j] = va_arg( ap, const char *); |
37 | printf("list[%d] = \"%s\"\n", j, list[j] ); | ||
38 | } | ||
31 | list[iCnt+1] = NULL; | 39 | list[iCnt+1] = NULL; |
32 | va_end( ap ); | 40 | va_end( ap ); |
33 | 41 | ||
@@ -52,6 +60,8 @@ void Bu::Process::gexec( const char *sName, char *const argv[] ) | |||
52 | iStdOut = iaStdOut[0]; | 60 | iStdOut = iaStdOut[0]; |
53 | iStdErr = iaStdErr[0]; | 61 | iStdErr = iaStdErr[0]; |
54 | 62 | ||
63 | // fcntl( iStdOut, F_SETFL, fcntl( iStdOut, F_GETFL, 0 )|O_NONBLOCK ); | ||
64 | |||
55 | iPid = fork(); | 65 | iPid = fork(); |
56 | if( iPid == 0 ) | 66 | if( iPid == 0 ) |
57 | { | 67 | { |
@@ -63,6 +73,9 @@ void Bu::Process::gexec( const char *sName, char *const argv[] ) | |||
63 | dup2( iaStdErr[1], 2 ); | 73 | dup2( iaStdErr[1], 2 ); |
64 | execvp( sName, argv ); | 74 | execvp( sName, argv ); |
65 | } | 75 | } |
76 | ::close( iaStdIn[0] ); | ||
77 | ::close( iaStdOut[1] ); | ||
78 | ::close( iaStdErr[1] ); | ||
66 | } | 79 | } |
67 | 80 | ||
68 | void Bu::Process::close() | 81 | void Bu::Process::close() |
@@ -71,7 +84,46 @@ void Bu::Process::close() | |||
71 | 84 | ||
72 | size_t Bu::Process::read( void *pBuf, size_t nBytes ) | 85 | size_t Bu::Process::read( void *pBuf, size_t nBytes ) |
73 | { | 86 | { |
74 | return ::read( iStdOut, pBuf, nBytes ); | 87 | size_t iTotal = 0; |
88 | for(;;) | ||
89 | { | ||
90 | size_t iRet = ::read( iStdOut, (char *)pBuf+iTotal, nBytes-iTotal ); | ||
91 | if( iRet == 0 ) | ||
92 | return iTotal; | ||
93 | printf("--read=%d / %d--\n", iRet, iTotal+iRet ); | ||
94 | iTotal += iRet; | ||
95 | if( iTotal == nBytes ) | ||
96 | return iTotal; | ||
97 | } | ||
98 | /* | ||
99 | size_t iTotal = 0; | ||
100 | fd_set rfs; | ||
101 | FD_ZERO( &rfs ); | ||
102 | for(;;) | ||
103 | { | ||
104 | if( waitpid( iPid, NULL, WNOHANG ) ) | ||
105 | { | ||
106 | printf("!!!wait failed!\n"); | ||
107 | size_t iRet = ::read( iStdOut, (char *)pBuf+iTotal, | ||
108 | nBytes-iTotal ); | ||
109 | iTotal += iRet; | ||
110 | return iTotal; | ||
111 | } | ||
112 | |||
113 | FD_SET( iStdOut, &rfs ); | ||
114 | select( iStdOut+1, &rfs, NULL, &rfs, NULL ); | ||
115 | size_t iRet = ::read( iStdOut, (char *)pBuf+iTotal, nBytes-iTotal ); | ||
116 | printf("--read=%d / %d--\n", iRet, iTotal+iRet ); | ||
117 | iTotal += iRet; | ||
118 | if( iTotal == nBytes ) | ||
119 | return iTotal; | ||
120 | } | ||
121 | */ | ||
122 | } | ||
123 | |||
124 | size_t Bu::Process::readErr( void *pBuf, size_t nBytes ) | ||
125 | { | ||
126 | return ::read( iStdErr, pBuf, nBytes ); | ||
75 | } | 127 | } |
76 | 128 | ||
77 | size_t Bu::Process::write( const void *pBuf, size_t nBytes ) | 129 | size_t Bu::Process::write( const void *pBuf, size_t nBytes ) |
diff --git a/src/process.h b/src/process.h index dbf1553..025b295 100644 --- a/src/process.h +++ b/src/process.h | |||
@@ -30,6 +30,7 @@ namespace Bu | |||
30 | 30 | ||
31 | virtual void close(); | 31 | virtual void close(); |
32 | virtual size_t read( void *pBuf, size_t nBytes ); | 32 | virtual size_t read( void *pBuf, size_t nBytes ); |
33 | virtual size_t readErr( void *pBuf, size_t nBytes ); | ||
33 | virtual size_t write( const void *pBuf, size_t nBytes ); | 34 | virtual size_t write( const void *pBuf, size_t nBytes ); |
34 | 35 | ||
35 | virtual long tell(); | 36 | virtual long tell(); |
diff --git a/src/tests/procs.cpp b/src/tests/procs.cpp index 53e5142..c233040 100644 --- a/src/tests/procs.cpp +++ b/src/tests/procs.cpp | |||
@@ -4,12 +4,16 @@ | |||
4 | 4 | ||
5 | int main( int agrc, char *argv[] ) | 5 | int main( int agrc, char *argv[] ) |
6 | { | 6 | { |
7 | Bu::Process p( argv[1], argv+1 ); | 7 | //Bu::Process p( argv[1], argv+1 ); |
8 | Bu::Process p("mplayer", "mplayer", "dvd://", "-framedrop", | ||
9 | "-ao", "null", "-nosound", "-vf", "framestep=I,cropdetect" "-sstep", | ||
10 | "197", NULL ); | ||
8 | 11 | ||
9 | char buf[1000]; | 12 | char buf[1000]; |
10 | for(;;) | 13 | for(;;) |
11 | { | 14 | { |
12 | int iSize = p.read( buf, 1000 ); | 15 | int iSize = p.read( buf, 1000 ); |
16 | printf("::read=%d::\n", iSize ); | ||
13 | if( iSize == 0 ) | 17 | if( iSize == 0 ) |
14 | break; | 18 | break; |
15 | fwrite( buf, iSize, 1, stdout ); | 19 | fwrite( buf, iSize, 1, stdout ); |