@ -42,11 +42,6 @@
# define _MAPPINGS_CONFIG
# define _MAPPINGS_CONFIG
# include "config.h"
# include "config.h"
typedef struct {
const char * name ;
char * cmd ;
} exec_t ;
typedef struct {
typedef struct {
struct timeval when ;
struct timeval when ;
bool active ;
bool active ;
@ -75,15 +70,20 @@ bool extprefix;
bool resized = false ;
bool resized = false ;
typedef struct {
int err ;
char * cmd ;
} extcmd_t ;
struct {
struct {
char * cmd ;
extcmd_t f ;
int fd ;
int fd ;
unsigned int i , lastsep ;
unsigned int i , lastsep ;
bool open ;
bool open ;
} info ;
} info ;
struct {
struct {
char * cmd ;
extcmd_t f ;
bool warned ;
bool warned ;
} keyhandler ;
} keyhandler ;
@ -97,26 +97,24 @@ timeout_t timeouts[] = {
void cleanup ( void )
void cleanup ( void )
{
{
static bool in = false ;
img_close ( & img , false ) ;
tns_free ( & tns ) ;
if ( ! in ) {
win_close ( & win ) ;
in = true ;
img_close ( & img , false ) ;
tns_free ( & tns ) ;
win_close ( & win ) ;
}
}
}
void check_add_file ( char * filename , bool given )
void check_add_file ( char * filename , bool given )
{
{
char * path ;
const char * bn ;
const char * bn ;
if ( * filename = = ' \0 ' )
if ( * filename = = ' \0 ' )
return ;
return ;
if ( access ( filename , R_OK ) < 0 ) {
if ( access ( filename , R_OK ) < 0 | |
( path = realpath ( filename , NULL ) ) = = NULL )
{
if ( given )
if ( given )
warn ( " could not open file: %s " , filename ) ;
error( 0 , errno , " %s" , filename ) ;
return ;
return ;
}
}
@ -126,12 +124,8 @@ void check_add_file(char *filename, bool given)
memset ( & files [ filecnt / 2 ] , 0 , filecnt / 2 * sizeof ( * files ) ) ;
memset ( & files [ filecnt / 2 ] , 0 , filecnt / 2 * sizeof ( * files ) ) ;
}
}
if ( ( files [ fileidx ] . path = realpath ( filename , NULL ) ) = = NULL ) {
warn ( " could not get real path of file: %s \n " , filename ) ;
return ;
}
files [ fileidx ] . name = estrdup ( filename ) ;
files [ fileidx ] . name = estrdup ( filename ) ;
files [ fileidx ] . path = path ;
if ( ( bn = strrchr ( files [ fileidx ] . name , ' / ' ) ) ! = NULL & & bn [ 1 ] ! = ' \0 ' )
if ( ( bn = strrchr ( files [ fileidx ] . name , ' / ' ) ) ! = NULL & & bn [ 1 ] ! = ' \0 ' )
files [ fileidx ] . base = + + bn ;
files [ fileidx ] . base = + + bn ;
else
else
@ -149,7 +143,6 @@ void remove_file(int n, bool manual)
if ( filecnt = = 1 ) {
if ( filecnt = = 1 ) {
if ( ! manual )
if ( ! manual )
fprintf ( stderr , " sxiv: no more files to display, aborting \n " ) ;
fprintf ( stderr , " sxiv: no more files to display, aborting \n " ) ;
cleanup ( ) ;
exit ( manual ? EXIT_SUCCESS : EXIT_FAILURE ) ;
exit ( manual ? EXIT_SUCCESS : EXIT_FAILURE ) ;
}
}
if ( files [ n ] . flags & FF_MARK )
if ( files [ n ] . flags & FF_MARK )
@ -232,7 +225,7 @@ void open_info(void)
static pid_t pid ;
static pid_t pid ;
int pfd [ 2 ] ;
int pfd [ 2 ] ;
if ( info . cmd = = NULL | | info . open | | win . bar . h = = 0 )
if ( info . f. err ! = 0 | | info . open | | win . bar . h = = 0 )
return ;
return ;
if ( info . fd ! = - 1 ) {
if ( info . fd ! = - 1 ) {
close ( info . fd ) ;
close ( info . fd ) ;
@ -246,9 +239,8 @@ void open_info(void)
if ( ( pid = fork ( ) ) = = 0 ) {
if ( ( pid = fork ( ) ) = = 0 ) {
close ( pfd [ 0 ] ) ;
close ( pfd [ 0 ] ) ;
dup2 ( pfd [ 1 ] , 1 ) ;
dup2 ( pfd [ 1 ] , 1 ) ;
execl ( info . cmd , info . cmd , files [ fileidx ] . name , NULL ) ;
execl ( info . f . cmd , info . f . cmd , files [ fileidx ] . name , NULL ) ;
warn ( " could not exec: %s " , info . cmd ) ;
error ( EXIT_FAILURE , errno , " exec: %s " , info . f . cmd ) ;
exit ( EXIT_FAILURE ) ;
}
}
close ( pfd [ 1 ] ) ;
close ( pfd [ 1 ] ) ;
if ( pid < 0 ) {
if ( pid < 0 ) {
@ -386,7 +378,7 @@ void update_info(void)
bar_put ( r , " %0*d/%d | " , fn , img . multi . sel + 1 , img . multi . cnt ) ;
bar_put ( r , " %0*d/%d | " , fn , img . multi . sel + 1 , img . multi . cnt ) ;
}
}
bar_put ( r , " %0*d/%d " , fw , fileidx + 1 , filecnt ) ;
bar_put ( r , " %0*d/%d " , fw , fileidx + 1 , filecnt ) ;
ow_info = info . cmd = = NULL ;
ow_info = info . f. err ! = 0 ;
}
}
if ( ow_info ) {
if ( ow_info ) {
fn = strlen ( files [ fileidx ] . name ) ;
fn = strlen ( files [ fileidx ] . name ) ;
@ -469,14 +461,14 @@ void run_key_handler(const char *key, unsigned int mask)
FILE * pfs ;
FILE * pfs ;
bool marked = mode = = MODE_THUMB & & markcnt > 0 ;
bool marked = mode = = MODE_THUMB & & markcnt > 0 ;
bool changed = false ;
bool changed = false ;
int f , i , pfd [ 2 ] , retval, status;
int f , i , pfd [ 2 ] , status;
int fcnt = marked ? markcnt : 1 ;
int fcnt = marked ? markcnt : 1 ;
char kstr [ 32 ] ;
char kstr [ 32 ] ;
struct stat * oldst , st ;
struct stat * oldst , st ;
if ( keyhandler . cmd = = NULL ) {
if ( keyhandler . f. err ! = 0 ) {
if ( ! keyhandler . warned ) {
if ( ! keyhandler . warned ) {
warn( " key handler not installed " ) ;
error( 0 , keyhandler . f . err , " %s " , keyhandler . f . cmd ) ;
keyhandler . warned = true ;
keyhandler . warned = true ;
}
}
return ;
return ;
@ -485,12 +477,12 @@ void run_key_handler(const char *key, unsigned int mask)
return ;
return ;
if ( pipe ( pfd ) < 0 ) {
if ( pipe ( pfd ) < 0 ) {
warn( " could not create pipe for key handler " ) ;
error( 0 , errno , " pipe " ) ;
return ;
return ;
}
}
if ( ( pfs = fdopen ( pfd [ 1 ] , " w " ) ) = = NULL ) {
if ( ( pfs = fdopen ( pfd [ 1 ] , " w " ) ) = = NULL ) {
error ( 0 , errno , " open pipe " ) ;
close ( pfd [ 0 ] ) , close ( pfd [ 1 ] ) ;
close ( pfd [ 0 ] ) , close ( pfd [ 1 ] ) ;
warn ( " could not open pipe for key handler " ) ;
return ;
return ;
}
}
oldst = emalloc ( fcnt * sizeof ( * oldst ) ) ;
oldst = emalloc ( fcnt * sizeof ( * oldst ) ) ;
@ -507,14 +499,13 @@ void run_key_handler(const char *key, unsigned int mask)
if ( ( pid = fork ( ) ) = = 0 ) {
if ( ( pid = fork ( ) ) = = 0 ) {
close ( pfd [ 1 ] ) ;
close ( pfd [ 1 ] ) ;
dup2 ( pfd [ 0 ] , 0 ) ;
dup2 ( pfd [ 0 ] , 0 ) ;
execl ( keyhandler . cmd , keyhandler . cmd , kstr , NULL ) ;
execl ( keyhandler . f . cmd , keyhandler . f . cmd , kstr , NULL ) ;
warn ( " could not exec key handler " ) ;
error ( EXIT_FAILURE , errno , " exec: %s " , keyhandler . f . cmd ) ;
exit ( EXIT_FAILURE ) ;
}
}
close ( pfd [ 0 ] ) ;
close ( pfd [ 0 ] ) ;
if ( pid < 0 ) {
if ( pid < 0 ) {
error ( 0 , errno , " fork " ) ;
fclose ( pfs ) ;
fclose ( pfs ) ;
warn ( " could not fork key handler " ) ;
goto end ;
goto end ;
}
}
@ -527,9 +518,8 @@ void run_key_handler(const char *key, unsigned int mask)
}
}
fclose ( pfs ) ;
fclose ( pfs ) ;
waitpid ( pid , & status , 0 ) ;
waitpid ( pid , & status , 0 ) ;
retval = WEXITSTATUS ( status ) ;
if ( ! WIFEXITED ( status ) | | WEXITSTATUS ( status ) ! = 0 )
if ( WIFEXITED ( status ) = = 0 | | retval ! = 0 )
error ( 0 , 0 , " %s: Exited abnormally " , keyhandler . f . cmd ) ;
warn ( " key handler exited with non-zero return value: %d " , retval ) ;
for ( f = i = 0 ; f < fcnt ; i + + ) {
for ( f = i = 0 ; f < fcnt ; i + + ) {
if ( ( marked & & ( files [ i ] . flags & FF_MARK ) ) | | ( ! marked & & i = = fileidx ) ) {
if ( ( marked & & ( files [ i ] . flags & FF_MARK ) ) | | ( ! marked & & i = = fileidx ) ) {
@ -550,7 +540,7 @@ end:
if ( changed ) {
if ( changed ) {
img_close ( & img , true ) ;
img_close ( & img , true ) ;
load_image ( fileidx ) ;
load_image ( fileidx ) ;
} else if ( info . cmd ! = NULL ) {
} else if ( info . f. err = = 0 ) {
info . open = false ;
info . open = false ;
open_info ( ) ;
open_info ( ) ;
}
}
@ -819,18 +809,18 @@ int main(int argc, char **argv)
filename = options - > filenames [ i ] ;
filename = options - > filenames [ i ] ;
if ( stat ( filename , & fstats ) < 0 ) {
if ( stat ( filename , & fstats ) < 0 ) {
warn( " could not stat file: %s" , filename ) ;
error( 0 , errno , " %s" , filename ) ;
continue ;
continue ;
}
}
if ( ! S_ISDIR ( fstats . st_mode ) ) {
if ( ! S_ISDIR ( fstats . st_mode ) ) {
check_add_file ( filename , true ) ;
check_add_file ( filename , true ) ;
} else {
} else {
if ( ! options - > recursive ) {
if ( ! options - > recursive ) {
warn( " ignoring directory: %s " , filename ) ;
error( 0 , 0 , " %s: Is a directory " , filename ) ;
continue ;
continue ;
}
}
if ( r_opendir ( & dir , filename ) < 0 ) {
if ( r_opendir ( & dir , filename ) < 0 ) {
warn( " could not open directory: %s" , filename ) ;
error( 0 , errno , " %s" , filename ) ;
continue ;
continue ;
}
}
start = fileidx ;
start = fileidx ;
@ -844,10 +834,8 @@ int main(int argc, char **argv)
}
}
}
}
if ( fileidx = = 0 ) {
if ( fileidx = = 0 )
fprintf ( stderr , " sxiv: no valid image file given, aborting \n " ) ;
error ( EXIT_FAILURE , 0 , " No valid image file given, aborting " ) ;
exit ( EXIT_FAILURE ) ;
}
filecnt = fileidx ;
filecnt = fileidx ;
fileidx = options - > startnum < filecnt ? options - > startnum : 0 ;
fileidx = options - > startnum < filecnt ? options - > startnum : 0 ;
@ -860,20 +848,18 @@ int main(int argc, char **argv)
dsuffix = " /.config " ;
dsuffix = " /.config " ;
}
}
if ( homedir ! = NULL ) {
if ( homedir ! = NULL ) {
char * * cmd [ ] = { & info . cmd , & keyhandler . cmd } ;
extcmd_t * cmd [ ] = { & info . f , & keyhandler . f } ;
const char * name [ ] = { " image-info " , " key-handler " } ;
const char * name [ ] = { " image-info " , " key-handler " } ;
for ( i = 0 ; i < ARRLEN ( cmd ) ; i + + ) {
for ( i = 0 ; i < ARRLEN ( cmd ) ; i + + ) {
n = strlen ( homedir ) + strlen ( dsuffix ) + strlen ( name [ i ] ) + 12 ;
n = strlen ( homedir ) + strlen ( dsuffix ) + strlen ( name [ i ] ) + 12 ;
* cmd [ i ] = ( char * ) emalloc ( n ) ;
cmd [ i ] - > cmd = ( char * ) emalloc ( n ) ;
snprintf ( * cmd [ i ] , n , " %s%s/sxiv/exec/%s " , homedir , dsuffix , name [ i ] ) ;
snprintf ( cmd [ i ] - > cmd , n , " %s%s/sxiv/exec/%s " , homedir , dsuffix , name [ i ] ) ;
if ( access ( * cmd [ i ] , X_OK ) ! = 0 ) {
if ( access ( cmd [ i ] - > cmd , X_OK ) ! = 0 )
free ( * cmd [ i ] ) ;
cmd [ i ] - > err = errno ;
* cmd [ i ] = NULL ;
}
}
}
} else {
} else {
warn( " could not locate exec directory " ) ;
error( 0 , 0 , " Exec directory not found " ) ;
}
}
info . fd = - 1 ;
info . fd = - 1 ;
@ -890,10 +876,11 @@ int main(int argc, char **argv)
win_open ( & win ) ;
win_open ( & win ) ;
win_set_cursor ( & win , CURSOR_WATCH ) ;
win_set_cursor ( & win , CURSOR_WATCH ) ;
atexit ( cleanup ) ;
set_timeout ( redraw , 25 , false ) ;
set_timeout ( redraw , 25 , false ) ;
run ( ) ;
run ( ) ;
cleanup ( ) ;
return 0 ;
return 0 ;
}
}