/**
* mds — A micro-display server
* Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include "util.h"
#include "config.h"
#include
#include
#include
#include
/**
* Read an environment variable, but handle it as undefined if empty
*
* @param var The environment variable's name
* @return The environment variable's value, `NULL` if empty or not defined
*/
char* getenv_nonempty(const char* var)
{
char* rc = getenv(var);
if ((rc == NULL) || (*rc == '\0'))
return NULL;
return rc;
}
/**
* Re-exec the server.
* This function only returns on failure.
*
* @param argc The number of elements in `argv`
* @param argv The command line arguments
* @param reexeced Whether the server has previously been re-exec:ed
*/
void reexec_server(int argc, char** argv, int reexeced)
{
char readlink_buf[PATH_MAX];
ssize_t readlink_ptr;
char** reexec_args;
char** reexec_args_;
int i;
/* Re-exec the server. */
readlink_ptr = readlink(SELF_EXE, readlink_buf, (sizeof(readlink_buf) / sizeof(char)) - 1);
if (readlink_ptr < 0)
return;
/* ‘readlink() does not append a null byte to buf.’ */
readlink_buf[readlink_ptr] = '\0';
reexec_args = alloca(((size_t)argc + 2) * sizeof(char*));
reexec_args_ = reexec_args;
if (reexeced == 0)
{
*reexec_args_++ = *argv;
*reexec_args_ = strdup("--re-exec");
if (*reexec_args_)
return;
for (i = 1; i < argc; i++)
reexec_args_[i] = argv[i];
}
else /* Don't let the --re-exec:s accumulate. */
*reexec_args_ = *argv;
for (i = 1; i < argc; i++)
reexec_args_[i] = argv[i];
reexec_args_[argc] = NULL;
execv(readlink_buf, reexec_args);
}