How to make your computer beep

A few days ago I decided it would be fun to make my computers internal speaker beep. So I wrote a short C program.


#include <stdio.h>

int main(void)
{
    printf("\a
");
    return(0);
}

It did not beep.
A few days later I was going through interesting man pages and came upon busy box.
It also had a beep program so I used it.


$busybox beep
beep: can't open console

It did not beep.
So I used:

$sudo busybox beep

And it worked. So, what’s up?
Why do I need superuser privileges?
If I want a program that I make to beep how do I do it without superuser privileges?

On 2014-01-11 21:06, ballsystemlord wrote:
>
> A few days ago I decided it would be fun to make my computers internal
> speaker beep.

Yes, it would.
I tried this many years ago…


Telcontar:~ # l /root/bin/beep
-rwxr-xr-- 1 root root 686 Apr  6  2002 /root/bin/beep*
Telcontar:~ #

So I wrote a short C program.

It did not beep.

I know…

A few days later I was going through interesting man pages and came upon
busy box.
It also had a beep program so I used it.

Code:

$busybox beep
beep: can’t open console

Heh… it probably wants to write to /dev/console, and you have no rights.

If I want a program that I make to beep how do I do it without superuser
privileges?

It is an interesting linux design decision. To make a beep as user you
need a terminal and output to it. You do not have access to the built-in
speaker as in MsDOS, where I had programs that made it speak. Literally.

In Linux, access to the built-in speaker is made by the terminal, no
controlling of it. Only “beep”, and only if you do have a terminal.

To do without a terminal, they use /dev/console… and for that, you
need to be root, as you found out.


Telcontar:~ # l /dev/console
crw------- 1 root root 5, 1 Jan  7 14:59 /dev/console
Telcontar:~ #


Cheers / Saludos,

Carlos E. R.
(from 12.3 x86_64 “Dartmouth” at Telcontar)

Well, you can configure KDE to beep the speaker for messages as user.
That’s the function that is called if you press the “Test” button in KDE’s settings:

void KBellConfig::ringBell(){
  if (!m_useBell->isChecked()) {
    KNotification::beep(QString(), this);
    return;
  }


  // store the old state
  XKeyboardState old_state;
  XGetKeyboardControl(QX11Info::display(), &old_state);


  // switch to the test state
  XKeyboardControl kbd;
  kbd.bell_percent = m_volume->value();
  kbd.bell_pitch = m_pitch->value();
  if (m_volume->value() > 0)
    kbd.bell_duration = m_duration->value();
  else
    kbd.bell_duration = 0;
  XChangeKeyboardControl(QX11Info::display(),
                         KBBellPercent | KBBellPitch | KBBellDuration,
                         &kbd);
  // ring bell
  XBell(QX11Info::display(),0);


  // restore old state
  kbd.bell_percent = old_state.bell_percent;
  kbd.bell_pitch = old_state.bell_pitch;
  kbd.bell_duration = old_state.bell_duration;
  XChangeKeyboardControl(QX11Info::display(),
                         KBBellPercent | KBBellPitch | KBBellDuration,
                         &kbd);
}

So have a look at “man XBell”.

But this would only work when X is running of course.

This is all very interesting but I don’t understand how it helps me create a program that beeps. Should I create my program to allocate a terminal?

On 2014-02-05 18:16, ballsystemlord wrote:

> This is all very interesting but I don’t understand how it helps me
> create a program that beeps. Should I create my program to allocate a
> terminal?

I tell you what I know, and how difficult it is.

For example, I write programs in Pascal (Lazarus). The beep function
call of it does not work, or was removed, because they did not find a
way to make it work in Linux.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

Well, of course if you have an X-session running then you can write to /dev/tty7 as the (user logged in)

beep > /dev/tty7

and other tty devices if the user is a member of the ‘tty’ group (for write access).

Beep is just an alias

 type beep
beep is aliased to `echo -en "\007"'

so ‘echo -en “\007” > /dev/ttyx’ will work too.

On 2014-02-06 06:06, deano ferrari wrote:
>
> Well, of course if you have an X-session running then you can write to
> /dev/tty7 as the (user logged in)
>
> Code:
> --------------------
> beep > /dev/tty7
> --------------------


cer@minas-tirith:~> beep > /dev/tty7
bash: /dev/tty7: Permission denied
cer@minas-tirith:~>
cer@minas-tirith:~> l /dev/tty7
crw--w---- 1 root tty 4, 7 Feb  2 19:59 /dev/tty7
cer@minas-tirith:~>

Yes, I’m on tty7.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

cer@minas-tirith:~> beep > /dev/tty7
bash: /dev/tty7: Permission denied
cer@minas-tirith:~>
cer@minas-tirith:~> l /dev/tty7
crw–w---- 1 root tty 4, 7 Feb 2 19:59 /dev/tty7
cer@minas-tirith:~>

Yes, I’m on tty7.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

A ownership of the tty should be assigned to the current user

For example

 l /dev/tty7
crw--w---- 1 dean tty 4, 7 Feb  7 06:13 /dev/tty7

On 2014-02-06 18:36, deano ferrari wrote:

> A ownership of the tty should be assigned to the current user

By whom? It is not automatic. My system does not do it.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

If you log into a particular tty as a user, then that user should be assigned ownership as my output showed (eg I’m logged into KDE on local machine which gives me /dev/tty7). What happens if you do CTRL+ALT+F2 (for /dev/tty2) and log in as user? I get

l /dev/tty2
crw--w---- 1 dean tty 4, 2 Feb  7 06:16 /dev/tty2

I can confirm this.

# l /dev/tty?
crw--w---- 1 root  tty 4, 0  6. Feb 09:21 /dev/tty0
crw--w---- 1 root  tty 4, 1  6. Feb 09:22 /dev/tty1
crw--w---- 1 root  tty 4, 2  6. Feb 09:21 /dev/tty2
crw--w---- 1 root  tty 4, 3  6. Feb 09:21 /dev/tty3
crw--w---- 1 root  tty 4, 4  6. Feb 09:21 /dev/tty4
crw--w---- 1 root  tty 4, 5  6. Feb 09:21 /dev/tty5
crw--w---- 1 root  tty 4, 6  6. Feb 09:21 /dev/tty6
crw--w---- 1 wolfi tty 4, 7  6. Feb 15:15 /dev/tty7
crw--w---- 1 root  tty 4, 8  6. Feb 09:21 /dev/tty8
crw--w---- 1 root  tty 4, 9  6. Feb 09:21 /dev/tty9

I’m logged in to KDE on tty7 at the moment.

I guess logind takes care of that?

PS:
After pressing Ctrl+Alt+F1 and additionally logging in in text mode, I get this:

# l /dev/tty?
crw--w---- 1 root  tty 4, 0  6. Feb 09:21 /dev/tty0
crw--w---- 1 wolfi tty 4, 1  6. Feb 20:16 /dev/tty1
crw--w---- 1 root  tty 4, 2  6. Feb 09:21 /dev/tty2
crw--w---- 1 root  tty 4, 3  6. Feb 09:21 /dev/tty3
crw--w---- 1 root  tty 4, 4  6. Feb 09:21 /dev/tty4
crw--w---- 1 root  tty 4, 5  6. Feb 09:21 /dev/tty5
crw--w---- 1 root  tty 4, 6  6. Feb 09:21 /dev/tty6
crw--w---- 1 wolfi tty 4, 7  6. Feb 15:15 /dev/tty7
crw--w---- 1 root  tty 4, 8  6. Feb 09:21 /dev/tty8
crw--w---- 1 root  tty 4, 9  6. Feb 09:21 /dev/tty9

On 2014-02-06 20:26, wolfi323 wrote:

> I’m logged in to KDE on tty7 at the moment.
>
> I guess logind takes care of that?

I’m logged on XFCE (oS 13.1), and I get this:


cer@minas-tirith:~> l /dev/tty?
crw--w---- 1 root tty 4, 0 Feb  6 21:14 /dev/tty0
crw--w---- 1 root tty 4, 1 Feb  6 21:14 /dev/tty1
crw--w---- 1 cer  tty 4, 2 Feb  6 21:55 /dev/tty2
crw--w---- 1 root tty 4, 3 Feb  6 18:35 /dev/tty3
crw--w---- 1 root tty 4, 4 Feb  6 18:35 /dev/tty4
crw--w---- 1 root tty 4, 5 Feb  6 18:35 /dev/tty5
crw--w---- 1 root tty 4, 6 Feb  6 18:35 /dev/tty6
crw--w---- 1 root tty 4, 7 Feb  6 18:35 /dev/tty7
crw--w---- 1 root tty 4, 8 Feb  6 18:35 /dev/tty8
crw--w---- 1 root tty 4, 9 Feb  6 18:35 /dev/tty9
cer@minas-tirith:~>

So this ownership of tty7 is not universal.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

I never suggested that it was, just that if the user is logged in to a particular VT, then they have ownership. Otherwise other user process would not execute properly either. :wink:

Anyway, the underlying display manager sets the preferred VT. For example, I’m using KDM, and /usr/share/kde4/config/kdm/kdmrc conatains

ServerVTs=-7

XDM uses /etc/X11/xdm/Xservers with the default entry

:0 local /usr/bin/X -nolisten tcp -br vt7

On 2014-02-06 22:56, deano ferrari wrote:

> I never suggested that it was, just that if the user is logged in to a
> particular VT, then they have ownership. Otherwise other user process
> would not execute properly either. :wink:

But that is not true. I’m indeed logged in, I have no issues with any
application, and the tty is owned by root.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

I noted from your output

crw--w---- 1 cer  tty 4, 2 Feb  6 21:55 /dev/tty2

Is your X-session running on /dev/tty2 instead?

On 2014-02-06 23:26, deano ferrari wrote:

> Is your X-session running on /dev/tty2 instead?

Nope. That’s a text session I opened to see if the tty changed, and it did.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))

Again, I think logind does that. But I’m not sure.

How are you logging into XFCE? Do you use a display manager?
At least kdm and gdm are patched to register the session with logind. I’m not sure about others, and how startx f.e. would behave.

What does “loginctl” say inside your graphical session?

I guess this is likely to be related to your display manager.

For reference, I have two sessions currently active

loginctl list-sessions
   SESSION        UID USER             SEAT            
        79       1000 dean             seat0           
        80       1000 dean             seat0 

The first (79) is for VT2, the second (80) for my graphical KDE session

loginctl show-session 80
Id=80
Timestamp=Fri 2014-02-07 11:56:42 NZDT
TimestampMonotonic=60169267128
VTNr=7
Display=:0
Remote=no
Service=xdm
Scope=session-80.scope
Leader=22434
Audit=80
Type=x11
Class=user
Active=yes
State=active
IdleHint=no
IdleSinceHint=0
IdleSinceHintMonotonic=0
Name=dean

On 2014-02-07 00:36, wolfi323 wrote:

> Again, I think logind does that. But I’m not sure.
>
> How are you logging into XFCE? Do you use a display manager?

Yes, I do. In this case, lightdm.


> root      1483  0.0  0.1 267472  5380 ?        SLl  Feb06   0:00 /usr/sbin/lightdm
> root      1532  3.2  1.6 324572 65392 tty7     Ssl+ Feb06  13:10  \_ /usr/bin/X :0 -auth /run/lightdm/root/:0 -nolisten tcp vt7 -novtswitc
> root      1714  0.0  0.0 164344  3856 ?        Sl   Feb06   0:00  \_ lightdm --session-child 12 19
> cer       1735  0.0  0.0  10788   700 ?        Ss   Feb06   0:00      \_ /usr/bin/ck-launch-session /usr/bin/dbus-launch --sh-syntax --clo
> cer       1894  0.0  0.0  13108  1656 ?        S    Feb06   0:00          \_ /bin/sh /etc/xdg/xfce4/xinitrc -- /etc/X11/xinit/xserverrc
> cer       1906  0.0  0.3 346348 14296 ?        Sl   Feb06   0:02              \_ xfce4-session

What does “loginctl” say inside your graphical session?


cer@minas-tirith:~> loginctl
SESSION        UID USER             SEAT
1        494 lightdm          seat0
2       1000 cer              seat0
34       1000 cer              seat0

3 sessions listed.
cer@minas-tirith:~>

cer@minas-tirith:~> loginctl show-session 2
Id=2
Timestamp=Thu 2014-02-06 18:36:09 CET
TimestampMonotonic=68675485
VTNr=7
Display=:0
Remote=no
Service=lightdm
Scope=session-2.scope
Leader=1714
Audit=2
Type=x11
Class=user
Active=yes
State=active
IdleHint=no
IdleSinceHint=0
IdleSinceHintMonotonic=0
Name=cer
cer@minas-tirith:~>


As you see, it is registered. The details are the same as deano_ferrari
posted.


Cheers / Saludos,

Carlos E. R.

(from 13.1 x86_64 “Bottle” (Minas Tirith))