0

I am having trouble daemonizing my server, I have tried using the daemon(0,0) function but get the same problem. Without the daemonizing function my server works like a charm but whenever i try to daemonize the server won't even start.

Here is my source code for the server:

    //Server

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <sys/stat.h>
    #include <signal.h>
    #include <wait.h>

    #define SOCK_PATH "echo_socket"


    void demonize()
    {
      pid_t pid, sid;

      pid = fork();

      if(pid < 0)
        {
          exit(EXIT_FAILURE);
        }

      if(pid > 0)
        {
          exit(EXIT_SUCCESS);
        }

      /* This is the child */

      umask(0);

      sid = setsid();
      if(sid < 0)
        {
          exit(EXIT_FAILURE);
        }

      if((chdir("/")) < 0)
        {
          exit(EXIT_FAILURE);
        }

      freopen("/dev/null", "r", stdin);
      freopen("/dev/null", "w", stdout);
      freopen("/dev/null", "w", stderr);
    }

    void sigchld_handler(int s)
    {
      while(waitpid(-1, NULL, WNOHANG) > 0);
    }

    void ENDTRANS()
    {
      switch(fork())
        {
        case 0:
          //Skriver ut End of transmission
          execlp("/bin/echo", "echo", "ENDOFTRANS", NULL);
          perror("Exec");

          exit(1);
          break;

        case -1:
          perror("Fork failed");
          exit(1);
        }
      wait(0);
    }

    int main(void)
    {
      int s, s2, t, len;
      struct sockaddr_un local, remote;
      struct sigaction sa;

      demonize();
      //daemon(0,0);
      //printf("%d\n", getppid());

      sa.sa_handler = sigchld_handler; //Reap all dead processes
      sigemptyset(&sa.sa_mask);
      sa.sa_flags = SA_RESTART;
      if(sigaction(SIGCHLD, &sa, NULL) == -1)
        {
          perror("sigaction");
          exit(1);
        }

      if((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
        {
          perror("socket");
          exit(1);
        }

      local.sun_family = AF_UNIX;
      strcpy(local.sun_path, SOCK_PATH);
      unlink(local.sun_path);
      len = strlen(local.sun_path) + sizeof(local.sun_family);

      if(bind(s, (struct sockaddr *)&local, len) == -1)
        {
          perror("Bind");
          exit(1);
        }

      if(listen(s, 5) == -1)
        {
          perror("listen");
          exit(1);
        }

      for(;;)
        {
          int done, n;
          printf("Waiting for a connection...\n");
          t = sizeof(remote);

          if((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1)
        {
          perror("accept");
          exit(1);
        }

          printf("Connected client, forking child\n");
          if(fork())
        {
          close(s2);
        }
          else
        {
          close(s);
          done = 0;
          do
            {
              char str[100] = "", tmp; int i;

              n = recv(s2,str,100,0);


              if(n <= 0 || strlen(str) == 0)
            {
              if(n < 0)
                perror("recv");
              done = 1;
            }

              if(!done)
            {
              dup2(s2, STDOUT_FILENO);
              dup2(s2, STDERR_FILENO);
              printf(">%s<\n\n",str);
              shell(&str);
              ENDTRANS();
            }

            }while(!done);
          close(s2);
          exit(EXIT_SUCCESS);
        }

        }
      return 0;
    }


    int shell(char *arg_list)
    {

      char directory[100];
      pid_t pid = fork();
      int i;

      switch(pid)
        {
        case -1:
          printf("Error");
          exit(0);

        case 0:
          if(arg_list[0] != 'c' && arg_list[1] != 'd')
        { 
          execlp("/bin/sh", "sh", "-c", arg_list, NULL);
        }
          else
        {
        }
          exit(0);

        default:

          if(arg_list[0] == 'c' && arg_list[1] == 'd')
        {
          for(i = 0; i < strlen(arg_list); i++)
            {
              if(arg_list[i+3] != '\0' && arg_list[i+3] != '\n')
            {
              directory[i] = arg_list[i+3];
            }
            }
          chdir(directory);
          wait(0);
        }
          else
        wait(0);
        }
    }
ZeppRock
  • 848
  • 1
  • 8
  • 21
  • 2
    If **your** code breaks after calling `daemon(0, 0)`... **your** code is probably the cause! Without knowing what you do, and without a [mcve], your question is just *unclear* – Serge Ballesta Mar 07 '16 at 11:07
  • Unrelated, but wrong: `if(n <= 0 || strlen(str) == 0)` :: str was read by recv(), but need not be nul-terminated at this point. – joop Mar 07 '16 at 11:41
  • You should never `exit` in the child if you also plan to allow the parent to continue running. This causes the parent's `atexit` handlers to run twice, once when the child calls `exit` and again when the parent does. In your case, they can run more than twice since each invocation of `fork` followed by `exit` in the child can run the parent's `atexit` handlers. This has caused serious bugs in the past with security implications. You should use `_exit` in the child. – David Schwartz Mar 07 '16 at 11:44
  • perhaps strace -f could give you a clue – GroovyDotCom Mar 07 '16 at 14:36

0 Answers0