home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
gnat-2.06-src.tgz
/
tar.out
/
fsf
/
gnat
/
ada
/
a-adaint.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
11KB
|
443 lines
/****************************************************************************/
/* */
/* GNAT COMPILER COMPONENTS */
/* */
/* A - A D A I N T */
/* */
/* $Revision: 1.52 $ */
/* */
/* C Implementation File */
/* */
/* Copyright (c) 1992,1993,1994,1995 NYU, All Rights Reserved */
/* */
/* The GNAT library is free software; you can redistribute it and/or modify */
/* it under terms of the GNU Library General Public License as published by */
/* the Free Software Foundation; either version 2, or (at your option) any */
/* later version. The GNAT library 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 */
/* Library General Public License for more details. You should have */
/* received a copy of the GNU Library General Public License along with */
/* the GNAT library; see the file COPYING.LIB. If not, write to the Free */
/* Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/****************************************************************************/
/* This file contains those routines named by Import pragmas in package */
/* GNAT.OS_Lib. Many of the subprograms in OS_Lib import standard library */
/* calls directly. This file contains all other routines. */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include "config.h" /* this may define MSDOS */
#if defined (__EMX__) || defined (MSDOS) || defined (WINNT)
#include <process.h>
#include <string.h>
#endif
#include "a-adaint.h"
/* Define symbols O_BINARY and O_TEXT as harmless zeroes if they are not
defined in the current system. On DOS-like systems these flags control
whether the file is opened/created in text-translation mode (CR/LF in
external file mapped to LF in internal file), but in Unix-like systems,
no text translation is required, so these flags have no effect.
*/
#if defined (__EMX__)
#include <os2.h>
#endif
#if defined (MSDOS)
#include <dos.h>
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef O_TEXT
#define O_TEXT 0
#endif
extern char *getenv ();
#if __amigaos__
#define fork vfork /* AmigaOS doesn't have a true fork() */
#endif
void
to_gm_time (p_time, p_year, p_month, p_day, p_hours, p_mins, p_secs)
time_t *p_time;
int *p_year, *p_month, *p_day, *p_hours, *p_mins, *p_secs;
{
struct tm *res = gmtime (p_time);
*p_year = res->tm_year;
*p_month = res->tm_mon;
*p_day = res->tm_mday;
*p_hours = res->tm_hour;
*p_mins = res->tm_min;
*p_secs = res->tm_sec;
}
/* Return the maximum file name length. */
int
Get_Maximum_File_Name_Length ()
{
#ifdef MSDOS
return 8;
#else
return -1;
#endif
}
/* Return the default switch character. */
char
Get_Switch_Character ()
{
/* Under MSDOS, the switch character is not normally a hyphen, but this is
the convention DJGPP uses. Similarly under OS2, the switch character is
not normally a hypen, but this is the convention EMX uses.
*/
return '-';
}
/* Return nonzero if file names are case sensitive. */
int
Get_File_Names_Case_Sensitive ()
{
#if defined (__EMX__) || defined (MSDOS)
return 0;
#else
return 1;
#endif
}
char
Get_Default_Identifier_Character_Set ()
{
#if defined (__EMX__) || defined (MSDOS)
return 'p';
#else
return '1';
#endif
}
#if defined(__EMX__) || defined (MSDOS)
char dirsep_char = '\\';
#else
char dirsep_char = '/';
#endif
#if defined(__EMX__) || defined (MSDOS) || defined (WINNT)
char pathsep_char = ';';
#else
char pathsep_char = ':';
#endif
/* Return the suffix for object files; the argument, str, is assumed to point
to an array of at least 4 characters. */
void
Get_Object_Suffix (str)
char *str;
{
/* Under MSDOS, the suffix for object files is not normally .o, but this is
the convention DJGPP uses. Similarly under OS/2, the suffix for object
files is not normally .o, but this is the convention EMX uses. */
strcpy (str, "o");
}
int
open_read (path, fmode)
char *path;
int fmode;
{
int fd;
if (fmode)
fd = open (path, O_RDONLY | O_TEXT);
else
fd = open (path, O_RDONLY | O_BINARY);
return fd < 0 ? -1 : fd;
}
#if defined (__EMX__)
#define PERM (S_IREAD | S_IWRITE)
#else
#define PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
#endif
int
open_create (path, fmode)
char *path;
int fmode;
{
int fd;
if (fmode)
fd = open (path, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, PERM);
else
fd = open (path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, PERM);
return fd < 0 ? -1 : fd;
}
/* Open a new file. Return error (-1) if the file already exists. */
int
open_new (path, fmode)
char *path;
int fmode;
{
int fd;
if (fmode)
fd = open (path, O_WRONLY | O_CREAT | O_EXCL | O_TEXT,
S_IWRITE | S_IREAD);
else
fd = open (path, O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
S_IWRITE | S_IREAD);
return fd < 0 ? -1 : fd;
}
/* Return the number of bytes in the specified file. */
long
file_length (fd)
int fd;
{
int ret;
struct stat statbuf;
ret = fstat (fd, &statbuf);
if (ret || !S_ISREG (statbuf.st_mode))
return 0;
return (statbuf.st_size);
}
/* Return a GNAT time stamp given a file name. */
time_t
file_time_name (name)
char *name;
{
struct stat statbuf;
char buf[13];
#if defined (__EMX__) || defined (MSDOS)
int fd = open (name, O_RDONLY | O_BINARY);
time_t ret = file_time_fd (fd);
close (fd);
return ret;
#else
int ret = stat (name, &statbuf);
return statbuf.st_mtime;
#endif
}
/* Return a GNAT time stamp given a file descriptor. */
time_t
file_time_fd (fd)
int fd;
{
/* The following workaround code is due to the fact that under EMX and DJGPP
fstat attempts to convert time values to GMT rather than keep the actual
OS timestamp of the file. By using the OS2/DOS functions directly the GNAT
timestamp are independent of this behavior, which is desired to facilitate
the distribution of GNAT compiled libraries. */
#if defined (__EMX__) || defined (MSDOS)
#ifdef __EMX__
FILESTATUS fs;
int ret = DosQueryFileInfo (fd, 1, (unsigned char *) &fs,
sizeof (FILESTATUS));
unsigned file_year = fs.fdateLastWrite.year;
unsigned file_month = fs.fdateLastWrite.month;
unsigned file_day = fs.fdateLastWrite.day;
unsigned file_hour = fs.ftimeLastWrite.hours;
unsigned file_min = fs.ftimeLastWrite.minutes;
unsigned file_tsec = fs.ftimeLastWrite.twosecs;
#else
struct ftime fs;
int ret = getftime (fd, &fs);
unsigned file_year = fs.ft_year;
unsigned file_month = fs.ft_month;
unsigned file_day = fs.ft_day;
unsigned file_hour = fs.ft_hour;
unsigned file_min = fs.ft_min;
unsigned file_tsec = fs.ft_tsec;
#endif
/* Calculate the seconds since epoch from the time components. First count
the whole days passed. The value for years returned by the DOS and OS2
functions count years from 1980, so to compensate for the UNIX epoch which
begins in 1970 start with 10 years worth of days and add days for each
four year period since then. */
time_t tot_secs;
int cum_days [12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
int days_passed = 3652 + (file_year / 4) * 1461;
int years_since_leap = file_year % 4;
if (years_since_leap == 1) days_passed += 366;
else if (years_since_leap == 2) days_passed += 731;
else if (years_since_leap == 3) days_passed += 1096;
if (file_year > 20) days_passed -= 1;
days_passed += cum_days [file_month - 1];
if (years_since_leap == 0 && file_year != 20
&& file_month > 2) days_passed++;
days_passed += file_day - 1;
/* OK - have whole days. Multiply -- then add in other parts. */
tot_secs = days_passed * 86400;
tot_secs += file_hour * 3600;
tot_secs += file_min * 60;
tot_secs += file_tsec * 2;
return tot_secs;
#else
struct stat statbuf;
char buf[13];
int ret = fstat (fd, &statbuf);
return statbuf.st_mtime;
#endif
}
void
get_env_value_ptr (name, len, value)
char *name;
int *len;
char **value;
{
*value = getenv (name);
if (!*value)
*len = 0;
else
*len = strlen (*value);
return;
}
int
is_regular_file (name)
char *name;
{
int ret;
struct stat statbuf;
ret = stat (name, &statbuf);
return (!ret && S_ISREG (statbuf.st_mode));
}
int
is_directory (name)
char *name;
{
int ret;
struct stat statbuf;
ret = stat (name, &statbuf);
return (!ret && S_ISDIR (statbuf.st_mode));
}
int
portable_spawn (args)
char *args[];
{
int status;
int finished;
int pid;
#if defined (__EMX__) || defined (MSDOS) || defined (WINNT)
if (spawnvp (P_WAIT, args [0], args) != 0)
return (4);
#else
pid = fork ();
if (pid == -1)
return (4);
if (pid == 0) {
/* The child */
execv (args [0], args);
return (4);
}
/* The parent */
finished = wait (&status);
if (finished != pid || status & 0xffff)
return 4;
#endif
return 0;
}
char *
locate_exec (exec_name, path_val)
char *exec_name;
char *path_val;
{
char buf [1000];
char *ptr;
/* Handle absolute pathnames (DJGPP and EMX could have either '/' or '\') */
if ((exec_name [0] == '/' || exec_name [0] == dirsep_char)
#if defined(__EMX__) || defined(MSDOS) || defined(WINNT)
|| isalpha (exec_name [0]) && exec_name [1] == ':'
#endif
) {
strncpy (buf, exec_name, sizeof buf);
buf[sizeof buf - 1] = '\0';
#if defined(__EMX__) || defined(MSDOS) || defined(WINNT)
ptr = strstr (buf, ".exe");
if (ptr == NULL || strlen (ptr) != 4)
strcat (buf, ".exe");
#endif
if (is_regular_file (buf))
return xstrdup (buf);
else
return (char *)0;
}
if (! path_val) return (char *) 0;
for (;;) {
for (; *path_val == pathsep_char ; path_val++)
;
if (! *path_val) return (char *) 0;
for (ptr = buf; *path_val && *path_val != pathsep_char; )
*ptr++ = *path_val++;
ptr--;
if (*ptr != '/' && *ptr != dirsep_char) /* DJGPP could have either */
*++ptr = dirsep_char;
strcpy (++ptr, exec_name);
#if defined(__EMX__) || defined(MSDOS) || defined(WINNT)
ptr = strstr (buf, ".exe");
if (ptr == NULL || strlen (ptr) != 4)
strcat (buf, ".exe");
#endif
if (is_regular_file (buf))
return xstrdup (buf);
}
return (char *) 0;
}