/*============= Give a user program IO access : lp_tty_start.c ============= PURPOSE - show use of ioperm and exec to give a non-root program direct IO access to just lp0/1/2 and ttyS0/1/2/3. Priority is also adjusted. USAGE - ./ioperm_start ./target_program_name param1 param2 ... NOTE - ioperm allows access to a limited range of IO between 0 and 0x3FF and no access to interrupt disable/enable. - the setgid, setuid removes root privileges. - setpriority adjusts process scheduling priority. - the command line minus the first parameter (the target program name) is sent to the target program. */ #include #include #include #include #include const int lp0 = 0x378; // lp (LPT) base addresses. const int lp1 = 0x278; const int lp2 = 0x3BC; const int lp_length = 3; const int ttyS0 = 0x3F8; // ttyS (COM) port base addresses. const int ttyS1 = 0x2F8; const int ttyS2 = 0x3E8; const int ttyS3 = 0x2E8; const int ttyS_length = 8; int main( int argc, char *argv[] ) { // abort if no parameters: if ( argc < 2 ) { cerr << "usage: " << argv[ 0 ] << " program program-args...\n"; exit( 1 ); } // set process priority: see man setpriority // may need to sudo apt-get install manpages-dev to see it. const int priority = 0; // 0= normal, -20 highest, +20 lowest. const int this_process = 0; setpriority( PRIO_PROCESS, this_process, priority ); /*--- Get access to the ports and remove root privileges.*/ if ( ioperm( lp0, lp_length, 1 ) ) perror( "Failed ioperm lp0 on" ); // if ( ioperm( lp1, lp_length, 1 ) ) // perror( "Failed ioperm lp1 on" ); // if ( ioperm( lp2, lp_length, 1 ) ) // perror( "Failed ioperm lp2 on" ); // if ( ioperm( ttyS0, ttyS_length, 1 ) ) // perror( "Failed ioperm ttyS0 on" ); // if ( ioperm( ttyS1, ttyS_length, 1) ) // perror( "Failed ioperm ttyS1 on" ); // if ( ioperm( ttyS2, ttyS_length, 1 ) ) // perror( "Failed ioperm ttyS2 on" ); // if ( ioperm( ttyS3, ttyS_length, 1 ) ) // perror( "Failed ioperm ttyS3 on" ); setgid( getgid() ); setuid( getuid() ); /*--- do the exec to the target program, use argv array from parameter 1 onward.*/ execvp( argv[1], &argv[1] ); /* if get here exec must have failed.*/ perror( " execv failed" ); cerr << "Target program was " << argv[ 1 ] << "\n"; exit( 2 ); }