www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/07/05/21:27:17

From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Thu, 5 Jul 2001 21:27:12 -0400
MIME-Version: 1.0
Subject: dosexec.c changes
Message-ID: <3B44DBB0.9188.1772CD@localhost>
X-mailer: Pegasus Mail for Win32 (v3.12c)
Reply-To: djgpp-workers AT delorie DOT com

Below are the changes I've made so far to dosexec.c and I'd like to see if I'm headed 
in the right direction. The code has been rearranged a bit and some of the common code 
has been split off into separate functions and the functionality of __spawnve has been 
transferred to __spawn_internal. I added a flags variable to control whether an 
extension+interpreter or a plain interpreter search is performed.

I don't care too much for the spawnvx interface. My preference would be to call  
something distinctive like __djgpp_spawn and allow more flexibility by (just 
brainstorming here...) allowing a flag to dictate the type of search, an interpreter 
hint (for example, Bash will have already discovered what interpreter is needed to 
handle an extensionless file). Comments?

/* for libc/dosexec.h */
#define SPAWN_FLAG_EXT_SEARCH    0
#define SPAWN_FLAG_INTERP_SEARCH 1

int __spawn_internal(int mode, const char *path, char *const argv[],
                     char *const envp[], unsigned long flags);

int spawnve(int mode, const char *path, char *const argv[], char *const envp[])
{
  return __spawn_internal(mode, path, argv, envp, SPAWN_FLAG_EXT_SEARCH);
}
  
int spawnvx(int mode, const char *path, char *const argv[])
{
  return __spawn_internal(mode, path, argv, environ, SPAWN_FLAG_INTERP_SEARCH);
}
  
int spawnvxe(int mode, const char *path, char *const argv[],
                  char *const envp[])
{
  return __spawn_internal(mode, path, argv, envp, SPAWN_FLAG_INTERP_SEARCH);
}
  
int __spawn_internal(int mode, const char *path, char *const argv[],
                     char *const envp[], unsigned long flags)
{
  /* This is the one that does the work! */
  union { char *const *x; char **p; } u;
  const int no_interp_found = -1;
  int i = no_interp_found;
  char **argvp;
  char **envpp;
  char rpath[FILENAME_MAX], *rp, *rd=0;
  int e = errno;
  int is_dir = 0;
  int ret_code;

  if (path == 0 || argv[0] == 0)
  {
    errno = EINVAL;
    return -1;
  }
  if (strlen(path) > FILENAME_MAX - 1)
  {
    errno = ENAMETOOLONG;
    return -1;
  }

  u.x = argv; argvp = u.p;
  u.x = envp; envpp = u.p;

  fflush(stdout); /* just in case */
  for (rp=rpath; *path; *rp++ = *path++)
  {
    if (*path == '.')
      rd = rp;
    if (*path == '\\' || *path == '/')
      rd = 0;
  }
  *rp = 0;

  /* Perform an extension search when the flag SPAWN_INTERP_SEARCH is not
     present.  If LFN is supported on the volume where rpath resides, we
     might have something like foo.bar.exe or even foo.exe.com.
     If so, look for RPATH.ext before even trying RPATH itself.
     Otherwise, try to add an extension to a file without one.  */
  if (!(flags & SPAWN_FLAG_INTERP_SEARCH))
  {
    if (_use_lfn(path) || !rd)
    {
      i = find_extension(rpath, rp);
      /* When LFN is supported and an extension search fails, the go32_exec
         interpreter will be selected instead of none.  In this case,
         set the interpreter to none so the interpreter will be selected
         from the existing extension.  */
      if ((i != no_interp_found) && rd && *rp == 0)
        i = no_interp_found;
    }
  }

  /* If no interpreter has already been detected, find one based on the
     extension in rpath.  */
  if (i == no_interp_found)
    i = find_interpreter(rpath, rd ? rd : rp);

  /* The file does not exist. Return with errno set either by find_extension
     or find_interpreter to indicate the error.  */
  if (i == no_interp_found)
    return -1;

  errno = e;
  ret_code = interpreters[i].interp(rpath, argvp, envpp);
  if (mode == P_OVERLAY)
    exit(ret_code);
  return ret_code;
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019