firecat53 / urlscan

Mutt and terminal url selector (similar to urlview)
GNU General Public License v2.0
214 stars 38 forks source link

urlscan.close_stdin() failes #32

Closed fischerling closed 8 years ago

fischerling commented 8 years ago

urlscan version: 432997f

Backtrace:

Traceback (most recent call last):
    File "/usr/bin/urlscan", line 4, in <module>
    __import__('pkg_resources').run_script('urlscan==0.8.2', 'urlscan')
    File "/usr/lib/python3.5/site-packages/pkg_resources/__init__.py", line 719, in run_script
    self.require(requires)[0].run_script(script_name, ns)
    File "/usr/lib/python3.5/site-packages/pkg_resources/__init__.py", line 1511, in run_script
    exec(script_code, namespace, namespace)
    File "/usr/lib/python3.5/site-packages/urlscan-0.8.2-py3.5.egg/EGG-INFO/scripts/urlscan", line 130, in <module>
    File "/usr/lib/python3.5/site-packages/urlscan-0.8.2-py3.5.egg/EGG-INFO/scripts/urlscan", line 110, in process_input
    File "/usr/lib/python3.5/site-packages/urlscan-0.8.2-py3.5.egg/EGG-INFO/scripts/urlscan", line 61, in close_stdin
OSError: [Errno 6] No such device or address: '/dev/tty'

Manpage for open(2) says:

_ENXIO O_NONBLOCK | OWRONLY is set, the named file is a FIFO, and no process has the FIFO open for reading. Or, the file is a device special file and no corresponding device exists.

Situation when this happened to me:

#include <unistd.h>
#include <sys/types.h>                                                          
#include <stdio.h>                                                              
#include <stdlib.h>                                                             
#include <signal.h>                                                             

int                                                                             
main(int argc, char **argv)                                                    
{                                                                               
    int to[2]; /* 0=read, 1=write */                                        
    pid_t child;                                                                
    FILE *f;                                                                    
    int c;                                                                      
    void (*oldsigpipe)(int);                                                    

    if(pipe(to) == -1)                                                          
        return 1;                                                               

    switch(child = fork()){                                                     
        case -1:                                                                
            close(to[0]), close(to[1]);                                         
            return 1;                                                           
        case 0: /* child */                                                         
            close(to[1]);                                                       
            dup2(to[0], STDIN_FILENO); /* 0<&to */                              
            close(to[0]);                                                       
            execvp(
                "sh",                                                       
                (char *const[]){                                           
                "/bin/sh",                                                  
                "-c",                                                       
                argv[1],                                                    
                "&> bar",                                                   
                0                                                           
                });                                                         
            exit(127);                                                          
    }                                                                           
    /* parent */                                                                
    close(to[0]);                                                               
    /* ignore sigpipe */
    oldsigpipe = signal(SIGPIPE, SIG_IGN);                                      

    f=fopen("foo", "r");
    while((c=fgetc(f)) != EOF)
    {                                                
        write(to[1], &c, sizeof(c));                                            
    }                                                                           

    close(to[1]);                                                               

    /* restore */                                                               
    signal(SIGPIPE, oldsigpipe);                                                
}

Behaviour:

  1. creates pipe
  2. forkes
    • child executes sh with "argv[1] &> bar" to get the output of argv[1]
    • parent reads file foo and write its content into the pipe

Conclusion:

If I understand the docstring of close_stdin() correctly, then it is not even needed if urlscan is called with the '-n' flag.

firecat53 commented 8 years ago

I can't reproduce this on my machine with either st v0.6 or the most recent git version.

  1. git clone git clone git://git.suckless.org/st
  2. patch -p1 < st-externalpipe-0.6.diff
  3. Add this line to config.def.h

    { MODKEY, 'u', externalpipe, { .v = "urlscan -n | dmenu -l 10 | xargs -r firefox" } }

  4. make
  5. ./st
  6. cat some of the emails in the urlscan/test_emails directory, then Alt-u. Selected URL is opened in firefox.

Running Archlinux, with libx11 v1.6.3

Am I missing something? Is there something in your environment that's different? I also tried both python2 and python3 just to be sure.

Scott

fischerling commented 8 years ago

This is strange. After a restart I also can't reproduce.

I have no idea what could be different after reboot. Pacman.log shows I updated libevdev and lib32-systemd at this day maybe this resulted in some sort of a broken state.

Closing for now. I let you know if I find something related.