Recent

Author Topic: unix daemon program.  (Read 1867 times)

BSaidus

  • Sr. Member
  • ****
  • Posts: 333
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
unix daemon program.
« on: January 22, 2020, 01:45:15 pm »
Hello.
i have under hand a small program on C written to be daemon and run forever sleeps seconds and try to start an external program
Code: C  [Select][+][-]
  1. /*
  2.         $Id$
  3.         part of m0n0wall (http://m0n0.ch/wall)
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <unistd.h>
  9.  
  10. /* usage: minicron interval pidfile cmd */
  11.  
  12. int main(int argc, char *argv[]) {
  13.        
  14.         int interval;
  15.         FILE *pidfd;
  16.        
  17.         if (argc < 4)
  18.                 exit(1);
  19.        
  20.         interval = atoi(argv[1]);
  21.         if (interval == 0)
  22.                 exit(1);
  23.        
  24.         /* unset loads of CGI environment variables */
  25.         unsetenv("CONTENT_TYPE"); unsetenv("GATEWAY_INTERFACE");
  26.         unsetenv("REMOTE_USER"); unsetenv("REMOTE_ADDR");
  27.         unsetenv("AUTH_TYPE"); unsetenv("SCRIPT_FILENAME");
  28.         unsetenv("CONTENT_LENGTH"); unsetenv("HTTP_USER_AGENT");
  29.         unsetenv("HTTP_HOST"); unsetenv("SERVER_SOFTWARE");
  30.         unsetenv("HTTP_REFERER"); unsetenv("SERVER_PROTOCOL");
  31.         unsetenv("REQUEST_METHOD"); unsetenv("SERVER_PORT");
  32.         unsetenv("SCRIPT_NAME"); unsetenv("SERVER_NAME");
  33.        
  34.         /* go into background */
  35.         if (daemon(0, 0) == -1)
  36.                 exit(1);
  37.        
  38.         /* write PID to file */
  39.         pidfd = fopen(argv[2], "w");
  40.         if (pidfd) {
  41.                 fprintf(pidfd, "%d\n", getpid());
  42.                 fclose(pidfd);
  43.         }
  44.                
  45.         while (1) {
  46.                 sleep(interval);
  47.                
  48.                 system(argv[3]);
  49.         }
  50. }
  51.  

I have translated this program in pascal
Code: Pascal  [Select][+][-]
  1. { minicron
  2.   translated from C minicron.c from m0n0wall project
  3.   usage : micron interval pidfile cmd
  4. }
  5. program project1;
  6.  
  7. {$mode objfpc}{$H+}
  8.  
  9. uses
  10.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  11.   cthreads,
  12.   {$ENDIF}{$ENDIF}
  13.   Classes,
  14.   sysutils,
  15.   BaseUnix,
  16.   Unix
  17.   { you can add units after this };
  18.  
  19. var
  20.   Interval: Integer;
  21.   pid : TPid;
  22.   Cmd: String;
  23.   pF: TextFile;
  24.  
  25. begin
  26.   // init global vars
  27.   interval := 0;
  28.  
  29.   // see how parameters
  30.   if ParamCount < 3 then begin WriteLn('error lunching must be 4 params'); Exit; end;
  31.   // see if 2nd arg is integer > 0
  32.   interval := StrToInt(ParamStr(1));
  33.   if interval = 0 then begin WriteLn('Interval must be > 0 '); Exit; end;
  34.   // daemon
  35.   pid := FpFork ;
  36.   if pid = -1 then begin WriteLn('no daemon '); Exit; end;
  37.   // file for pid!
  38.   pid := FpGetpid;
  39.   AssignFile( pF, ParamStr(2) );
  40.   rewrite(pF);
  41.   Write(pF, pid);
  42.   CloseFile(pF);
  43.   // run forever
  44.   while true do
  45.   begin
  46.     FpSleep(interval);
  47.     fpSystem(ParamStr(3));
  48.   end;
  49. end.
  50.  
  51.  

It runs but do not daemonize ( It do not return to Shell ).

Any help ??

PS: Program under FreeBSD 10.3 /
Lazarus version: 2.1.0
Lazarus svn revision: 59757M
fpc 3.3.1 revision 40491
« Last Edit: January 22, 2020, 01:47:54 pm by BSaidus »
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

Thaddy

  • Hero Member
  • *****
  • Posts: 10449
Re: unix daemon program.
« Reply #1 on: January 22, 2020, 01:57:00 pm »
Daemons - should - never return to shell or communicate with it. You need to write a - user space - controller application to do that.
Explanation: Daemons usually run with root privilege.
« Last Edit: January 22, 2020, 02:00:38 pm by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

MarkMLl

  • Hero Member
  • *****
  • Posts: 1219
Re: unix daemon program.
« Reply #2 on: January 22, 2020, 02:25:29 pm »
Daemons - should - never return to shell or communicate with it. You need to write a - user space - controller application to do that.
Explanation: Daemons usually run with root privilege.

Daemons should start with root privilege, and then give up as many capabilities as possible and/or revert to an unprivileged user:group before settling down into their main loop. That's been SOP for many years, and is why nobody:nogroup exists.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8722
  • FPC developer.
Re: unix daemon program.
« Reply #3 on: January 22, 2020, 02:33:19 pm »
Daemon is afaik more than just fork.

Look at fpc/packages/fcl-extra/src/unix/daemonapp.inc:34

(or use TService which is a daemon on *nix)

There are three results of fork:

<0  -> failure
>0  -> parent
=0  -> child.



Then the child does some things like setsid and umask, change working dir and close all input and outputs.

BSaidus

  • Sr. Member
  • ****
  • Posts: 333
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Re: unix daemon program.
« Reply #4 on: January 22, 2020, 02:41:16 pm »
First of all I'm in root ( I use the root user ).
If I use the fcl-extra, I need to use interfaces unit, therefor I must install libgtk*.so ( my system will be big).
So using TDaemon units is not recommended for me

The previous program in C works well, but the one on C do not.
When I invoke :   
Code: Text  [Select][+][-]
  1. root # ./micron 10 /mnt/d1/ffile.pid /mnt/d1/app
I think that the "micron" must fork and runs in background then and after then It will try to start the command line "/mnt/d1/app"

thanks.
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

Thaddy

  • Hero Member
  • *****
  • Posts: 10449
Re: unix daemon program.
« Reply #5 on: January 22, 2020, 02:49:44 pm »
Daemons should start with root privilege, and then give up as many capabilities as possible and/or revert to an unprivileged user:group before settling down into their main loop. That's been SOP for many years, and is why nobody:nogroup exists.
And nobody uses it, since there have been plenty of warnings not to do so.
https://en.wikipedia.org/wiki/Nobody_(username)

But any google search will wake you up. < grumpy  >:D >:D >:D first time this year>
Plz never advertise bad practice.

Citrix employee?  >:D
« Last Edit: January 22, 2020, 03:28:57 pm by Thaddy »
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8722
  • FPC developer.
Re: unix daemon program.
« Reply #6 on: January 22, 2020, 03:15:31 pm »
First of all I'm in root ( I use the root user ).
If I use the fcl-extra, I need to use interfaces unit, therefor I must install libgtk*.so ( my system will be big).

No. fcl-extra is part of FPC, and works without lazarus. Otherwise it wouldn't be part of FPC!?!?

But more importantly, you can also simply look at the source, which is better than just substituting a daemon() call in C with Fork() in Pascal and then wondering why it doesn't work.

MarkMLl

  • Hero Member
  • *****
  • Posts: 1219
Re: unix daemon program.
« Reply #7 on: January 22, 2020, 04:31:57 pm »
Daemons should start with root privilege, and then give up as many capabilities as possible and/or revert to an unprivileged user:group before settling down into their main loop. That's been SOP for many years, and is why nobody:nogroup exists.
And nobody uses it, since there have been plenty of warnings not to do so.
https://en.wikipedia.org/wiki/Nobody_(username)

Nobody should be able to use nobody, since nobody shouldn't have login rights. And while I note what you're saying, in the absence of a proper per-daemon unprivileged user it's still better to use nobody than to have unaudited code running as root and being ripe for the first script kiddy who manages to trigger a buffer overflow.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 932
  • Former Delphi 1-7, 10.2 User
Re: unix daemon program.
« Reply #8 on: January 22, 2020, 11:30:27 pm »
@BSaidus: The daemon() function is hiding some of the detail which you are missing. As you're using FreeBSD, refer to /usr/src/lib/libc/gen/daemon.c to see what is really happening when you call daemon().

An even better exposition with comments may be found in the source for the FreeBSD (by way of BSDI) daemon utility which you can find at /usr/src/usr.sbin/daemon/daemon.c. The daemon utility detaches itself from the controlling terminal and executes the program specified by its arguments.
o Lazarus v2.1.0 r63871, FPC v3.3.1 r46876, macOS 10.14.6 (with sup update), Xcode 11.3.1
o Lazarus v2.1.0 r61574, FPC v3.3.1 r42318, FreeBSD 12.1 amd64 (VMware Fusion VM)
o FPC 3.0.4, FreeBSD 12.2-STABLE r365646 amd64
o Lazarus v2.1.0 r61574, FPC v3.0.4, Ubuntu 18.04 (Parallels VM)

dbannon

  • Hero Member
  • *****
  • Posts: 1140
    • tomboy-ng, a rewrite of the classic Tomboy
Re: unix daemon program.
« Reply #9 on: January 23, 2020, 12:08:15 am »
Just about any app will run "as a daemon" as long as there is no need for interaction with the shell -

nohup ./project1 & [enter]

stdout is written to a file and you can control that behaviour. see "man nohup"

There is no specific need to run as root or nobody, if appropriate, it can be run as an ordinary user, its up to you to ensure its safe to do so of course.  A multiuser system obviously requires a higher standard than, for example a RasPi running a datalogger.

Davo
Lazarus 2, Linux (and reluctantly Win10, OSX)
My Project - https://github.com/tomboy-notes/tomboy-ng

PascalDragon

  • Hero Member
  • *****
  • Posts: 2107
  • Compiler Developer
Re: unix daemon program.
« Reply #10 on: January 23, 2020, 09:14:21 am »
Daemons - should - never return to shell or communicate with it. You need to write a - user space - controller application to do that.

This is about starting a daemon, not communicating with it.

Explanation: Daemons usually run with root privilege.

This is also highly simplified. Often daemons have dedicated non-login users so that their rights can be adjusted (e.g. Apache is often started as user www while MySQL often uses a mysql user; this are usually created when installing the daemon).

Thaddy

  • Hero Member
  • *****
  • Posts: 10449
Re: unix daemon program.
« Reply #11 on: January 23, 2020, 09:23:01 am »
This is also highly simplified.
Hence usually. But your point about a dedicated user with specific rights is correct and preferable.
When you ask a question that is actually answered in the documentation, you are either lazy or a moron.

BSaidus

  • Sr. Member
  • ****
  • Posts: 333
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Re: unix daemon program.
« Reply #12 on: January 23, 2020, 09:46:02 am »
Thanks for all responses.
I will investigate and tell you.

 :)
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

BSaidus

  • Sr. Member
  • ****
  • Posts: 333
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Re: unix daemon program.
« Reply #13 on: January 23, 2020, 05:21:32 pm »
Hello
Finally this is the code .
I found it.

Thank you for Help !! ;)

Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  7.   cthreads,
  8.   {$ENDIF}{$ENDIF}
  9.   Classes,
  10.   SysUtils,
  11.   BaseUnix,
  12.   Unix
  13.   { you can add units after this };
  14. var
  15.   pid: TPid;
  16.   intv: Integer;
  17.   f: TextFile;
  18. begin
  19.   // mcron 10 /pid.file /exe.file
  20.  
  21.   //if ParamCount < 3 then
  22.   //  Exit;
  23.  
  24.   //intv := StrToInt(ParamStr(1));
  25.   //if intv = 0 then Exit;
  26.  
  27.   pid := fpFork;
  28.   if (pid < 0) then
  29.     Exit;
  30.  
  31.   if pid > 0 then
  32.   begin
  33.     FpExit(0);  // I must exit with FpExit not Exit.
  34.   end;
  35.   //WriteLn(pid);
  36.   //if pid <> 0 then Exit;
  37.  
  38.   //case pid of
  39.   //  -1: Exit;
  40.   //  0: break;
  41.   //end;
  42.   //WriteLn('This is a test !!!');
  43.  
  44.   //AssignFile( f, ParamStr(2) );
  45.   //Rewrite( f );
  46.   //Write(f, FpGetpid);
  47.   //CloseFile(f);
  48.  
  49.  
  50.   while true do
  51.   begin
  52.     //WriteLn('This is a test in While!!!');
  53.     //FpSleep(intv);
  54.     FpSleep(10);
  55.     //if not FileExists( ParamStr( 2 ) ) then
  56.     fpSystem( PChar(ParamStr(3)));
  57.     //Exit;
  58.   end;
  59.  
  60.  
  61. end.
  62.  
  63.  
  64.  
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

 

TinyPortal © 2005-2018