(root)/
make-4.4/
src/
w32/
compat/
posixfcn.c
       1  /* Replacements for Posix functions and Posix functionality for MS-Windows.
       2  
       3  Copyright (C) 2013-2022 Free Software Foundation, Inc.
       4  This file is part of GNU Make.
       5  
       6  GNU Make is free software; you can redistribute it and/or modify it under the
       7  terms of the GNU General Public License as published by the Free Software
       8  Foundation; either version 3 of the License, or (at your option) any later
       9  version.
      10  
      11  GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
      12  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      13  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      14  
      15  You should have received a copy of the GNU General Public License along with
      16  this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  #include "makeint.h"
      19  
      20  #include <string.h>
      21  #include <io.h>
      22  #include <stdarg.h>
      23  #include <errno.h>
      24  #include <windows.h>
      25  
      26  #include "dlfcn.h"
      27  
      28  #include "job.h"
      29  
      30  #if MAKE_LOAD
      31  
      32  /* Support for dynamic loading of objects.  */
      33  
      34  static DWORD last_err;
      35  
      36  void *
      37  dlopen (const char *file, int mode)
      38  {
      39    char dllfn[MAX_PATH], *p;
      40    HANDLE dllhandle;
      41  
      42    if ((mode & ~(RTLD_LAZY | RTLD_NOW | RTLD_GLOBAL)) != 0)
      43      {
      44        errno = EINVAL;
      45        last_err = ERROR_INVALID_PARAMETER;
      46        return NULL;
      47      }
      48  
      49    if (!file)
      50      dllhandle = GetModuleHandle (NULL);
      51    else
      52      {
      53        /* MSDN says to be sure to use backslashes in the DLL file name.  */
      54        strcpy (dllfn, file);
      55        for (p = dllfn; *p; p++)
      56          if (*p == '/')
      57            *p = '\\';
      58  
      59        dllhandle = LoadLibrary (dllfn);
      60      }
      61    if (!dllhandle)
      62      last_err = GetLastError ();
      63  
      64    return dllhandle;
      65  }
      66  
      67  char *
      68  dlerror (void)
      69  {
      70    static char errbuf[1024];
      71    DWORD ret;
      72  
      73    if (!last_err)
      74      return NULL;
      75  
      76    ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
      77                         | FORMAT_MESSAGE_IGNORE_INSERTS,
      78                         NULL, last_err, 0, errbuf, sizeof (errbuf), NULL);
      79    while (ret > 0 && (errbuf[ret - 1] == '\n' || errbuf[ret - 1] == '\r'))
      80      --ret;
      81  
      82    errbuf[ret] = '\0';
      83    if (!ret)
      84      sprintf (errbuf, "Error code %lu", last_err);
      85  
      86    last_err = 0;
      87    return errbuf;
      88  }
      89  
      90  void *
      91  dlsym (void *handle, const char *name)
      92  {
      93    FARPROC addr = NULL;
      94  
      95    if (!handle || handle == INVALID_HANDLE_VALUE)
      96      {
      97        last_err = ERROR_INVALID_PARAMETER;
      98        return NULL;
      99      }
     100  
     101    addr = GetProcAddress (handle, name);
     102    if (!addr)
     103      last_err = GetLastError ();
     104  
     105    return (void *)addr;
     106  }
     107  
     108  int
     109  dlclose (void *handle)
     110  {
     111    if (!handle || handle == INVALID_HANDLE_VALUE)
     112      return -1;
     113    if (!FreeLibrary (handle))
     114      return -1;
     115  
     116    return 0;
     117  }
     118  
     119  
     120  #endif  /* MAKE_LOAD */
     121  
     122  
     123  /* MS runtime's isatty returns non-zero for any character device,
     124     including the null device, which is not what we want.  */
     125  int
     126  isatty (int fd)
     127  {
     128    HANDLE fh = (HANDLE) _get_osfhandle (fd);
     129    DWORD con_mode;
     130  
     131    if (fh == INVALID_HANDLE_VALUE)
     132      {
     133        errno = EBADF;
     134        return 0;
     135      }
     136    if (GetConsoleMode (fh, &con_mode))
     137      return 1;
     138  
     139    errno = ENOTTY;
     140    return 0;
     141  }
     142  
     143  char *
     144  ttyname (int fd)
     145  {
     146    /* This "knows" that Make only asks about stdout and stderr.  A more
     147       sophisticated implementation should test whether FD is open for
     148       input or output.  We can do that by looking at the mode returned
     149       by GetConsoleMode.  */
     150    return "CONOUT$";
     151  }