dl-origin.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /* Find path of executable.
  2. Copyright (C) 1998-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, see
  15. <http://www.gnu.org/licenses/>. */
  16. #include <assert.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <unistd.h>
  20. #include <sys/param.h>
  21. #include <ldsodefs.h>
  22. #include <sysdep.h>
  23. #include <dl-dst.h>
  24. /* On Linux >= 2.1 systems which have the dcache implementation we can get
  25. the path of the application from the /proc/self/exe symlink. Try this
  26. first and fall back on the generic method if necessary. */
  27. const char *
  28. _dl_get_origin (void)
  29. {
  30. char linkval[PATH_MAX];
  31. char *result;
  32. int len;
  33. INTERNAL_SYSCALL_DECL (err);
  34. len = INTERNAL_SYSCALL (readlink, err, 3, "/proc/self/exe", linkval,
  35. sizeof (linkval));
  36. if (! INTERNAL_SYSCALL_ERROR_P (len, err) && len > 0 && linkval[0] != '[')
  37. {
  38. /* We can use this value. */
  39. assert (linkval[0] == '/');
  40. while (len > 1 && linkval[len - 1] != '/')
  41. --len;
  42. result = (char *) malloc (len + 1);
  43. if (result == NULL)
  44. result = (char *) -1;
  45. else if (len == 1)
  46. memcpy (result, "/", 2);
  47. else
  48. *((char *) __mempcpy (result, linkval, len - 1)) = '\0';
  49. }
  50. else
  51. {
  52. result = (char *) -1;
  53. /* We use the environment variable LD_ORIGIN_PATH. If it is set make
  54. a copy and strip out trailing slashes. */
  55. if (GLRO(dl_origin_path) != NULL)
  56. {
  57. size_t len = strlen (GLRO(dl_origin_path));
  58. result = (char *) malloc (len + 1);
  59. if (result == NULL)
  60. result = (char *) -1;
  61. else
  62. {
  63. char *cp = __mempcpy (result, GLRO(dl_origin_path), len);
  64. while (cp > result + 1 && cp[-1] == '/')
  65. --cp;
  66. *cp = '\0';
  67. }
  68. }
  69. }
  70. return result;
  71. }