lib: Add LIB_ERR_SYSTEM_CALL and convert VRF_SOCKET to SOCKET

Add a new error code LIB_ERR_SYSTEM_CALL to the ferr subsystem.
Additionally convert LIB_ERR_VRF_SOCKET to a more generic
LIB_ERR_SOCKET.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2018-06-14 09:13:18 -04:00 committed by Quentin Young
parent 3ec8b5b898
commit 481bc15ffc
11 changed files with 98 additions and 67 deletions

View File

@ -25,6 +25,8 @@
#include "buffer.h" #include "buffer.h"
#include "log.h" #include "log.h"
#include "network.h" #include "network.h"
#include "lib_errors.h"
#include <stddef.h> #include <stddef.h>
DEFINE_MTYPE_STATIC(LIB, BUFFER, "Buffer") DEFINE_MTYPE_STATIC(LIB, BUFFER, "Buffer")
@ -341,11 +343,11 @@ buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width,
iov_alloc * sizeof(*iov)); iov_alloc * sizeof(*iov));
} else { } else {
/* This should absolutely never occur. */ /* This should absolutely never occur. */
zlog_err( zlog_ferr(LIB_ERR_SYSTEM_CALL,
"%s: corruption detected: iov_small overflowed; " "%s: corruption detected: iov_small overflowed; "
"head %p, tail %p, head->next %p", "head %p, tail %p, head->next %p",
__func__, (void *)b->head, __func__, (void *)b->head,
(void *)b->tail, (void *)b->head->next); (void *)b->tail, (void *)b->head->next);
iov = XMALLOC(MTYPE_TMP, iov = XMALLOC(MTYPE_TMP,
iov_alloc * sizeof(*iov)); iov_alloc * sizeof(*iov));
memcpy(iov, small_iov, sizeof(small_iov)); memcpy(iov, small_iov, sizeof(small_iov));

View File

@ -45,6 +45,7 @@
#include "libfrr.h" #include "libfrr.h"
#include "jhash.h" #include "jhash.h"
#include "hook.h" #include "hook.h"
#include "lib_errors.h"
DEFINE_MTYPE(LIB, HOST, "Host config") DEFINE_MTYPE(LIB, HOST, "Host config")
DEFINE_MTYPE(LIB, COMPLETION, "Completion item") DEFINE_MTYPE(LIB, COMPLETION, "Completion item")
@ -2416,7 +2417,8 @@ static int set_log_file(struct vty *vty, const char *fname, int loglevel)
cwd[MAXPATHLEN] = '\0'; cwd[MAXPATHLEN] = '\0';
if (getcwd(cwd, MAXPATHLEN) == NULL) { if (getcwd(cwd, MAXPATHLEN) == NULL) {
zlog_err("config_log_file: Unable to alloc mem!"); zlog_ferr(LIB_ERR_SYSTEM_CALL,
"config_log_file: Unable to alloc mem!");
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }

View File

@ -35,9 +35,9 @@ static struct ferr_ref ferr_lib_err[] = {
.suggestion = "Ensure that there is sufficient memory to start processes and restart FRR", .suggestion = "Ensure that there is sufficient memory to start processes and restart FRR",
}, },
{ {
.code = LIB_ERR_VRF_SOCKET, .code = LIB_ERR_SOCKET,
.title = "VRF Socket Error", .title = "Socket Error",
.description = "When attempting to access a socket for the VRF specified, we\nwere unable to properly complete the request", .description = "When attempting to access a socket a system error has occured\nand we were unable to properly complete the request",
.suggestion = "Ensure that there is sufficient system resources available and\nensure that the frr user has sufficient permisions to work", .suggestion = "Ensure that there is sufficient system resources available and\nensure that the frr user has sufficient permisions to work",
}, },
{ {
@ -59,7 +59,13 @@ static struct ferr_ref ferr_lib_err[] = {
.suggestion = "Restart FRR" .suggestion = "Restart FRR"
}, },
{ {
.code = END_FERR .code = LIB_ERR_SYSTEM_CALL,
.title = "System Call Error",
.description = "FRR has detected a error from using a vital system call and has probably\nalready exited",
.suggestion = "Ensure permissions are correct for FRR and FRR user and groups are correct\nAdditionally check that system resources are still available"
},
{
.code = END_FERR,
} }
}; };

View File

@ -26,10 +26,11 @@
enum lib_ferr_refs { enum lib_ferr_refs {
LIB_ERR_PRIVILEGES = LIB_FERR_START, LIB_ERR_PRIVILEGES = LIB_FERR_START,
LIB_ERR_VRF_START, LIB_ERR_VRF_START,
LIB_ERR_VRF_SOCKET, LIB_ERR_SOCKET,
LIB_ERR_ZAPI_MISSMATCH, LIB_ERR_ZAPI_MISSMATCH,
LIB_ERR_ZAPI_ENCODE, LIB_ERR_ZAPI_ENCODE,
LIB_ERR_ZAPI_SOCKET, LIB_ERR_ZAPI_SOCKET,
LIB_ERR_SYSTEM_CALL,
}; };
extern void lib_error_init(void); extern void lib_error_init(void);

View File

@ -28,6 +28,8 @@
#include "log_int.h" #include "log_int.h"
#include "memory.h" #include "memory.h"
#include "command.h" #include "command.h"
#include "lib_errors.h"
#ifndef SUNOS_5 #ifndef SUNOS_5
#include <sys/un.h> #include <sys/un.h>
#endif #endif
@ -631,15 +633,16 @@ void zlog_backtrace(int priority)
size = backtrace(array, array_size(array)); size = backtrace(array, array_size(array));
if (size <= 0 || (size_t)size > array_size(array)) { if (size <= 0 || (size_t)size > array_size(array)) {
zlog_err( zlog_ferr(LIB_ERR_SYSTEM_CALL,
"Cannot get backtrace, returned invalid # of frames %d " "Cannot get backtrace, returned invalid # of frames %d "
"(valid range is between 1 and %lu)", "(valid range is between 1 and %lu)",
size, (unsigned long)(array_size(array))); size, (unsigned long)(array_size(array)));
return; return;
} }
zlog(priority, "Backtrace for %d stack frames:", size); zlog(priority, "Backtrace for %d stack frames:", size);
if (!(strings = backtrace_symbols(array, size))) { if (!(strings = backtrace_symbols(array, size))) {
zlog_err("Cannot get backtrace symbols (out of memory?)"); zlog_ferr(LIB_ERR_SYSTEM_CALL,
"Cannot get backtrace symbols (out of memory?)");
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
zlog(priority, "[bt %d] %p", i, array[i]); zlog(priority, "[bt %d] %p", i, array[i]);
} else { } else {
@ -712,10 +715,10 @@ void _zlog_assert_failed(const char *assertion, const char *file,
void memory_oom(size_t size, const char *name) void memory_oom(size_t size, const char *name)
{ {
zlog_err( zlog_ferr(LIB_ERR_SYSTEM_CALL,
"out of memory: failed to allocate %zu bytes for %s" "out of memory: failed to allocate %zu bytes for %s"
"object", "object",
size, name); size, name);
zlog_backtrace(LOG_ERR); zlog_backtrace(LOG_ERR);
abort(); abort();
} }
@ -864,9 +867,9 @@ int zlog_rotate(void)
save_errno = errno; save_errno = errno;
umask(oldumask); umask(oldumask);
if (zl->fp == NULL) { if (zl->fp == NULL) {
zlog_err( zlog_ferr(LIB_ERR_SYSTEM_CALL,
"Log rotate failed: cannot open file %s for append: %s", "Log rotate failed: cannot open file %s for append: %s",
zl->filename, safe_strerror(save_errno)); zl->filename, safe_strerror(save_errno));
ret = -1; ret = -1;
} else { } else {
logfile_fd = fileno(zl->fp); logfile_fd = fileno(zl->fp);

View File

@ -35,10 +35,10 @@
#include "ns.h" #include "ns.h"
#include "log.h" #include "log.h"
#include "memory.h" #include "memory.h"
#include "command.h" #include "command.h"
#include "vty.h" #include "vty.h"
#include "vrf.h" #include "vrf.h"
#include "lib_errors.h"
DEFINE_MTYPE_STATIC(LIB, NS, "NetNS Context") DEFINE_MTYPE_STATIC(LIB, NS, "NetNS Context")
DEFINE_MTYPE_STATIC(LIB, NS_NAME, "NetNS Name") DEFINE_MTYPE_STATIC(LIB, NS_NAME, "NetNS Name")
@ -219,8 +219,9 @@ static int ns_enable_internal(struct ns *ns, void (*func)(ns_id_t, void *))
} }
if (!ns_is_enabled(ns)) { if (!ns_is_enabled(ns)) {
zlog_err("Can not enable NS %u: %s!", ns->ns_id, zlog_ferr(LIB_ERR_SYSTEM_CALL,
safe_strerror(errno)); "Can not enable NS %u: %s!", ns->ns_id,
safe_strerror(errno));
return 0; return 0;
} }

View File

@ -24,6 +24,7 @@
#include <log.h> #include <log.h>
#include "version.h" #include "version.h"
#include "network.h" #include "network.h"
#include "lib_errors.h"
#define PIDFILE_MASK 0644 #define PIDFILE_MASK 0644
@ -41,8 +42,9 @@ pid_t pid_output(const char *path)
oldumask = umask(0777 & ~PIDFILE_MASK); oldumask = umask(0777 & ~PIDFILE_MASK);
fd = open(path, O_RDWR | O_CREAT, PIDFILE_MASK); fd = open(path, O_RDWR | O_CREAT, PIDFILE_MASK);
if (fd < 0) { if (fd < 0) {
zlog_err("Can't create pid lock file %s (%s), exiting", path, zlog_ferr(LIB_ERR_SYSTEM_CALL,
safe_strerror(errno)); "Can't create pid lock file %s (%s), exiting", path,
safe_strerror(errno));
umask(oldumask); umask(oldumask);
exit(1); exit(1);
} else { } else {
@ -57,22 +59,23 @@ pid_t pid_output(const char *path)
lock.l_whence = SEEK_SET; lock.l_whence = SEEK_SET;
if (fcntl(fd, F_SETLK, &lock) < 0) { if (fcntl(fd, F_SETLK, &lock) < 0) {
zlog_err("Could not lock pid_file %s (%s), exiting", zlog_ferr(LIB_ERR_SYSTEM_CALL,
path, safe_strerror(errno)); "Could not lock pid_file %s (%s), exiting",
path, safe_strerror(errno));
exit(1); exit(1);
} }
sprintf(buf, "%d\n", (int)pid); sprintf(buf, "%d\n", (int)pid);
pidsize = strlen(buf); pidsize = strlen(buf);
if ((tmp = write(fd, buf, pidsize)) != (int)pidsize) if ((tmp = write(fd, buf, pidsize)) != (int)pidsize)
zlog_err( zlog_ferr(LIB_ERR_SYSTEM_CALL,
"Could not write pid %d to pid_file %s, rc was %d: %s", "Could not write pid %d to pid_file %s, rc was %d: %s",
(int)pid, path, tmp, safe_strerror(errno)); (int)pid, path, tmp, safe_strerror(errno));
else if (ftruncate(fd, pidsize) < 0) else if (ftruncate(fd, pidsize) < 0)
zlog_err( zlog_ferr(LIB_ERR_SYSTEM_CALL,
"Could not truncate pid_file %s to %u bytes: %s", "Could not truncate pid_file %s to %u bytes: %s",
path, (unsigned int)pidsize, path, (unsigned int)pidsize,
safe_strerror(errno)); safe_strerror(errno));
} }
return pid; return pid;
} }

View File

@ -22,6 +22,7 @@
#include <sigevent.h> #include <sigevent.h>
#include <log.h> #include <log.h>
#include <memory.h> #include <memory.h>
#include <lib_errors.h>
#ifdef SA_SIGINFO #ifdef SA_SIGINFO
#ifdef HAVE_UCONTEXT_H #ifdef HAVE_UCONTEXT_H
@ -83,7 +84,8 @@ int quagga_sigevent_process(void)
sigdelset(&newmask, SIGKILL); sigdelset(&newmask, SIGKILL);
if ((sigprocmask(SIG_BLOCK, &newmask, &oldmask)) < 0) { if ((sigprocmask(SIG_BLOCK, &newmask, &oldmask)) < 0) {
zlog_err("quagga_signal_timer: couldnt block signals!"); zlog_ferr(LIB_ERR_SYSTEM_CALL,
"quagga_signal_timer: couldnt block signals!");
return -1; return -1;
} }
#endif /* SIGEVENT_BLOCK_SIGNALS */ #endif /* SIGEVENT_BLOCK_SIGNALS */

View File

@ -27,6 +27,7 @@
#include "log.h" #include "log.h"
#include "sockopt.h" #include "sockopt.h"
#include "sockunion.h" #include "sockunion.h"
#include "lib_errors.h"
void setsockopt_so_recvbuf(int sock, int size) void setsockopt_so_recvbuf(int sock, int size)
{ {
@ -61,8 +62,9 @@ int getsockopt_so_sendbuf(const int sock)
int ret = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&optval, int ret = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&optval,
&optlen); &optlen);
if (ret < 0) { if (ret < 0) {
zlog_err("fd %d: can't getsockopt SO_SNDBUF: %d (%s)", sock, zlog_ferr(LIB_ERR_SYSTEM_CALL,
errno, safe_strerror(errno)); "fd %d: can't getsockopt SO_SNDBUF: %d (%s)", sock,
errno, safe_strerror(errno));
return ret; return ret;
} }
return optval; return optval;
@ -670,8 +672,9 @@ int sockopt_tcp_signature(int sock, union sockunion *su, const char *password)
if (ENOENT == errno) if (ENOENT == errno)
ret = 0; ret = 0;
else else
zlog_err("sockopt_tcp_signature: setsockopt(%d): %s", zlog_ferr(LIB_ERR_SYSTEM_CALL,
sock, safe_strerror(errno)); "sockopt_tcp_signature: setsockopt(%d): %s",
sock, safe_strerror(errno));
} }
return ret; return ret;
#else /* HAVE_TCP_MD5SIG */ #else /* HAVE_TCP_MD5SIG */

View File

@ -545,7 +545,7 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
ret = vrf_switch_to_netns(vrf_id); ret = vrf_switch_to_netns(vrf_id);
if (ret < 0) if (ret < 0)
zlog_ferr(LIB_ERR_VRF_SOCKET, zlog_ferr(LIB_ERR_SOCKET,
"%s: Can't switch to VRF %u (%s)", __func__, vrf_id, "%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
safe_strerror(errno)); safe_strerror(errno));
@ -560,7 +560,7 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
save_errno = errno; save_errno = errno;
ret2 = vrf_switchback_to_initial(); ret2 = vrf_switchback_to_initial();
if (ret2 < 0) if (ret2 < 0)
zlog_ferr(LIB_ERR_VRF_SOCKET, zlog_ferr(LIB_ERR_SOCKET,
"%s: Can't switchback from VRF %u (%s)", __func__, "%s: Can't switchback from VRF %u (%s)", __func__,
vrf_id, safe_strerror(errno)); vrf_id, safe_strerror(errno));
errno = save_errno; errno = save_errno;
@ -914,14 +914,14 @@ int vrf_getaddrinfo(const char *node, const char *service,
ret = vrf_switch_to_netns(vrf_id); ret = vrf_switch_to_netns(vrf_id);
if (ret < 0) if (ret < 0)
zlog_ferr(LIB_ERR_VRF_SOCKET, zlog_ferr(LIB_ERR_SOCKET,
"%s: Can't switch to VRF %u (%s)", __func__, vrf_id, "%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
safe_strerror(errno)); safe_strerror(errno));
ret = getaddrinfo(node, service, hints, res); ret = getaddrinfo(node, service, hints, res);
save_errno = errno; save_errno = errno;
ret2 = vrf_switchback_to_initial(); ret2 = vrf_switchback_to_initial();
if (ret2 < 0) if (ret2 < 0)
zlog_ferr(LIB_ERR_VRF_SOCKET, zlog_ferr(LIB_ERR_SOCKET,
"%s: Can't switchback from VRF %u (%s)", __func__, "%s: Can't switchback from VRF %u (%s)", __func__,
vrf_id, safe_strerror(errno)); vrf_id, safe_strerror(errno));
errno = save_errno; errno = save_errno;
@ -934,7 +934,7 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
ret = vrf_switch_to_netns(vrf_id); ret = vrf_switch_to_netns(vrf_id);
if (ret < 0) { if (ret < 0) {
zlog_ferr(LIB_ERR_VRF_SOCKET, zlog_ferr(LIB_ERR_SOCKET,
"%s: Can't switch to VRF %u (%s)", __func__, vrf_id, "%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
safe_strerror(errno)); safe_strerror(errno));
return 0; return 0;
@ -943,7 +943,7 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
saved_errno = errno; saved_errno = errno;
ret = vrf_switchback_to_initial(); ret = vrf_switchback_to_initial();
if (ret < 0) if (ret < 0)
zlog_ferr(LIB_ERR_VRF_SOCKET, zlog_ferr(LIB_ERR_SOCKET,
"%s: Can't switchback from VRF %u (%s)", __func__, "%s: Can't switchback from VRF %u (%s)", __func__,
vrf_id, safe_strerror(errno)); vrf_id, safe_strerror(errno));
errno = saved_errno; errno = saved_errno;
@ -957,14 +957,14 @@ int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
ret = vrf_switch_to_netns(vrf_id); ret = vrf_switch_to_netns(vrf_id);
if (ret < 0) if (ret < 0)
zlog_ferr(LIB_ERR_VRF_SOCKET, zlog_ferr(LIB_ERR_SOCKET,
"%s: Can't switch to VRF %u (%s)", __func__, vrf_id, "%s: Can't switch to VRF %u (%s)", __func__, vrf_id,
safe_strerror(errno)); safe_strerror(errno));
ret = sockunion_socket(su); ret = sockunion_socket(su);
save_errno = errno; save_errno = errno;
ret2 = vrf_switchback_to_initial(); ret2 = vrf_switchback_to_initial();
if (ret2 < 0) if (ret2 < 0)
zlog_ferr(LIB_ERR_VRF_SOCKET, zlog_ferr(LIB_ERR_SOCKET,
"%s: Can't switchback from VRF %u (%s)", __func__, "%s: Can't switchback from VRF %u (%s)", __func__,
vrf_id, safe_strerror(errno)); vrf_id, safe_strerror(errno));
errno = save_errno; errno = save_errno;

View File

@ -1972,7 +1972,8 @@ static void vty_serv_sock_addrinfo(const char *hostname, unsigned short port)
ret = getaddrinfo(hostname, port_str, &req, &ainfo); ret = getaddrinfo(hostname, port_str, &req, &ainfo);
if (ret != 0) { if (ret != 0) {
zlog_err("getaddrinfo failed: %s", gai_strerror(ret)); zlog_ferr(LIB_ERR_SYSTEM_CALL,
"getaddrinfo failed: %s", gai_strerror(ret));
exit(1); exit(1);
} }
@ -2032,7 +2033,8 @@ static void vty_serv_un(const char *path)
/* Make UNIX domain socket. */ /* Make UNIX domain socket. */
sock = socket(AF_UNIX, SOCK_STREAM, 0); sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) { if (sock < 0) {
zlog_err("Cannot create unix stream socket: %s", zlog_ferr(LIB_ERR_SOCKET,
"Cannot create unix stream socket: %s",
safe_strerror(errno)); safe_strerror(errno));
return; return;
} }
@ -2051,15 +2053,18 @@ static void vty_serv_un(const char *path)
ret = bind(sock, (struct sockaddr *)&serv, len); ret = bind(sock, (struct sockaddr *)&serv, len);
if (ret < 0) { if (ret < 0) {
zlog_err("Cannot bind path %s: %s", path, safe_strerror(errno)); zlog_ferr(LIB_ERR_SOCKET,
"Cannot bind path %s: %s",
path, safe_strerror(errno));
close(sock); /* Avoid sd leak. */ close(sock); /* Avoid sd leak. */
return; return;
} }
ret = listen(sock, 5); ret = listen(sock, 5);
if (ret < 0) { if (ret < 0) {
zlog_err("listen(fd %d) failed: %s", sock, zlog_ferr(LIB_ERR_SOCKET,
safe_strerror(errno)); "listen(fd %d) failed: %s", sock,
safe_strerror(errno));
close(sock); /* Avoid sd leak. */ close(sock); /* Avoid sd leak. */
return; return;
} }
@ -2074,8 +2079,9 @@ static void vty_serv_un(const char *path)
if ((int)ids.gid_vty > 0) { if ((int)ids.gid_vty > 0) {
/* set group of socket */ /* set group of socket */
if (chown(path, -1, ids.gid_vty)) { if (chown(path, -1, ids.gid_vty)) {
zlog_err("vty_serv_un: could chown socket, %s", zlog_ferr(LIB_ERR_SYSTEM_CALL,
safe_strerror(errno)); "vty_serv_un: could chown socket, %s",
safe_strerror(errno));
} }
} }
@ -2480,9 +2486,9 @@ bool vty_read_config(const char *config_file, char *config_default_dir)
if (config_file != NULL) { if (config_file != NULL) {
if (!IS_DIRECTORY_SEP(config_file[0])) { if (!IS_DIRECTORY_SEP(config_file[0])) {
if (getcwd(cwd, MAXPATHLEN) == NULL) { if (getcwd(cwd, MAXPATHLEN) == NULL) {
zlog_err( zlog_ferr(LIB_ERR_SYSTEM_CALL,
"Failure to determine Current Working Directory %d!", "Failure to determine Current Working Directory %d!",
errno); errno);
exit(1); exit(1);
} }
tmp = XMALLOC(MTYPE_TMP, tmp = XMALLOC(MTYPE_TMP,
@ -2495,7 +2501,7 @@ bool vty_read_config(const char *config_file, char *config_default_dir)
confp = fopen(fullpath, "r"); confp = fopen(fullpath, "r");
if (confp == NULL) { if (confp == NULL) {
zlog_err("%s: failed to open configuration file %s: %s", zlog_warn("%s: failed to open configuration file %s: %s, checking backup",
__func__, fullpath, safe_strerror(errno)); __func__, fullpath, safe_strerror(errno));
confp = vty_use_backup_config(fullpath); confp = vty_use_backup_config(fullpath);
@ -2540,9 +2546,9 @@ bool vty_read_config(const char *config_file, char *config_default_dir)
#endif /* VTYSH */ #endif /* VTYSH */
confp = fopen(config_default_dir, "r"); confp = fopen(config_default_dir, "r");
if (confp == NULL) { if (confp == NULL) {
zlog_err("%s: failed to open configuration file %s: %s", zlog_warn("%s: failed to open configuration file %s: %s, checking backup",
__func__, config_default_dir, __func__, config_default_dir,
safe_strerror(errno)); safe_strerror(errno));
confp = vty_use_backup_config(config_default_dir); confp = vty_use_backup_config(config_default_dir);
if (confp) { if (confp) {
@ -3064,12 +3070,14 @@ static void vty_save_cwd(void)
* Hence not worrying about it too much. * Hence not worrying about it too much.
*/ */
if (!chdir(SYSCONFDIR)) { if (!chdir(SYSCONFDIR)) {
zlog_err("Failure to chdir to %s, errno: %d", zlog_ferr(LIB_ERR_SYSTEM_CALL,
SYSCONFDIR, errno); "Failure to chdir to %s, errno: %d",
SYSCONFDIR, errno);
exit(-1); exit(-1);
} }
if (getcwd(cwd, MAXPATHLEN) == NULL) { if (getcwd(cwd, MAXPATHLEN) == NULL) {
zlog_err("Failure to getcwd, errno: %d", errno); zlog_ferr(LIB_ERR_SYSTEM_CALL,
"Failure to getcwd, errno: %d", errno);
exit(-1); exit(-1);
} }
} }