-rw-r--r-- | libopie2/opiecore/oprocess.cpp | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/libopie2/opiecore/oprocess.cpp b/libopie2/opiecore/oprocess.cpp index 5cfcf32..83677aa 100644 --- a/libopie2/opiecore/oprocess.cpp +++ b/libopie2/opiecore/oprocess.cpp | |||
@@ -687,259 +687,259 @@ int OProcess::commSetupDoneP() | |||
687 | this, SLOT( slotChildOutput( int ) ) ); | 687 | this, SLOT( slotChildOutput( int ) ) ); |
688 | if ( communication & NoRead ) | 688 | if ( communication & NoRead ) |
689 | suspend(); | 689 | suspend(); |
690 | } | 690 | } |
691 | 691 | ||
692 | if ( communication & Stderr ) | 692 | if ( communication & Stderr ) |
693 | { | 693 | { |
694 | // ok &= (-1 != fcntl(err[0], F_SETFL, O_NONBLOCK)); | 694 | // ok &= (-1 != fcntl(err[0], F_SETFL, O_NONBLOCK)); |
695 | errnot = new QSocketNotifier( err[ 0 ], QSocketNotifier::Read, this ); | 695 | errnot = new QSocketNotifier( err[ 0 ], QSocketNotifier::Read, this ); |
696 | CHECK_PTR( errnot ); | 696 | CHECK_PTR( errnot ); |
697 | QObject::connect( errnot, SIGNAL( activated( int ) ), | 697 | QObject::connect( errnot, SIGNAL( activated( int ) ), |
698 | this, SLOT( slotChildError( int ) ) ); | 698 | this, SLOT( slotChildError( int ) ) ); |
699 | } | 699 | } |
700 | } | 700 | } |
701 | return ok; | 701 | return ok; |
702 | } | 702 | } |
703 | 703 | ||
704 | int OProcess::commSetupDoneC() | 704 | int OProcess::commSetupDoneC() |
705 | { | 705 | { |
706 | int ok = 1; | 706 | int ok = 1; |
707 | struct linger so; | 707 | struct linger so; |
708 | memset( &so, 0, sizeof( so ) ); | 708 | memset( &so, 0, sizeof( so ) ); |
709 | 709 | ||
710 | if ( communication & Stdin ) | 710 | if ( communication & Stdin ) |
711 | close( in[ 1 ] ); | 711 | close( in[ 1 ] ); |
712 | if ( communication & Stdout ) | 712 | if ( communication & Stdout ) |
713 | close( out[ 0 ] ); | 713 | close( out[ 0 ] ); |
714 | if ( communication & Stderr ) | 714 | if ( communication & Stderr ) |
715 | close( err[ 0 ] ); | 715 | close( err[ 0 ] ); |
716 | 716 | ||
717 | if ( communication & Stdin ) | 717 | if ( communication & Stdin ) |
718 | ok &= dup2( in[ 0 ], STDIN_FILENO ) != -1; | 718 | ok &= dup2( in[ 0 ], STDIN_FILENO ) != -1; |
719 | else | 719 | else |
720 | { | 720 | { |
721 | int null_fd = open( "/dev/null", O_RDONLY ); | 721 | int null_fd = open( "/dev/null", O_RDONLY ); |
722 | ok &= dup2( null_fd, STDIN_FILENO ) != -1; | 722 | ok &= dup2( null_fd, STDIN_FILENO ) != -1; |
723 | close( null_fd ); | 723 | close( null_fd ); |
724 | } | 724 | } |
725 | if ( communication & Stdout ) | 725 | if ( communication & Stdout ) |
726 | { | 726 | { |
727 | ok &= dup2( out[ 1 ], STDOUT_FILENO ) != -1; | 727 | ok &= dup2( out[ 1 ], STDOUT_FILENO ) != -1; |
728 | ok &= !setsockopt( out[ 1 ], SOL_SOCKET, SO_LINGER, ( char* ) & so, sizeof( so ) ); | 728 | ok &= !setsockopt( out[ 1 ], SOL_SOCKET, SO_LINGER, ( char* ) & so, sizeof( so ) ); |
729 | } | 729 | } |
730 | else | 730 | else |
731 | { | 731 | { |
732 | int null_fd = open( "/dev/null", O_WRONLY ); | 732 | int null_fd = open( "/dev/null", O_WRONLY ); |
733 | ok &= dup2( null_fd, STDOUT_FILENO ) != -1; | 733 | ok &= dup2( null_fd, STDOUT_FILENO ) != -1; |
734 | close( null_fd ); | 734 | close( null_fd ); |
735 | } | 735 | } |
736 | if ( communication & Stderr ) | 736 | if ( communication & Stderr ) |
737 | { | 737 | { |
738 | ok &= dup2( err[ 1 ], STDERR_FILENO ) != -1; | 738 | ok &= dup2( err[ 1 ], STDERR_FILENO ) != -1; |
739 | ok &= !setsockopt( err[ 1 ], SOL_SOCKET, SO_LINGER, reinterpret_cast<char *>( &so ), sizeof( so ) ); | 739 | ok &= !setsockopt( err[ 1 ], SOL_SOCKET, SO_LINGER, reinterpret_cast<char *>( &so ), sizeof( so ) ); |
740 | } | 740 | } |
741 | else | 741 | else |
742 | { | 742 | { |
743 | int null_fd = open( "/dev/null", O_WRONLY ); | 743 | int null_fd = open( "/dev/null", O_WRONLY ); |
744 | ok &= dup2( null_fd, STDERR_FILENO ) != -1; | 744 | ok &= dup2( null_fd, STDERR_FILENO ) != -1; |
745 | close( null_fd ); | 745 | close( null_fd ); |
746 | } | 746 | } |
747 | return ok; | 747 | return ok; |
748 | } | 748 | } |
749 | 749 | ||
750 | void OProcess::commClose() | 750 | void OProcess::commClose() |
751 | { | 751 | { |
752 | if ( NoCommunication != communication ) | 752 | if ( NoCommunication != communication ) |
753 | { | 753 | { |
754 | bool b_in = ( communication & Stdin ); | 754 | bool b_in = ( communication & Stdin ); |
755 | bool b_out = ( communication & Stdout ); | 755 | bool b_out = ( communication & Stdout ); |
756 | bool b_err = ( communication & Stderr ); | 756 | bool b_err = ( communication & Stderr ); |
757 | if ( b_in ) | 757 | if ( b_in ) |
758 | delete innot; | 758 | delete innot; |
759 | 759 | ||
760 | if ( b_out || b_err ) | 760 | if ( b_out || b_err ) |
761 | { | 761 | { |
762 | // If both channels are being read we need to make sure that one socket buffer | 762 | // If both channels are being read we need to make sure that one socket buffer |
763 | // doesn't fill up whilst we are waiting for data on the other (causing a deadlock). | 763 | // doesn't fill up whilst we are waiting for data on the other (causing a deadlock). |
764 | // Hence we need to use select. | 764 | // Hence we need to use select. |
765 | 765 | ||
766 | // Once one or other of the channels has reached EOF (or given an error) go back | 766 | // Once one or other of the channels has reached EOF (or given an error) go back |
767 | // to the usual mechanism. | 767 | // to the usual mechanism. |
768 | 768 | ||
769 | int fds_ready = 1; | 769 | int fds_ready = 1; |
770 | fd_set rfds; | 770 | fd_set rfds; |
771 | 771 | ||
772 | int max_fd = 0; | 772 | int max_fd = 0; |
773 | if ( b_out ) | 773 | if ( b_out ) |
774 | { | 774 | { |
775 | fcntl( out[ 0 ], F_SETFL, O_NONBLOCK ); | 775 | fcntl( out[ 0 ], F_SETFL, O_NONBLOCK ); |
776 | if ( out[ 0 ] > max_fd ) | 776 | if ( out[ 0 ] > max_fd ) |
777 | max_fd = out[ 0 ]; | 777 | max_fd = out[ 0 ]; |
778 | delete outnot; | 778 | delete outnot; |
779 | outnot = 0; | 779 | outnot = 0; |
780 | } | 780 | } |
781 | if ( b_err ) | 781 | if ( b_err ) |
782 | { | 782 | { |
783 | fcntl( err[ 0 ], F_SETFL, O_NONBLOCK ); | 783 | fcntl( err[ 0 ], F_SETFL, O_NONBLOCK ); |
784 | if ( err[ 0 ] > max_fd ) | 784 | if ( err[ 0 ] > max_fd ) |
785 | max_fd = err[ 0 ]; | 785 | max_fd = err[ 0 ]; |
786 | delete errnot; | 786 | delete errnot; |
787 | errnot = 0; | 787 | errnot = 0; |
788 | } | 788 | } |
789 | 789 | ||
790 | 790 | ||
791 | while ( b_out || b_err ) | 791 | while ( b_out || b_err ) |
792 | { | 792 | { |
793 | // * If the process is still running we block until we | 793 | // * If the process is still running we block until we |
794 | // receive data. (p_timeout = 0, no timeout) | 794 | // receive data. (p_timeout = 0, no timeout) |
795 | // * If the process has already exited, we only check | 795 | // * If the process has already exited, we only check |
796 | // the available data, we don't wait for more. | 796 | // the available data, we don't wait for more. |
797 | // (p_timeout = &timeout, timeout immediately) | 797 | // (p_timeout = &timeout, timeout immediately) |
798 | struct timeval timeout; | 798 | struct timeval timeout; |
799 | timeout.tv_sec = 0; | 799 | timeout.tv_sec = 0; |
800 | timeout.tv_usec = 0; | 800 | timeout.tv_usec = 0; |
801 | struct timeval *p_timeout = runs ? 0 : &timeout; | 801 | struct timeval *p_timeout = runs ? 0 : &timeout; |
802 | 802 | ||
803 | FD_ZERO( &rfds ); | 803 | FD_ZERO( &rfds ); |
804 | if ( b_out ) | 804 | if ( b_out ) |
805 | FD_SET( out[ 0 ], &rfds ); | 805 | FD_SET( out[ 0 ], &rfds ); |
806 | 806 | ||
807 | if ( b_err ) | 807 | if ( b_err ) |
808 | FD_SET( err[ 0 ], &rfds ); | 808 | FD_SET( err[ 0 ], &rfds ); |
809 | 809 | ||
810 | fds_ready = select( max_fd + 1, &rfds, 0, 0, p_timeout ); | 810 | fds_ready = select( max_fd + 1, &rfds, 0, 0, p_timeout ); |
811 | if ( fds_ready <= 0 ) | 811 | if ( fds_ready <= 0 ) |
812 | break; | 812 | break; |
813 | 813 | ||
814 | if ( b_out && FD_ISSET( out[ 0 ], &rfds ) ) | 814 | if ( b_out && FD_ISSET( out[ 0 ], &rfds ) ) |
815 | { | 815 | { |
816 | int ret = 1; | 816 | int ret = 1; |
817 | while ( ret > 0 ) | 817 | while ( ret > 0 ) |
818 | ret = childOutput( out[ 0 ] ); | 818 | ret = childOutput( out[ 0 ] ); |
819 | if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 ) | 819 | if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 ) |
820 | b_out = false; | 820 | b_out = false; |
821 | } | 821 | } |
822 | 822 | ||
823 | if ( b_err && FD_ISSET( err[ 0 ], &rfds ) ) | 823 | if ( b_err && FD_ISSET( err[ 0 ], &rfds ) ) |
824 | { | 824 | { |
825 | int ret = 1; | 825 | int ret = 1; |
826 | while ( ret > 0 ) | 826 | while ( ret > 0 ) |
827 | ret = childError( err[ 0 ] ); | 827 | ret = childError( err[ 0 ] ); |
828 | if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 ) | 828 | if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 ) |
829 | b_err = false; | 829 | b_err = false; |
830 | } | 830 | } |
831 | } | 831 | } |
832 | } | 832 | } |
833 | 833 | ||
834 | if ( b_in ) | 834 | if ( b_in ) |
835 | { | 835 | { |
836 | communication = ( Communication ) ( communication & ~Stdin ); | 836 | communication = ( Communication ) ( communication & ~Stdin ); |
837 | close( in[ 1 ] ); | 837 | close( in[ 1 ] ); |
838 | } | 838 | } |
839 | if ( b_out ) | 839 | if ( b_out ) |
840 | { | 840 | { |
841 | communication = ( Communication ) ( communication & ~Stdout ); | 841 | communication = ( Communication ) ( communication & ~Stdout ); |
842 | close( out[ 0 ] ); | 842 | close( out[ 0 ] ); |
843 | } | 843 | } |
844 | if ( b_err ) | 844 | if ( b_err ) |
845 | { | 845 | { |
846 | communication = ( Communication ) ( communication & ~Stderr ); | 846 | communication = ( Communication ) ( communication & ~Stderr ); |
847 | close( err[ 0 ] ); | 847 | close( err[ 0 ] ); |
848 | } | 848 | } |
849 | } | 849 | } |
850 | } | 850 | } |
851 | 851 | ||
852 | void OProcess::setUseShell( bool useShell, const char *shell ) | 852 | void OProcess::setUseShell( bool useShell, const char *shell ) |
853 | { | 853 | { |
854 | if ( !d ) | 854 | if ( !d ) |
855 | d = new OProcessPrivate; | 855 | d = new OProcessPrivate; |
856 | d->useShell = useShell; | 856 | d->useShell = useShell; |
857 | d->shell = shell; | 857 | d->shell = shell; |
858 | if ( d->shell.isEmpty() ) | 858 | if ( d->shell.isEmpty() ) |
859 | d->shell = searchShell(); | 859 | d->shell = searchShell(); |
860 | } | 860 | } |
861 | 861 | ||
862 | QString OProcess::quote( const QString &arg ) | 862 | QString OProcess::quote( const QString &arg ) |
863 | { | 863 | { |
864 | QString res = arg; | 864 | QString res = arg; |
865 | res.replace( QRegExp( QString::fromLatin1( "\'" ) ), | 865 | res.replace( QRegExp( QString::fromLatin1( "\'" ) ), |
866 | QString::fromLatin1( "'\"'\"'" ) ); | 866 | QString::fromLatin1( "'\"'\"'" ) ); |
867 | res.prepend( '\'' ); | 867 | res.prepend( '\'' ); |
868 | res.append( '\'' ); | 868 | res.append( '\'' ); |
869 | return res; | 869 | return res; |
870 | } | 870 | } |
871 | 871 | ||
872 | QCString OProcess::searchShell() | 872 | QCString OProcess::searchShell() |
873 | { | 873 | { |
874 | QCString tmpShell = QCString( getenv( "SHELL" ) ).stripWhiteSpace(); | 874 | QCString tmpShell = QCString( getenv( "SHELL" ) ).stripWhiteSpace(); |
875 | if ( !isExecutable( tmpShell ) ) | 875 | if ( !isExecutable( tmpShell ) ) |
876 | { | 876 | { |
877 | tmpShell = "/bin/sh"; | 877 | tmpShell = "/bin/sh"; |
878 | } | 878 | } |
879 | 879 | ||
880 | return tmpShell; | 880 | return tmpShell; |
881 | } | 881 | } |
882 | 882 | ||
883 | bool OProcess::isExecutable( const QCString &filename ) | 883 | bool OProcess::isExecutable( const QCString &filename ) |
884 | { | 884 | { |
885 | struct stat fileinfo; | 885 | struct stat fileinfo; |
886 | 886 | ||
887 | if ( filename.isEmpty() ) | 887 | if ( filename.isEmpty() ) |
888 | return false; | 888 | return false; |
889 | 889 | ||
890 | // CC: we've got a valid filename, now let's see whether we can execute that file | 890 | // CC: we've got a valid filename, now let's see whether we can execute that file |
891 | 891 | ||
892 | if ( -1 == stat( filename.data(), &fileinfo ) ) | 892 | if ( -1 == stat( filename.data(), &fileinfo ) ) |
893 | return false; | 893 | return false; |
894 | // CC: return false if the file does not exist | 894 | // CC: return false if the file does not exist |
895 | 895 | ||
896 | // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets | 896 | // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets |
897 | if ( ( S_ISDIR( fileinfo.st_mode ) ) || | 897 | if ( ( S_ISDIR( fileinfo.st_mode ) ) || |
898 | ( S_ISCHR( fileinfo.st_mode ) ) || | 898 | ( S_ISCHR( fileinfo.st_mode ) ) || |
899 | ( S_ISBLK( fileinfo.st_mode ) ) || | 899 | ( S_ISBLK( fileinfo.st_mode ) ) || |
900 | #ifdef S_ISSOCK | 900 | #ifdef S_ISSOCK |
901 | // CC: SYSVR4 systems don't have that macro | 901 | // CC: SYSVR4 systems don't have that macro |
902 | ( S_ISSOCK( fileinfo.st_mode ) ) || | 902 | ( S_ISSOCK( fileinfo.st_mode ) ) || |
903 | #endif | 903 | #endif |
904 | ( S_ISFIFO( fileinfo.st_mode ) ) || | 904 | ( S_ISFIFO( fileinfo.st_mode ) ) || |
905 | ( S_ISDIR( fileinfo.st_mode ) ) ) | 905 | ( S_ISDIR( fileinfo.st_mode ) ) ) |
906 | { | 906 | { |
907 | return false; | 907 | return false; |
908 | } | 908 | } |
909 | 909 | ||
910 | // CC: now check for permission to execute the file | 910 | // CC: now check for permission to execute the file |
911 | if ( access( filename.data(), X_OK ) != 0 ) | 911 | if ( access( filename.data(), X_OK ) != 0 ) |
912 | return false; | 912 | return false; |
913 | 913 | ||
914 | // CC: we've passed all the tests... | 914 | // CC: we've passed all the tests... |
915 | return true; | 915 | return true; |
916 | } | 916 | } |
917 | 917 | ||
918 | int OProcess::processPID( const QString& process ) | 918 | int OProcess::processPID( const QString& process ) |
919 | { | 919 | { |
920 | QString line; | 920 | QString line; |
921 | QDir d = QDir( "/proc" ); | 921 | QDir d = QDir( "/proc" ); |
922 | QStringList dirs = d.entryList( QDir::Dirs ); | 922 | QStringList dirs = d.entryList( QDir::Dirs ); |
923 | QStringList::Iterator it; | 923 | QStringList::Iterator it; |
924 | for ( it = dirs.begin(); it != dirs.end(); ++it ) | 924 | for ( it = dirs.begin(); it != dirs.end(); ++it ) |
925 | { | 925 | { |
926 | //qDebug( "next entry: %s", (const char*) *it ); | 926 | //qDebug( "next entry: %s", (const char*) *it ); |
927 | QFile file( "/proc/"+*it+"/cmdline" ); | 927 | QFile file( "/proc/"+*it+"/cmdline" ); |
928 | file.open( IO_ReadOnly ); | 928 | file.open( IO_ReadOnly ); |
929 | if ( !file.isOpen() ) continue; | 929 | if ( !file.isOpen() ) continue; |
930 | QTextStream t( &file ); | 930 | QTextStream t( &file ); |
931 | line = t.readLine(); | 931 | line = t.readLine(); |
932 | //qDebug( "cmdline = %s", (const char*) line ); | 932 | //qDebug( "cmdline = %s", (const char*) line ); |
933 | if ( line.contains( process ) ) break; //FIXME: That may find also other process, if the name is not long enough ;) | 933 | if ( line.contains( process ) ) break; //FIXME: That may find also other process, if the name is not long enough ;) |
934 | } | 934 | } |
935 | if ( line.contains( process ) ) | 935 | if ( line.contains( process ) ) |
936 | { | 936 | { |
937 | //qDebug( "found process id #%d", (*it).toInt() ); | 937 | //qDebug( "found process id #%d", (*it).toInt() ); |
938 | return (*it).toInt(); | 938 | return (*it).toInt(); |
939 | } | 939 | } |
940 | else | 940 | else |
941 | { | 941 | { |
942 | //qDebug( "process '%s' not found", (const char*) process ); | 942 | //qDebug( "process '%s' not found", (const char*) process ); |
943 | return -1; | 943 | return 0; |
944 | } | 944 | } |
945 | } | 945 | } |