How do I let an SDL app (not running as root) use the console












13















I want to use an SDL-based program to display graphics on the console, without having to log on from the console, and without running the program as root. For example, I want to be able to run it via ssh. The target OS is raspbian.



Here is a short example in python to illustrate the problem:



import os, pygame
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
pygame.init()
s = pygame.display.set_mode()
print "Success"


This works (runs to completion, does not throw exceptions) if I run it from the console, and it works via ssh if I run it as root.



I have checked that my user is in the audio and video groups.



I have used strace to see what is different between running it from the console (which works), running it as root via ssh (also works), and running it as a regular user via ssh (doesn't work).



The first difference was that my user did not have permission to access /dev/tty0. I created a new group (tty0), put my user in that group, and added a udev rule to give that group access to /dev/tty0.



The strace output diverges at this ioctl call - the failure is show here; ioctl returns 0 when the program is run from the console or run from ssh as root:



open("/dev/tty", O_RDWR)                = 4
ioctl(4, VT_GETSTATE, 0xbeaa01f8) = -1 EINVAL (Invalid argument)


(The addresses also differ, but that isn't important.)



Given that my program works when it runs as root, I think this means I have a permissions problem. How do I give the necessary permissions to my user to be able to run this program without logging on at the console (and without running as root)?










share|improve this question

























  • What are the ownership/permissions on your framebuffer device?

    – Bandrami
    Oct 6 '15 at 6:53











  • Also /dev/tty generally requires membership in the console group to write to.

    – Bandrami
    Oct 6 '15 at 6:53











  • ajclarkson.co.uk/blog/pygame-no-root looks like a solution.

    – Arthur2e5
    Oct 23 '15 at 23:35
















13















I want to use an SDL-based program to display graphics on the console, without having to log on from the console, and without running the program as root. For example, I want to be able to run it via ssh. The target OS is raspbian.



Here is a short example in python to illustrate the problem:



import os, pygame
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
pygame.init()
s = pygame.display.set_mode()
print "Success"


This works (runs to completion, does not throw exceptions) if I run it from the console, and it works via ssh if I run it as root.



I have checked that my user is in the audio and video groups.



I have used strace to see what is different between running it from the console (which works), running it as root via ssh (also works), and running it as a regular user via ssh (doesn't work).



The first difference was that my user did not have permission to access /dev/tty0. I created a new group (tty0), put my user in that group, and added a udev rule to give that group access to /dev/tty0.



The strace output diverges at this ioctl call - the failure is show here; ioctl returns 0 when the program is run from the console or run from ssh as root:



open("/dev/tty", O_RDWR)                = 4
ioctl(4, VT_GETSTATE, 0xbeaa01f8) = -1 EINVAL (Invalid argument)


(The addresses also differ, but that isn't important.)



Given that my program works when it runs as root, I think this means I have a permissions problem. How do I give the necessary permissions to my user to be able to run this program without logging on at the console (and without running as root)?










share|improve this question

























  • What are the ownership/permissions on your framebuffer device?

    – Bandrami
    Oct 6 '15 at 6:53











  • Also /dev/tty generally requires membership in the console group to write to.

    – Bandrami
    Oct 6 '15 at 6:53











  • ajclarkson.co.uk/blog/pygame-no-root looks like a solution.

    – Arthur2e5
    Oct 23 '15 at 23:35














13












13








13


4






I want to use an SDL-based program to display graphics on the console, without having to log on from the console, and without running the program as root. For example, I want to be able to run it via ssh. The target OS is raspbian.



Here is a short example in python to illustrate the problem:



import os, pygame
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
pygame.init()
s = pygame.display.set_mode()
print "Success"


This works (runs to completion, does not throw exceptions) if I run it from the console, and it works via ssh if I run it as root.



I have checked that my user is in the audio and video groups.



I have used strace to see what is different between running it from the console (which works), running it as root via ssh (also works), and running it as a regular user via ssh (doesn't work).



The first difference was that my user did not have permission to access /dev/tty0. I created a new group (tty0), put my user in that group, and added a udev rule to give that group access to /dev/tty0.



The strace output diverges at this ioctl call - the failure is show here; ioctl returns 0 when the program is run from the console or run from ssh as root:



open("/dev/tty", O_RDWR)                = 4
ioctl(4, VT_GETSTATE, 0xbeaa01f8) = -1 EINVAL (Invalid argument)


(The addresses also differ, but that isn't important.)



Given that my program works when it runs as root, I think this means I have a permissions problem. How do I give the necessary permissions to my user to be able to run this program without logging on at the console (and without running as root)?










share|improve this question
















I want to use an SDL-based program to display graphics on the console, without having to log on from the console, and without running the program as root. For example, I want to be able to run it via ssh. The target OS is raspbian.



Here is a short example in python to illustrate the problem:



import os, pygame
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
pygame.init()
s = pygame.display.set_mode()
print "Success"


This works (runs to completion, does not throw exceptions) if I run it from the console, and it works via ssh if I run it as root.



I have checked that my user is in the audio and video groups.



I have used strace to see what is different between running it from the console (which works), running it as root via ssh (also works), and running it as a regular user via ssh (doesn't work).



The first difference was that my user did not have permission to access /dev/tty0. I created a new group (tty0), put my user in that group, and added a udev rule to give that group access to /dev/tty0.



The strace output diverges at this ioctl call - the failure is show here; ioctl returns 0 when the program is run from the console or run from ssh as root:



open("/dev/tty", O_RDWR)                = 4
ioctl(4, VT_GETSTATE, 0xbeaa01f8) = -1 EINVAL (Invalid argument)


(The addresses also differ, but that isn't important.)



Given that my program works when it runs as root, I think this means I have a permissions problem. How do I give the necessary permissions to my user to be able to run this program without logging on at the console (and without running as root)?







linux permissions console devices






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 20 '12 at 23:24









Gilles

540k12810941609




540k12810941609










asked Dec 20 '12 at 8:53









michaelmichael

6615




6615













  • What are the ownership/permissions on your framebuffer device?

    – Bandrami
    Oct 6 '15 at 6:53











  • Also /dev/tty generally requires membership in the console group to write to.

    – Bandrami
    Oct 6 '15 at 6:53











  • ajclarkson.co.uk/blog/pygame-no-root looks like a solution.

    – Arthur2e5
    Oct 23 '15 at 23:35



















  • What are the ownership/permissions on your framebuffer device?

    – Bandrami
    Oct 6 '15 at 6:53











  • Also /dev/tty generally requires membership in the console group to write to.

    – Bandrami
    Oct 6 '15 at 6:53











  • ajclarkson.co.uk/blog/pygame-no-root looks like a solution.

    – Arthur2e5
    Oct 23 '15 at 23:35

















What are the ownership/permissions on your framebuffer device?

– Bandrami
Oct 6 '15 at 6:53





What are the ownership/permissions on your framebuffer device?

– Bandrami
Oct 6 '15 at 6:53













Also /dev/tty generally requires membership in the console group to write to.

– Bandrami
Oct 6 '15 at 6:53





Also /dev/tty generally requires membership in the console group to write to.

– Bandrami
Oct 6 '15 at 6:53













ajclarkson.co.uk/blog/pygame-no-root looks like a solution.

– Arthur2e5
Oct 23 '15 at 23:35





ajclarkson.co.uk/blog/pygame-no-root looks like a solution.

– Arthur2e5
Oct 23 '15 at 23:35










3 Answers
3






active

oldest

votes


















3














My aim was the same as original poster’s one, but with one difference: I needed to run SDL application as a systemd daemon.
My Linux machine is Raspberry Pi 3 and operating system is Raspbian Jessie. There is no keyboard or mouse connected to RPi. I connect to it using SSH. My SDL app is actually a Pygame-based app. I set pygame/SDL to use the “fbcon” framebuffer driver via the SDL_VIDEODRIVER environment variable.
My systemd --version output is:




systemd 215
+PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ -SECCOMP -APPARMOR




My pygame package version is: (aptitude show python-pygame):




1.9.2~pre~r3348-2~bpo8+rpi1




My libSDL 1.2 version is: (aptitude show libsdl1.2debian - on your machine package name can be different):




1.2.15-10+rpi1




The recipe




  1. Set up permissions for /dev/tty and /dev/fb0 files as described in
    UDude’s answer. I discovered that /dev/console permission changes
    are not necessary in Raspbian Jessie.


  2. Add these lines to the [Service] section of your daemon’s .service
    file:



    User=pi #Your limited user name goes here
    StandardInput=tty
    StandardOutput=tty
    TTYPath=/dev/tty2 # I also tried /dev/tty1 and that didn't work for me


    In case anyone interested, here is the complete pyscopefb.service file I used:



    [Unit]
    Description=Pyscopefb test service
    Wants=network-online.target
    After=rsyslog.service
    After=network-online.target

    [Service]
    Restart=no
    ExecStart=/home/pi/Soft/Test/pygame/pyscopefb
    ExecStop=/bin/kill -INT $MAINPID
    OOMScoreAdjust=-100
    TimeoutStopSec=10s
    User=pi
    WorkingDirectory=/home/pi/Soft/Test/pygame
    StandardInput=tty
    StandardOutput=tty
    TTYPath=/dev/tty2

    [Install]
    WantedBy=multi-user.target



  3. Issue these commands in the command prompt (I assume pyscopefb.service file is already placed to the correct location where systemd can find it):



    sudo systemctl daemon-reload
    sudo systemctl start pyscopefb



This is working for me. Please note I didn’t test whether pygame application is able to receive keyboard and mouse events or not.



Bonus



I also had to solve another 2 problems which may be of interest as well





  1. There was blinking text cursor at the bottom of the screen with
    framebuffer graphics. To resolve that, I added to my application the
    following Python code which runs in my app before Pygame/SDL initialization:



    def _disable_text_cursor_blinking(self):
    command_to_run = ["/usr/bin/sudo", "sh", "-c", "echo 0 > /sys/class/graphics/fbcon/cursor_blink"]
    try:
    output = subprocess32.check_output(command_to_run, universal_newlines = True)
    self._log.info("_disable_text_cursor_blinking succeeded! Output was:n{output}", output = output)
    except subprocess32.CalledProcessError:
    self._log.failure("_disable_text_cursor_blinking failed!")
    raise



  2. After about 10 minutes screen connected to Raspberry Pi’s HDMI
    output turned black (but not powered off) and my graphics didn’t
    display, though Pygame reported no errors. This turned out to be a
    power saving feature. To disable that, I added the following Python
    code which also runs before Pygame/SDL initialization:



    def _disable_screen_blanking(self):
    command_to_run = ["/usr/bin/setterm", "--blank", "0"]
    try:
    output = subprocess32.check_output(command_to_run, universal_newlines = True)
    self._log.info("_disable_screen_blanking succeeded! Output was:n{output}", output = output)
    except subprocess32.CalledProcessError:
    self._log.failure("_disable_screen_blanking failed!")
    raise







share|improve this answer
























  • This was extremely helpful to me to accomplish starting pygame without having a keyboard connected to my Pi, so thank you! I wanted to mention that I found it simple enough to run pygame on /dev/tty7 and issue an ExecStartPre=/bin/chvt 7 to avoid the cursor thing, and it has the bonus of not colliding with agetty which runs by default on tty1–tty6.

    – dctucker
    Dec 13 '18 at 19:23



















2














Although you question is slightly ambiguous (what is meant by console), I will attempt to answer for the most common cases: /dev/console, /dev/tty, /dev/fb0 ...adapt this to the devices you need. We assume the username is "myuser."



Look at the permissions of the device (this is ubuntu 15.04)



odroid@mbrxu3:~/projects/sc$ ls -l /dev/console
crw------- 1 root root 5, 1 Oct 23 17:49 /dev/console

odroid@mbrxu3:~/projects/sc$ ls -l /dev/tty
crw-rw-rw- 1 root tty 5, 0 Oct 24 17:50 /dev/tty

odroid@mbrxu3:~/projects/sc$ ls -l /dev/fb0
crw-rw---- 1 root video 29, 0 Jan 1 2000 /dev/fb0


Take action



/dev/console



the group is "root" but no group access is allowed. I don't like just adding permissions to the root group, so instead I create a group and chgrp the file and change the permissions



$ sudo addgroup --system console
$ sudo chgrp console /dev/console
$ sudo chmod g+rw /dev/console
$ sudo usermod -a -G console <myuser> <==== replace <myuser>


/dev/tty



$ sudo usermod -a -G tty <myuser>


/dev/fb0



$ sudo usermod -a -G video <myuser> 


You can use the usermod command to add your user to all the above groups, too, if that is your need.






share|improve this answer































    0














    From my recent experience, besides granting permission to your tty device (as mentioned before) you need to do 2 additional things:




    • granting cap_sys_tty_config capability for the executable. If you are using python program you can do it like setcap cap_sys_tty_config+eip /usr/bin/python3.5 (substitute the path for python with your's). Of course, take into account that you are granting this capability for any python script.

    • running the process in a new virtual terminal, e.g. using openvt: openvt ./your_script.py






    share|improve this answer























      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "106"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f58961%2fhow-do-i-let-an-sdl-app-not-running-as-root-use-the-console%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      3














      My aim was the same as original poster’s one, but with one difference: I needed to run SDL application as a systemd daemon.
      My Linux machine is Raspberry Pi 3 and operating system is Raspbian Jessie. There is no keyboard or mouse connected to RPi. I connect to it using SSH. My SDL app is actually a Pygame-based app. I set pygame/SDL to use the “fbcon” framebuffer driver via the SDL_VIDEODRIVER environment variable.
      My systemd --version output is:




      systemd 215
      +PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ -SECCOMP -APPARMOR




      My pygame package version is: (aptitude show python-pygame):




      1.9.2~pre~r3348-2~bpo8+rpi1




      My libSDL 1.2 version is: (aptitude show libsdl1.2debian - on your machine package name can be different):




      1.2.15-10+rpi1




      The recipe




      1. Set up permissions for /dev/tty and /dev/fb0 files as described in
        UDude’s answer. I discovered that /dev/console permission changes
        are not necessary in Raspbian Jessie.


      2. Add these lines to the [Service] section of your daemon’s .service
        file:



        User=pi #Your limited user name goes here
        StandardInput=tty
        StandardOutput=tty
        TTYPath=/dev/tty2 # I also tried /dev/tty1 and that didn't work for me


        In case anyone interested, here is the complete pyscopefb.service file I used:



        [Unit]
        Description=Pyscopefb test service
        Wants=network-online.target
        After=rsyslog.service
        After=network-online.target

        [Service]
        Restart=no
        ExecStart=/home/pi/Soft/Test/pygame/pyscopefb
        ExecStop=/bin/kill -INT $MAINPID
        OOMScoreAdjust=-100
        TimeoutStopSec=10s
        User=pi
        WorkingDirectory=/home/pi/Soft/Test/pygame
        StandardInput=tty
        StandardOutput=tty
        TTYPath=/dev/tty2

        [Install]
        WantedBy=multi-user.target



      3. Issue these commands in the command prompt (I assume pyscopefb.service file is already placed to the correct location where systemd can find it):



        sudo systemctl daemon-reload
        sudo systemctl start pyscopefb



      This is working for me. Please note I didn’t test whether pygame application is able to receive keyboard and mouse events or not.



      Bonus



      I also had to solve another 2 problems which may be of interest as well





      1. There was blinking text cursor at the bottom of the screen with
        framebuffer graphics. To resolve that, I added to my application the
        following Python code which runs in my app before Pygame/SDL initialization:



        def _disable_text_cursor_blinking(self):
        command_to_run = ["/usr/bin/sudo", "sh", "-c", "echo 0 > /sys/class/graphics/fbcon/cursor_blink"]
        try:
        output = subprocess32.check_output(command_to_run, universal_newlines = True)
        self._log.info("_disable_text_cursor_blinking succeeded! Output was:n{output}", output = output)
        except subprocess32.CalledProcessError:
        self._log.failure("_disable_text_cursor_blinking failed!")
        raise



      2. After about 10 minutes screen connected to Raspberry Pi’s HDMI
        output turned black (but not powered off) and my graphics didn’t
        display, though Pygame reported no errors. This turned out to be a
        power saving feature. To disable that, I added the following Python
        code which also runs before Pygame/SDL initialization:



        def _disable_screen_blanking(self):
        command_to_run = ["/usr/bin/setterm", "--blank", "0"]
        try:
        output = subprocess32.check_output(command_to_run, universal_newlines = True)
        self._log.info("_disable_screen_blanking succeeded! Output was:n{output}", output = output)
        except subprocess32.CalledProcessError:
        self._log.failure("_disable_screen_blanking failed!")
        raise







      share|improve this answer
























      • This was extremely helpful to me to accomplish starting pygame without having a keyboard connected to my Pi, so thank you! I wanted to mention that I found it simple enough to run pygame on /dev/tty7 and issue an ExecStartPre=/bin/chvt 7 to avoid the cursor thing, and it has the bonus of not colliding with agetty which runs by default on tty1–tty6.

        – dctucker
        Dec 13 '18 at 19:23
















      3














      My aim was the same as original poster’s one, but with one difference: I needed to run SDL application as a systemd daemon.
      My Linux machine is Raspberry Pi 3 and operating system is Raspbian Jessie. There is no keyboard or mouse connected to RPi. I connect to it using SSH. My SDL app is actually a Pygame-based app. I set pygame/SDL to use the “fbcon” framebuffer driver via the SDL_VIDEODRIVER environment variable.
      My systemd --version output is:




      systemd 215
      +PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ -SECCOMP -APPARMOR




      My pygame package version is: (aptitude show python-pygame):




      1.9.2~pre~r3348-2~bpo8+rpi1




      My libSDL 1.2 version is: (aptitude show libsdl1.2debian - on your machine package name can be different):




      1.2.15-10+rpi1




      The recipe




      1. Set up permissions for /dev/tty and /dev/fb0 files as described in
        UDude’s answer. I discovered that /dev/console permission changes
        are not necessary in Raspbian Jessie.


      2. Add these lines to the [Service] section of your daemon’s .service
        file:



        User=pi #Your limited user name goes here
        StandardInput=tty
        StandardOutput=tty
        TTYPath=/dev/tty2 # I also tried /dev/tty1 and that didn't work for me


        In case anyone interested, here is the complete pyscopefb.service file I used:



        [Unit]
        Description=Pyscopefb test service
        Wants=network-online.target
        After=rsyslog.service
        After=network-online.target

        [Service]
        Restart=no
        ExecStart=/home/pi/Soft/Test/pygame/pyscopefb
        ExecStop=/bin/kill -INT $MAINPID
        OOMScoreAdjust=-100
        TimeoutStopSec=10s
        User=pi
        WorkingDirectory=/home/pi/Soft/Test/pygame
        StandardInput=tty
        StandardOutput=tty
        TTYPath=/dev/tty2

        [Install]
        WantedBy=multi-user.target



      3. Issue these commands in the command prompt (I assume pyscopefb.service file is already placed to the correct location where systemd can find it):



        sudo systemctl daemon-reload
        sudo systemctl start pyscopefb



      This is working for me. Please note I didn’t test whether pygame application is able to receive keyboard and mouse events or not.



      Bonus



      I also had to solve another 2 problems which may be of interest as well





      1. There was blinking text cursor at the bottom of the screen with
        framebuffer graphics. To resolve that, I added to my application the
        following Python code which runs in my app before Pygame/SDL initialization:



        def _disable_text_cursor_blinking(self):
        command_to_run = ["/usr/bin/sudo", "sh", "-c", "echo 0 > /sys/class/graphics/fbcon/cursor_blink"]
        try:
        output = subprocess32.check_output(command_to_run, universal_newlines = True)
        self._log.info("_disable_text_cursor_blinking succeeded! Output was:n{output}", output = output)
        except subprocess32.CalledProcessError:
        self._log.failure("_disable_text_cursor_blinking failed!")
        raise



      2. After about 10 minutes screen connected to Raspberry Pi’s HDMI
        output turned black (but not powered off) and my graphics didn’t
        display, though Pygame reported no errors. This turned out to be a
        power saving feature. To disable that, I added the following Python
        code which also runs before Pygame/SDL initialization:



        def _disable_screen_blanking(self):
        command_to_run = ["/usr/bin/setterm", "--blank", "0"]
        try:
        output = subprocess32.check_output(command_to_run, universal_newlines = True)
        self._log.info("_disable_screen_blanking succeeded! Output was:n{output}", output = output)
        except subprocess32.CalledProcessError:
        self._log.failure("_disable_screen_blanking failed!")
        raise







      share|improve this answer
























      • This was extremely helpful to me to accomplish starting pygame without having a keyboard connected to my Pi, so thank you! I wanted to mention that I found it simple enough to run pygame on /dev/tty7 and issue an ExecStartPre=/bin/chvt 7 to avoid the cursor thing, and it has the bonus of not colliding with agetty which runs by default on tty1–tty6.

        – dctucker
        Dec 13 '18 at 19:23














      3












      3








      3







      My aim was the same as original poster’s one, but with one difference: I needed to run SDL application as a systemd daemon.
      My Linux machine is Raspberry Pi 3 and operating system is Raspbian Jessie. There is no keyboard or mouse connected to RPi. I connect to it using SSH. My SDL app is actually a Pygame-based app. I set pygame/SDL to use the “fbcon” framebuffer driver via the SDL_VIDEODRIVER environment variable.
      My systemd --version output is:




      systemd 215
      +PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ -SECCOMP -APPARMOR




      My pygame package version is: (aptitude show python-pygame):




      1.9.2~pre~r3348-2~bpo8+rpi1




      My libSDL 1.2 version is: (aptitude show libsdl1.2debian - on your machine package name can be different):




      1.2.15-10+rpi1




      The recipe




      1. Set up permissions for /dev/tty and /dev/fb0 files as described in
        UDude’s answer. I discovered that /dev/console permission changes
        are not necessary in Raspbian Jessie.


      2. Add these lines to the [Service] section of your daemon’s .service
        file:



        User=pi #Your limited user name goes here
        StandardInput=tty
        StandardOutput=tty
        TTYPath=/dev/tty2 # I also tried /dev/tty1 and that didn't work for me


        In case anyone interested, here is the complete pyscopefb.service file I used:



        [Unit]
        Description=Pyscopefb test service
        Wants=network-online.target
        After=rsyslog.service
        After=network-online.target

        [Service]
        Restart=no
        ExecStart=/home/pi/Soft/Test/pygame/pyscopefb
        ExecStop=/bin/kill -INT $MAINPID
        OOMScoreAdjust=-100
        TimeoutStopSec=10s
        User=pi
        WorkingDirectory=/home/pi/Soft/Test/pygame
        StandardInput=tty
        StandardOutput=tty
        TTYPath=/dev/tty2

        [Install]
        WantedBy=multi-user.target



      3. Issue these commands in the command prompt (I assume pyscopefb.service file is already placed to the correct location where systemd can find it):



        sudo systemctl daemon-reload
        sudo systemctl start pyscopefb



      This is working for me. Please note I didn’t test whether pygame application is able to receive keyboard and mouse events or not.



      Bonus



      I also had to solve another 2 problems which may be of interest as well





      1. There was blinking text cursor at the bottom of the screen with
        framebuffer graphics. To resolve that, I added to my application the
        following Python code which runs in my app before Pygame/SDL initialization:



        def _disable_text_cursor_blinking(self):
        command_to_run = ["/usr/bin/sudo", "sh", "-c", "echo 0 > /sys/class/graphics/fbcon/cursor_blink"]
        try:
        output = subprocess32.check_output(command_to_run, universal_newlines = True)
        self._log.info("_disable_text_cursor_blinking succeeded! Output was:n{output}", output = output)
        except subprocess32.CalledProcessError:
        self._log.failure("_disable_text_cursor_blinking failed!")
        raise



      2. After about 10 minutes screen connected to Raspberry Pi’s HDMI
        output turned black (but not powered off) and my graphics didn’t
        display, though Pygame reported no errors. This turned out to be a
        power saving feature. To disable that, I added the following Python
        code which also runs before Pygame/SDL initialization:



        def _disable_screen_blanking(self):
        command_to_run = ["/usr/bin/setterm", "--blank", "0"]
        try:
        output = subprocess32.check_output(command_to_run, universal_newlines = True)
        self._log.info("_disable_screen_blanking succeeded! Output was:n{output}", output = output)
        except subprocess32.CalledProcessError:
        self._log.failure("_disable_screen_blanking failed!")
        raise







      share|improve this answer













      My aim was the same as original poster’s one, but with one difference: I needed to run SDL application as a systemd daemon.
      My Linux machine is Raspberry Pi 3 and operating system is Raspbian Jessie. There is no keyboard or mouse connected to RPi. I connect to it using SSH. My SDL app is actually a Pygame-based app. I set pygame/SDL to use the “fbcon” framebuffer driver via the SDL_VIDEODRIVER environment variable.
      My systemd --version output is:




      systemd 215
      +PAM +AUDIT +SELINUX +IMA +SYSVINIT +LIBCRYPTSETUP +GCRYPT +ACL +XZ -SECCOMP -APPARMOR




      My pygame package version is: (aptitude show python-pygame):




      1.9.2~pre~r3348-2~bpo8+rpi1




      My libSDL 1.2 version is: (aptitude show libsdl1.2debian - on your machine package name can be different):




      1.2.15-10+rpi1




      The recipe




      1. Set up permissions for /dev/tty and /dev/fb0 files as described in
        UDude’s answer. I discovered that /dev/console permission changes
        are not necessary in Raspbian Jessie.


      2. Add these lines to the [Service] section of your daemon’s .service
        file:



        User=pi #Your limited user name goes here
        StandardInput=tty
        StandardOutput=tty
        TTYPath=/dev/tty2 # I also tried /dev/tty1 and that didn't work for me


        In case anyone interested, here is the complete pyscopefb.service file I used:



        [Unit]
        Description=Pyscopefb test service
        Wants=network-online.target
        After=rsyslog.service
        After=network-online.target

        [Service]
        Restart=no
        ExecStart=/home/pi/Soft/Test/pygame/pyscopefb
        ExecStop=/bin/kill -INT $MAINPID
        OOMScoreAdjust=-100
        TimeoutStopSec=10s
        User=pi
        WorkingDirectory=/home/pi/Soft/Test/pygame
        StandardInput=tty
        StandardOutput=tty
        TTYPath=/dev/tty2

        [Install]
        WantedBy=multi-user.target



      3. Issue these commands in the command prompt (I assume pyscopefb.service file is already placed to the correct location where systemd can find it):



        sudo systemctl daemon-reload
        sudo systemctl start pyscopefb



      This is working for me. Please note I didn’t test whether pygame application is able to receive keyboard and mouse events or not.



      Bonus



      I also had to solve another 2 problems which may be of interest as well





      1. There was blinking text cursor at the bottom of the screen with
        framebuffer graphics. To resolve that, I added to my application the
        following Python code which runs in my app before Pygame/SDL initialization:



        def _disable_text_cursor_blinking(self):
        command_to_run = ["/usr/bin/sudo", "sh", "-c", "echo 0 > /sys/class/graphics/fbcon/cursor_blink"]
        try:
        output = subprocess32.check_output(command_to_run, universal_newlines = True)
        self._log.info("_disable_text_cursor_blinking succeeded! Output was:n{output}", output = output)
        except subprocess32.CalledProcessError:
        self._log.failure("_disable_text_cursor_blinking failed!")
        raise



      2. After about 10 minutes screen connected to Raspberry Pi’s HDMI
        output turned black (but not powered off) and my graphics didn’t
        display, though Pygame reported no errors. This turned out to be a
        power saving feature. To disable that, I added the following Python
        code which also runs before Pygame/SDL initialization:



        def _disable_screen_blanking(self):
        command_to_run = ["/usr/bin/setterm", "--blank", "0"]
        try:
        output = subprocess32.check_output(command_to_run, universal_newlines = True)
        self._log.info("_disable_screen_blanking succeeded! Output was:n{output}", output = output)
        except subprocess32.CalledProcessError:
        self._log.failure("_disable_screen_blanking failed!")
        raise








      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Aug 19 '17 at 12:05









      Roman MeRoman Me

      11112




      11112













      • This was extremely helpful to me to accomplish starting pygame without having a keyboard connected to my Pi, so thank you! I wanted to mention that I found it simple enough to run pygame on /dev/tty7 and issue an ExecStartPre=/bin/chvt 7 to avoid the cursor thing, and it has the bonus of not colliding with agetty which runs by default on tty1–tty6.

        – dctucker
        Dec 13 '18 at 19:23



















      • This was extremely helpful to me to accomplish starting pygame without having a keyboard connected to my Pi, so thank you! I wanted to mention that I found it simple enough to run pygame on /dev/tty7 and issue an ExecStartPre=/bin/chvt 7 to avoid the cursor thing, and it has the bonus of not colliding with agetty which runs by default on tty1–tty6.

        – dctucker
        Dec 13 '18 at 19:23

















      This was extremely helpful to me to accomplish starting pygame without having a keyboard connected to my Pi, so thank you! I wanted to mention that I found it simple enough to run pygame on /dev/tty7 and issue an ExecStartPre=/bin/chvt 7 to avoid the cursor thing, and it has the bonus of not colliding with agetty which runs by default on tty1–tty6.

      – dctucker
      Dec 13 '18 at 19:23





      This was extremely helpful to me to accomplish starting pygame without having a keyboard connected to my Pi, so thank you! I wanted to mention that I found it simple enough to run pygame on /dev/tty7 and issue an ExecStartPre=/bin/chvt 7 to avoid the cursor thing, and it has the bonus of not colliding with agetty which runs by default on tty1–tty6.

      – dctucker
      Dec 13 '18 at 19:23













      2














      Although you question is slightly ambiguous (what is meant by console), I will attempt to answer for the most common cases: /dev/console, /dev/tty, /dev/fb0 ...adapt this to the devices you need. We assume the username is "myuser."



      Look at the permissions of the device (this is ubuntu 15.04)



      odroid@mbrxu3:~/projects/sc$ ls -l /dev/console
      crw------- 1 root root 5, 1 Oct 23 17:49 /dev/console

      odroid@mbrxu3:~/projects/sc$ ls -l /dev/tty
      crw-rw-rw- 1 root tty 5, 0 Oct 24 17:50 /dev/tty

      odroid@mbrxu3:~/projects/sc$ ls -l /dev/fb0
      crw-rw---- 1 root video 29, 0 Jan 1 2000 /dev/fb0


      Take action



      /dev/console



      the group is "root" but no group access is allowed. I don't like just adding permissions to the root group, so instead I create a group and chgrp the file and change the permissions



      $ sudo addgroup --system console
      $ sudo chgrp console /dev/console
      $ sudo chmod g+rw /dev/console
      $ sudo usermod -a -G console <myuser> <==== replace <myuser>


      /dev/tty



      $ sudo usermod -a -G tty <myuser>


      /dev/fb0



      $ sudo usermod -a -G video <myuser> 


      You can use the usermod command to add your user to all the above groups, too, if that is your need.






      share|improve this answer




























        2














        Although you question is slightly ambiguous (what is meant by console), I will attempt to answer for the most common cases: /dev/console, /dev/tty, /dev/fb0 ...adapt this to the devices you need. We assume the username is "myuser."



        Look at the permissions of the device (this is ubuntu 15.04)



        odroid@mbrxu3:~/projects/sc$ ls -l /dev/console
        crw------- 1 root root 5, 1 Oct 23 17:49 /dev/console

        odroid@mbrxu3:~/projects/sc$ ls -l /dev/tty
        crw-rw-rw- 1 root tty 5, 0 Oct 24 17:50 /dev/tty

        odroid@mbrxu3:~/projects/sc$ ls -l /dev/fb0
        crw-rw---- 1 root video 29, 0 Jan 1 2000 /dev/fb0


        Take action



        /dev/console



        the group is "root" but no group access is allowed. I don't like just adding permissions to the root group, so instead I create a group and chgrp the file and change the permissions



        $ sudo addgroup --system console
        $ sudo chgrp console /dev/console
        $ sudo chmod g+rw /dev/console
        $ sudo usermod -a -G console <myuser> <==== replace <myuser>


        /dev/tty



        $ sudo usermod -a -G tty <myuser>


        /dev/fb0



        $ sudo usermod -a -G video <myuser> 


        You can use the usermod command to add your user to all the above groups, too, if that is your need.






        share|improve this answer


























          2












          2








          2







          Although you question is slightly ambiguous (what is meant by console), I will attempt to answer for the most common cases: /dev/console, /dev/tty, /dev/fb0 ...adapt this to the devices you need. We assume the username is "myuser."



          Look at the permissions of the device (this is ubuntu 15.04)



          odroid@mbrxu3:~/projects/sc$ ls -l /dev/console
          crw------- 1 root root 5, 1 Oct 23 17:49 /dev/console

          odroid@mbrxu3:~/projects/sc$ ls -l /dev/tty
          crw-rw-rw- 1 root tty 5, 0 Oct 24 17:50 /dev/tty

          odroid@mbrxu3:~/projects/sc$ ls -l /dev/fb0
          crw-rw---- 1 root video 29, 0 Jan 1 2000 /dev/fb0


          Take action



          /dev/console



          the group is "root" but no group access is allowed. I don't like just adding permissions to the root group, so instead I create a group and chgrp the file and change the permissions



          $ sudo addgroup --system console
          $ sudo chgrp console /dev/console
          $ sudo chmod g+rw /dev/console
          $ sudo usermod -a -G console <myuser> <==== replace <myuser>


          /dev/tty



          $ sudo usermod -a -G tty <myuser>


          /dev/fb0



          $ sudo usermod -a -G video <myuser> 


          You can use the usermod command to add your user to all the above groups, too, if that is your need.






          share|improve this answer













          Although you question is slightly ambiguous (what is meant by console), I will attempt to answer for the most common cases: /dev/console, /dev/tty, /dev/fb0 ...adapt this to the devices you need. We assume the username is "myuser."



          Look at the permissions of the device (this is ubuntu 15.04)



          odroid@mbrxu3:~/projects/sc$ ls -l /dev/console
          crw------- 1 root root 5, 1 Oct 23 17:49 /dev/console

          odroid@mbrxu3:~/projects/sc$ ls -l /dev/tty
          crw-rw-rw- 1 root tty 5, 0 Oct 24 17:50 /dev/tty

          odroid@mbrxu3:~/projects/sc$ ls -l /dev/fb0
          crw-rw---- 1 root video 29, 0 Jan 1 2000 /dev/fb0


          Take action



          /dev/console



          the group is "root" but no group access is allowed. I don't like just adding permissions to the root group, so instead I create a group and chgrp the file and change the permissions



          $ sudo addgroup --system console
          $ sudo chgrp console /dev/console
          $ sudo chmod g+rw /dev/console
          $ sudo usermod -a -G console <myuser> <==== replace <myuser>


          /dev/tty



          $ sudo usermod -a -G tty <myuser>


          /dev/fb0



          $ sudo usermod -a -G video <myuser> 


          You can use the usermod command to add your user to all the above groups, too, if that is your need.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Oct 25 '15 at 19:15









          UDudeUDude

          1493




          1493























              0














              From my recent experience, besides granting permission to your tty device (as mentioned before) you need to do 2 additional things:




              • granting cap_sys_tty_config capability for the executable. If you are using python program you can do it like setcap cap_sys_tty_config+eip /usr/bin/python3.5 (substitute the path for python with your's). Of course, take into account that you are granting this capability for any python script.

              • running the process in a new virtual terminal, e.g. using openvt: openvt ./your_script.py






              share|improve this answer




























                0














                From my recent experience, besides granting permission to your tty device (as mentioned before) you need to do 2 additional things:




                • granting cap_sys_tty_config capability for the executable. If you are using python program you can do it like setcap cap_sys_tty_config+eip /usr/bin/python3.5 (substitute the path for python with your's). Of course, take into account that you are granting this capability for any python script.

                • running the process in a new virtual terminal, e.g. using openvt: openvt ./your_script.py






                share|improve this answer


























                  0












                  0








                  0







                  From my recent experience, besides granting permission to your tty device (as mentioned before) you need to do 2 additional things:




                  • granting cap_sys_tty_config capability for the executable. If you are using python program you can do it like setcap cap_sys_tty_config+eip /usr/bin/python3.5 (substitute the path for python with your's). Of course, take into account that you are granting this capability for any python script.

                  • running the process in a new virtual terminal, e.g. using openvt: openvt ./your_script.py






                  share|improve this answer













                  From my recent experience, besides granting permission to your tty device (as mentioned before) you need to do 2 additional things:




                  • granting cap_sys_tty_config capability for the executable. If you are using python program you can do it like setcap cap_sys_tty_config+eip /usr/bin/python3.5 (substitute the path for python with your's). Of course, take into account that you are granting this capability for any python script.

                  • running the process in a new virtual terminal, e.g. using openvt: openvt ./your_script.py







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Feb 18 at 11:10









                  Eriks DobelisEriks Dobelis

                  1011




                  1011






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Unix & Linux Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f58961%2fhow-do-i-let-an-sdl-app-not-running-as-root-use-the-console%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      How to make a Squid Proxy server?

                      第一次世界大戦

                      Touch on Surface Book