fork.cc 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright [2021] JD.com, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. #include <sys/socket.h>
  18. #include <unistd.h>
  19. #include <stdlib.h>
  20. #include <sched.h>
  21. #include <string.h>
  22. #include <signal.h>
  23. #ifndef CLONE_PARENT
  24. #define CLONE_PARENT 0x00008000
  25. #endif
  26. #include "daemon_listener.h"
  27. #include "log/log.h"
  28. struct ForkInfo
  29. {
  30. char name[16];
  31. int fd;
  32. int (*entry)(void *);
  33. void *args;
  34. };
  35. static int CloneEntry(void *arg)
  36. {
  37. struct ForkInfo *info = (ForkInfo *)arg;
  38. send(info->fd, info->name, sizeof(info->name), 0);
  39. exit(info->entry(info->args));
  40. }
  41. int watch_dog_fork(const char *name, int (*entry)(void *), void *args)
  42. {
  43. /* 4K stack is enough for CloneEntry */
  44. char stack[4096];
  45. struct ForkInfo info;
  46. char *env = getenv(ENV_WATCHDOG_SOCKET_FD);
  47. info.fd = env == NULL ? -1 : atoi(env);
  48. log4cplus_debug("daemons fork, fd: %d, name: %s, args: %p", info.fd, name, args);
  49. if (info.fd <= 0) {
  50. int pid = fork();
  51. if (pid == 0)
  52. exit(entry(args));
  53. return pid;
  54. }
  55. strncpy(info.name, name, sizeof(info.name));
  56. info.entry = entry;
  57. info.args = args;
  58. return clone(
  59. /* entry */
  60. CloneEntry,
  61. stack + sizeof(stack) - 16,
  62. /* flag */
  63. CLONE_PARENT | SIGCHLD,
  64. /* data */
  65. &info
  66. );
  67. };