process-posix.cpp revision 26ce84897df60fed28f68a98b91ce82aed9f0ee7
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* $Id$ */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/** @file
199767f8919635c4928607450d9e0abb932109ceToomas Soome * innotek Portable Runtime - Process, POSIX.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (C) 2006-2007 innotek GmbH
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * This file is part of VirtualBox Open Source Edition (OSE), as
199767f8919635c4928607450d9e0abb932109ceToomas Soome * available from http://www.virtualbox.org. This file is free software;
199767f8919635c4928607450d9e0abb932109ceToomas Soome * you can redistribute it and/or modify it under the terms of the GNU
199767f8919635c4928607450d9e0abb932109ceToomas Soome * General Public License as published by the Free Software Foundation,
199767f8919635c4928607450d9e0abb932109ceToomas Soome * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * distribution. VirtualBox OSE is distributed in the hope that it will
199767f8919635c4928607450d9e0abb932109ceToomas Soome * be useful, but WITHOUT ANY WARRANTY of any kind.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * If you received this file as part of a commercial VirtualBox
199767f8919635c4928607450d9e0abb932109ceToomas Soome * distribution, then only the terms of your commercial VirtualBox
199767f8919635c4928607450d9e0abb932109ceToomas Soome * license agreement apply instead of the previous paragraph.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*******************************************************************************
199767f8919635c4928607450d9e0abb932109ceToomas Soome* Header Files *
199767f8919635c4928607450d9e0abb932109ceToomas Soome*******************************************************************************/
199767f8919635c4928607450d9e0abb932109ceToomas Soome#define LOG_GROUP RTLOGGROUP_PROCESS
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <unistd.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <stdlib.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <errno.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/stat.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/wait.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <signal.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if defined(RT_OS_LINUX) || defined(RT_OS_OS2)
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define HAVE_POSIX_SPAWN 1
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef HAVE_POSIX_SPAWN
199767f8919635c4928607450d9e0abb932109ceToomas Soome# include <spawn.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef RT_OS_DARWIN
199767f8919635c4928607450d9e0abb932109ceToomas Soome# include <mach-o/dyld.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <iprt/process.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <iprt/string.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <iprt/assert.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <iprt/err.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "internal/process.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas SoomeRTR3DECL(int) RTProcCreate(const char *pszExec, const char * const *papszArgs, const char * const *papszEnv, unsigned fFlags, PRTPROCESS pProcess)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Validate input.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!pszExec || !*pszExec)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome AssertMsgFailed(("no exec\n"));
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VERR_INVALID_PARAMETER;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (fFlags)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome AssertMsgFailed(("invalid flags!\n"));
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VERR_INVALID_PARAMETER;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* later: path searching. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Check for execute access to the file.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (access(pszExec, X_OK))
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome int rc = RTErrConvertFromErrno(errno);
199767f8919635c4928607450d9e0abb932109ceToomas Soome AssertMsgFailed(("'%s' %Vrc!\n", pszExec, rc));
199767f8919635c4928607450d9e0abb932109ceToomas Soome return rc;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if 0
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Squeeze gdb --args in front of what's being spawned.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome unsigned cArgs = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (papszArgs[cArgs])
199767f8919635c4928607450d9e0abb932109ceToomas Soome cArgs++;
199767f8919635c4928607450d9e0abb932109ceToomas Soome cArgs += 3;
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char **papszArgsTmp = (const char **)alloca(cArgs * sizeof(char *));
199767f8919635c4928607450d9e0abb932109ceToomas Soome papszArgsTmp[0] = "/usr/bin/gdb";
199767f8919635c4928607450d9e0abb932109ceToomas Soome papszArgsTmp[1] = "--args";
199767f8919635c4928607450d9e0abb932109ceToomas Soome papszArgsTmp[2] = pszExec;
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (unsigned i = 1; papszArgs[i]; i++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome papszArgsTmp[i + 2] = papszArgs[i];
199767f8919635c4928607450d9e0abb932109ceToomas Soome papszArgsTmp[cArgs - 1] = NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome pszExec = papszArgsTmp[0];
199767f8919635c4928607450d9e0abb932109ceToomas Soome papszArgs = papszArgsTmp;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Spawn the child.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome pid_t pid;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef HAVE_POSIX_SPAWN
199767f8919635c4928607450d9e0abb932109ceToomas Soome /** @todo check if it requires any of those two attributes, don't remember atm. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome int rc = posix_spawn(&pid, pszExec, NULL, NULL, (char * const *)papszArgs,
199767f8919635c4928607450d9e0abb932109ceToomas Soome papszEnv ? (char * const *)papszEnv : environ);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!rc)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (pProcess)
199767f8919635c4928607450d9e0abb932109ceToomas Soome *pProcess = pid;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VINF_SUCCESS;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome pid = fork();
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!pid)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome int rc;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (papszEnv)
199767f8919635c4928607450d9e0abb932109ceToomas Soome rc = execve(pszExec, (char * const *)papszArgs, (char * const *)papszEnv);
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome rc = execv(pszExec, (char * const *)papszArgs);
199767f8919635c4928607450d9e0abb932109ceToomas Soome AssertReleaseMsgFailed(("execve returns %d errno=%d\n", rc, errno));
199767f8919635c4928607450d9e0abb932109ceToomas Soome exit(127);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (pid > 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (pProcess)
199767f8919635c4928607450d9e0abb932109ceToomas Soome *pProcess = pid;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VINF_SUCCESS;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome int rc = errno;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* failure, errno value in rc. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome AssertMsgFailed(("spawn/exec failed rc=%d\n", rc)); /* this migth be annoying... */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return RTErrConvertFromErrno(rc);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas SoomeRTR3DECL(int) RTProcWait(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int rc;
199767f8919635c4928607450d9e0abb932109ceToomas Soome do rc = RTProcWaitNoResume(Process, fFlags, pProcStatus);
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (rc == VERR_INTERRUPTED);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return rc;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas SoomeRTR3DECL(int) RTProcWaitNoResume(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Validate input.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (Process <= 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome AssertMsgFailed(("Invalid Process=%d\n", Process));
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VERR_INVALID_PARAMETER;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (fFlags & ~(RTPROCWAIT_FLAGS_NOBLOCK | RTPROCWAIT_FLAGS_BLOCK))
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome AssertMsgFailed(("Invalid flags %#x\n", fFlags));
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VERR_INVALID_PARAMETER;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Performe the wait.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome int iStatus = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome int rc = waitpid(Process, &iStatus, fFlags & RTPROCWAIT_FLAGS_NOBLOCK ? WNOHANG : 0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (rc > 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Fill in the status structure.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (pProcStatus)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (WIFEXITED(iStatus))
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome pProcStatus->enmReason = RTPROCEXITREASON_NORMAL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome pProcStatus->iStatus = WEXITSTATUS(iStatus);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome else if (WIFSIGNALED(iStatus))
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome pProcStatus->enmReason = RTPROCEXITREASON_SIGNAL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome pProcStatus->iStatus = WTERMSIG(iStatus);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome Assert(!WIFSTOPPED(iStatus));
199767f8919635c4928607450d9e0abb932109ceToomas Soome pProcStatus->enmReason = RTPROCEXITREASON_ABEND;
199767f8919635c4928607450d9e0abb932109ceToomas Soome pProcStatus->iStatus = iStatus;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VINF_SUCCESS;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Child running?
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!rc)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome Assert(fFlags & RTPROCWAIT_FLAGS_NOBLOCK);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VERR_PROCESS_RUNNING;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Figure out which error to return.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome int iErr = errno;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (iErr == ECHILD)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VERR_PROCESS_NOT_FOUND;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return RTErrConvertFromErrno(iErr);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas SoomeRTR3DECL(int) RTProcTerminate(RTPROCESS Process)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!kill(Process, SIGKILL))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return VINF_SUCCESS;
199767f8919635c4928607450d9e0abb932109ceToomas Soome return RTErrConvertFromErrno(errno);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas SoomeRTR3DECL(uint64_t) RTProcGetAffinityMask()
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome // @todo
199767f8919635c4928607450d9e0abb932109ceToomas Soome return 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas SoomeRTR3DECL(char *) RTProcGetExecutableName(char *pszExecName, size_t cchExecName)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * I don't think there is a posix API for this, but
199767f8919635c4928607450d9e0abb932109ceToomas Soome * because I'm lazy I'm not creating OS specific code
199767f8919635c4928607450d9e0abb932109ceToomas Soome * files and code for this.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(RT_OS_SOLARIS)
199767f8919635c4928607450d9e0abb932109ceToomas Soome# ifdef RT_OS_LINUX
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cchLink = readlink("/proc/self/exe", pszExecName, cchExecName - 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome# elif defined(RT_OS_SOLARIS)
199767f8919635c4928607450d9e0abb932109ceToomas Soome char szFileBuf[80];
199767f8919635c4928607450d9e0abb932109ceToomas Soome RTStrPrintf(szFileBuf, sizeof(szFileBuf), "/proc/%ld/path/a.out", (long)getpid());
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cchLink = readlink(szFileBuf, pszExecName, cchExecName - 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome# else
199767f8919635c4928607450d9e0abb932109ceToomas Soome int cchLink = readlink("/proc/curproc/file", pszExecName, cchExecName - 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome# endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (cchLink > 0 && (size_t)cchLink <= cchExecName - 1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome pszExecName[cchLink] = '\0';
199767f8919635c4928607450d9e0abb932109ceToomas Soome return pszExecName;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#elif defined(RT_OS_OS2) || defined(RT_OS_L4)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (!_execname(pszExecName, cchExecName))
199767f8919635c4928607450d9e0abb932109ceToomas Soome return pszExecName;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#elif defined(RT_OS_DARWIN)
199767f8919635c4928607450d9e0abb932109ceToomas Soome const char *pszImageName = _dyld_get_image_name(0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (pszImageName)
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome size_t cchImageName = strlen(pszImageName);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (cchImageName < cchExecName)
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (char *)memcpy(pszExecName, pszImageName, cchImageName + 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#else
199767f8919635c4928607450d9e0abb932109ceToomas Soome# error "Port me!"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome return NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome