LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 06-11-2019, 06:10 AM   #16
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,680

Original Poster
Blog Entries: 19

Rep: Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492

Quote:
Originally Posted by GazL View Post
This post is going to make some assumptions as you've not provided much information about your barberella program...

There are a number of functions in Xlib named XGrab*() that a client can call to tell the Xserver, "Hey!, I'm in control of that now". The pointer is one of the resources that can be grabbed.
I'm not using Xlib directly. Who does, these days? Barbarella uses gtk2 for its widget set.
Quote:
One possible scenario:

Your buttonbar program grabs the pointer. It registers the click and runs system("view ..."). view is a tty based program and will probably block trying to open/read stdin for input. system() never returns control to your buttonbar, which still maintains a grab on the pointer or some other Xserver resource. Everything stops.
Sounds reasonable!
Quote:
My first suggestion would be to use a fork() + exec() method to spawn your applications rather than using system(). That way even if the spawned process blocks, your main process can continue to run.
Actually that's how I do it. The command is stored in a buffer, parsed to create an array of arguments, and then passed to execvp.
Quote:
If you're using any of the XGrab*() functions don't leave them grabbed for any longer than is necessary. Grab. do what you need to do and then Ungrab().
It would be useful to know about that, but as I am using a higher level widget set, I don't actually know whether the mouse is being grabbed or not. All I know is that the gtk_button widget picks up a gdk click event and emits a "clicked" signal, which my program responds to. I suppose I could look at the gtk2 source, but I doubt if I would understand much. My knowledge of C is pretty elementary.
Quote:
Oh, and you can see what a process is using for stdin/out by ls -l /proc/$pid/fd.
Wow, that's useful! Far easier than writing a program to do it.
Quote:
P.S. You might also want to consider closing stdin/out in your buttonbar program when it starts if it never use them and they're not connected to a valid source/dest.
That's also good advice. Presumably, if they are closed, they won't be open in any of the launched programs either. istr that file descriptors survive fork/exec, although streams don't.
Quote:
P.P.S.
I disconnect stdin/out from xdm in a custom rc.4 when I launch it, so that things don't inherit an unusable stdin/out.
Code:
....
# Close stdin/out to prevent the display manager process being
# killed by a SAK event on tty1:
exec <&-
exec >&-

...
... connecting stdin/out to /dev/null is probably safer than closing as I've seen some poorly written programs make a right hash of file-descriptors when FD's 0 and 1 are closed. Now I'm reminded of it, I'll give thought to making that change here.
I'm using startx, but I could put that bit of code in if I understood it! "exec <&-" What precisely does that do? And what's a SAK event?

PS: Maybe one of the mods could move this thread to programming. I think it would be more useful there.

Last edited by hazel; 06-11-2019 at 06:13 AM. Reason: Added PS
 
Old 06-11-2019, 06:33 AM   #17
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,918

Rep: Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035
exec <&- is a redirection that closes stdin.

SAK is the "secure attention key". It's a magic-sysrq kernel sequence that kills everything on the tty it's entered on. altgr-sysreq k
Don't run it on tty1 on Slackware as it'll kill most of the daemons that rc.S/M start. It's fine to use on the other ttys and can sometimes unlock a locked up X environment.

I started work on making tty1 SAK proof which is why I created this rc.4.local, but there's so much system stuff left attached to tty1 in one form or another on slackware that it became not worth the effort. Especially as I follow the current branch which means my changes get overwritten frequently.


I like playing with Xlib, and Motif and other old toolkits. GTK seems to be a constantly moving target, Qt is C++ and I'm a C kind of guy, so neither of those really appeal to me.

Last edited by GazL; 06-11-2019 at 06:35 AM.
 
Old 06-11-2019, 06:48 AM   #18
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,680

Original Poster
Blog Entries: 19

Rep: Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492
Appendix: I've just done an ls -l fd on one of my barbarellas (there are four instances altogether because I have a different selection of programs on each desktop) and it gives me
Code:
lr-x------ 1 hazel hazel 64 Jun 11 12:41 0 -> /dev/null
lrwx------ 1 hazel hazel 64 Jun 11 12:41 1 -> /dev/tty1
lrwx------ 1 hazel hazel 64 Jun 11 12:41 2 -> /dev/tty1
lrwx------ 1 hazel hazel 64 Jun 11 12:41 3 -> socket:[9101]
lrwx------ 1 hazel hazel 64 Jun 11 12:41 4 -> anon_inode:[eventfd]
So input has been closed (not by me! gtk must have done it) and both outputs go to tty1. The socket connection I assume to be to X. I have no idea what the other one is.

Does that mean that any programs launched by barbarella will try to take their input from /dev/null?
 
Old 06-11-2019, 07:00 AM   #19
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,918

Rep: Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035
Quote:
Originally Posted by hazel View Post
Does that mean that any programs launched by barbarella will try to take their input from /dev/null?
Yes, that's what I'd expect, so I wouldn't expect a normal program to block on a read of it. But then vim/view is a ncurses tty program and is probably getting up to all manner of shenanigans, so who knows.
 
Old 06-11-2019, 01:04 PM   #20
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,039

Rep: Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347
again, you can use (for example) pstree to check which process started which one. Also you can check the same way the fd of any other processes (like view), so just start it again and check. I'm really interested.
 
Old 06-11-2019, 02:23 PM   #21
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,680

Original Poster
Blog Entries: 19

Rep: Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492
OK, Pan, so here's what happens. I use barbarella to launch view and most of X goes dead. But not quite all of it. For example, I can move my mouse but not click it. I can use the keyboard to change consoles but not to write.

I went to console 2, logged in, and did a ps. I found that all the graphical stuff including the barbarellas was in state "T". And so was view. I'm not sure what that state is, but you can't kill them with a SIGTERM. You have to use SIGKILL (kill -9) and then those processes become zombies.

I checked the file descriptors for view and it just had the three standard channels, all going to /dev/tty1, which is odd when you consider that barbarella, the parent of view, has stdin set to /dev/null and not /dev/tty1.

I killed view to see if that cleared the block. It didn't. I killed the barbarellas with killall -9. Still blocked. I killed fluxbox and X went down, which cleared everything.

Any explanations?

PS: I find that state T means stopped. Just like a background job gets stopped when it tries to use the console. And I bet that's because the console belongs to X.

Last edited by hazel; 06-11-2019 at 02:26 PM. Reason: Added PS
 
Old 06-11-2019, 05:27 PM   #22
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,918

Rep: Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035
Code:
$ view /etc/hosts </dev/null >/dev/null 2>&1
$ echo $?
1
$ view /etc/hosts </dev/null >/dev/null
Vim: Warning: Output is not to a terminal
Vim: Warning: Input is not from a terminal
This quick test seems to suggest that view is using stderr to find its terminal, or at least it errors out with exit 1 when it can't access stderr. The second example has to be killed.



Quick trace shows this:
Code:
ioctl(0, SNDCTL_TMR_START or TCSETS, {B0 -opost -isig -icanon -echo ...}) = -1 ENOTTY (Inappropriate ioctl for device)
close(0)                                = 0
dup(2)
It looks like vim tries to dup() stderr if it can't use stdin. As I mentioned earlier, Shenanigans!

Still doesn't explain why your X input is getting locked out, or the stopped processes.

Last edited by GazL; 06-11-2019 at 05:47 PM.
 
Old 06-12-2019, 01:38 AM   #23
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,039

Rep: Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347
did you try pstree? Do you know what is the parent of that view process?
I told you already view inherited stdin/out from X, not from barbarella or any other process.
 
Old 06-12-2019, 05:49 AM   #24
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,680

Original Poster
Blog Entries: 19

Rep: Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492
Here's the relevant part of pstree. You can see that programs launched by barbarella are children of barbarella and grandchildren of fluxbox.

|-bash---startx---xinit-+-Xorg
| `-fluxbox-+-barbarella---xterm---bash---pstree
| |-barbarella---claws-mail
| |-3*[barbarella]
| `-fbsetbg
 
Old 06-12-2019, 06:40 AM   #25
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,918

Rep: Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035
This is just a hunch, but try including a setpgid(0,0); after you fork() and just before you exec() in order to move the forked process into its own process group. It's possible that vim/view is generating a SIGTTIN for the entire process group when trying to read the console. That would explain your 'T' process state.

vim/view is still being naughty by duplicating stderr to stdin rather than just erroring out, but at least it'll be its only victim by doing the above.


edit: ok according to the fork() manpage the child process should get a new pgid anyway, so I'm back to scratching my head and looking confused

scratch that last bit, I misread the fork manpage.

setsid() might even be a better choice than setpgid() if you want to disassociate from the controlling terminal, which might make sense for an X11 application.

Last edited by GazL; 06-12-2019 at 08:06 AM. Reason: edit2: scratch that I misread
 
1 members found this post helpful.
Old 06-12-2019, 10:33 AM   #26
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,680

Original Poster
Blog Entries: 19

Rep: Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492
GazL, you nailed it! Thank you! I put setpgid into the barbarella program and now it launches view without anything seizing up. Of course view is invisible as it hasn't got a terminal, and ps shows it as "T" aka "stopped", but nothing else is affected. Just out of interest, here are view's file descriptors:
Code:
lrwx------ 1 hazel hazel 64 Jun 12 16:26 0 -> /dev/tty1
lrwx------ 1 hazel hazel 64 Jun 12 16:25 1 -> /dev/tty1
lrwx------ 1 hazel hazel 64 Jun 12 16:26 2 -> /dev/tty1
I still think this thread should be transferred to programming.
 
1 members found this post helpful.
Old 06-12-2019, 02:58 PM   #27
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,918

Rep: Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035
Quote:
Originally Posted by hazel View Post
GazL, you nailed it! Thank you!
You're welcome. It was interesting, if initially confusing, and gave me an opportunity to look into an area I'd not studied in much detail before.
 
Old 06-13-2019, 12:49 AM   #28
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,039

Rep: Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347Reputation: 7347
that still not explain how and why /dev/tty1 is used.
 
Old 06-13-2019, 03:41 AM   #29
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,680

Original Poster
Blog Entries: 19

Rep: Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492Reputation: 4492
Quote:
Originally Posted by pan64 View Post
that still not explain how and why /dev/tty1 is used.
Presumably it's used because X uses it and therefore fluxbox uses it. And everything that runs in X is a descendent of the window manager. Remember, this is Slackware so I'm starting X with startx (which is my preferred method anyway).

But that's not really the core of the problem, is it. The real problem is how X can be seized up by a trivial bug in a graphical application. That oughtn't to happen.

In Windows, if a program does something illegal, the whole system crashes and you get the blue screen of death. I read somewhere that early UNIX systems were like that too: if a program did something silly with a pointer and wrote into a major component's address space, it could bring that component down. It could even bring down the kernel and crash the whole system. That doesn't happen with Linux. So how come a program I wrote could effectively crash X?

This is not good.
 
Old 06-13-2019, 05:13 AM   #30
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,918

Rep: Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035Reputation: 5035
I'd be interested to see the output of
ps -u $LOGNAME -o pid,ppid,sess,pgid,tty,cmd as I have some suspicions about this, but don't want to jump the gun.

Also, can you say whether you start 'barbarella' from xinitrc, or the fluxbox 'startup' file.

Last edited by GazL; 06-13-2019 at 05:24 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
using netcat stdout and stdin data between computer and a bash script A-Rap Linux - General 1 03-19-2012 07:53 AM
redirecting stdin, stdout and stderr, and finding files name and other stats wroom Programming 4 08-14-2010 06:48 AM
[C] stdout and stdin replace by pipes and execve the child chudzielec Programming 6 01-27-2008 05:52 AM
Stdout And Stdin: Can't get it to do it "on the fly"... Eskild Programming 4 07-19-2005 12:41 PM
redirecting stdin and stdout with pipes: convincing apps they're for a terminal? prell Programming 1 09-02-2004 06:38 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 05:44 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration