home *** CD-ROM | disk | FTP | other *** search
- /* MPW-Unix compatibility library.
- Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
-
- This file is part of the libiberty library.
- Libiberty is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- Libiberty 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 libiberty; see the file COPYING.LIB. If
- not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
-
- /* This should only be compiled and linked under MPW. */
-
- #include "mpw.h"
-
- #include <stdlib.h>
-
- #ifndef USE_MW_HEADERS
- #include <sys/time.h>
- #include <sys/resource.h>
- #endif
-
- #include <Types.h>
- #include <Files.h>
-
- #include <Timer.h>
-
- /* Initialize to 0 at first, then set to errno_max() later. */
-
- int sys_nerr = 0;
-
- /* Debug flag for pathname hacking. Set this to one and rebuild. */
-
- int DebugPI = -1;
-
- void
- mpwify_filename(char *unixname, char *macname)
- {
- int i, j;
-
- /* (should truncate 255 chars from end of name, not beginning) */
- if (strlen (unixname) > 255)
- {
- fprintf (stderr, "Pathname \"%s\" is too long for Macs, truncating\n",
- unixname);
- }
- j = 0;
- /* If you're going to end up with one or more colons in the middle of a
- a path after an all-Unix relative path is translated, you must add a
- colon on the front, so that the first component is not thought to be
- a disk name. */
- if (unixname[0] != '/' && ! strchr (unixname, ':') && strchr (unixname, '/'))
- {
- macname[j++] = ':';
- }
- for (i = 0; unixname[i] != '\0' && i < 255; ++i)
- {
- if (i == 0 && unixname[i] == '/')
- {
- if (strncmp (unixname, "/tmp/", 5) == 0)
- {
- /* A temporary name, make a more Mac-flavored tmpname. */
- /* A better choice would be {Boot}Trash:foo, but
- that would require being able to identify the
- boot disk's and trashcan's name. Another option
- would be to have an env var, so user can point it
- at a ramdisk. */
- macname[j++] = ':';
- macname[j++] = 't';
- macname[j++] = 'm';
- macname[j++] = 'p';
- macname[j++] = '_';
- i += 4;
- }
- else
- {
- /* Don't copy the leading slash. */
- }
- }
- else if (unixname[i] == ':' && unixname[i+1] == '/')
- {
- macname[j++] = ':';
- i += 1;
- }
- else if (unixname[i] == '.' && unixname[i+1] == '/')
- {
- macname[j++] = ':';
- i += 1;
- }
- else if (unixname[i] == '.' && unixname[i+1] == '.' && unixname[i+2] == '/')
- {
- macname[j++] = ':';
- macname[j++] = ':';
- i += 2;
- }
- else if (unixname[i] == '/')
- {
- macname[j++] = ':';
- }
- else
- {
- macname[j++] = unixname[i];
- }
- }
- macname[j] = '\0';
- /* Allow for getting the debug flag from an env var; quite useful. */
- if (DebugPI < 0)
- DebugPI = (*(getenv ("DEBUG_PATHNAMES")) == '1' ? 1 : 0);
- if (DebugPI)
- {
- fprintf (stderr, "# Made \"%s\"\n", unixname);
- fprintf (stderr, "# into \"%s\"\n", macname);
- }
- }
-
- /* MPW-flavored basename finder. */
-
- char *
- mpw_basename (name)
- char *name;
- {
- char *base = name;
-
- while (*name)
- {
- if (*name++ == ':')
- {
- base = name;
- }
- }
- return base;
- }
-
- /* Mixed MPW/Unix basename finder. This can be led astray by
- filenames with slashes in them and come up with a basename that
- either corresponds to no file or (worse) to some other file, so
- should only be tried if other methods of finding a file via a
- basename have failed. */
-
- char *
- mpw_mixed_basename (name)
- char *name;
- {
- char *base = name;
-
- while (*name)
- {
- if (*name == '/' || *name == ':')
- {
- base = name + 1;
- }
- ++name;
- }
- return base;
- }
-
- /* This function is fopen() modified to create files that are type TEXT
- or 'BIN ', and always of type 'MPS '. */
-
- FILE *
- mpw_fopen (char *name, char *mode)
- {
- #undef fopen
- int errnum;
- FILE *fp;
- char tmpname[256];
-
- mpwify_filename (name, tmpname);
- PROGRESS (1);
- fp = fopen (tmpname, mode);
- errnum = errno;
-
- /* If writing, need to set type and creator usefully. */
- if (strchr (mode, 'w'))
- {
- char *pname = (char *) malloc (strlen (tmpname) + 2);
- OSErr e;
- struct FInfo fi;
-
- pname[0] = strlen (tmpname);
- strcpy (pname+1, tmpname);
-
- e = GetFInfo ((ConstStr255Param) pname, 0, &fi);
- /* should do spiffier error handling */
- if (e != 0)
- fprintf(stderr, "GetFInfo returns %d\n", e);
- if (strchr (mode, 'b'))
- {
- fi.fdType = (OSType) 'BIN ';
- }
- else
- {
- fi.fdType = (OSType) 'TEXT';
- }
- fi.fdCreator = (OSType) 'MPS ';
- e = SetFInfo ((ConstStr255Param) pname, 0, &fi);
- if (e != 0)
- fprintf(stderr, "SetFInfo returns %d\n", e);
- free (pname);
- }
- if (fp == NULL)
- errno = errnum;
- return fp;
- }
-
- /* This is a version of fseek() modified to fill the file with zeros
- if seeking past the end of it. */
-
- #define ZEROBLKSIZE 4096
-
- char zeros[ZEROBLKSIZE];
-
- int
- mpw_fseek (FILE *fp, int offset, int whence)
- {
- #undef fseek
- int cursize, numleft;
-
- PROGRESS (1);
- if (whence == SEEK_SET)
- {
- fseek (fp, 0, SEEK_END);
- cursize = ftell (fp);
- if (offset > cursize)
- {
- numleft = offset - cursize;
- while (numleft > ZEROBLKSIZE)
- {
- /* This might fail, should check for that. */
- PROGRESS (1);
- fwrite (zeros, 1, ZEROBLKSIZE, fp);
- numleft -= ZEROBLKSIZE;
- }
- PROGRESS (1);
- fwrite (zeros, 1, numleft, fp);
- fflush (fp);
- }
- }
- return fseek (fp, offset, whence);
- }
-
- int
- mpw_fread (char *ptr, int size, int nitems, FILE *stream)
- {
- #undef fread
- int rslt;
-
- PROGRESS (1);
- rslt = fread (ptr, size, nitems, stream);
- PROGRESS (1);
- return rslt;
- }
-
- int
- mpw_fwrite (char *ptr, int size, int nitems, FILE *stream)
- {
- #undef fwrite
- int rslt;
-
- PROGRESS (1);
- rslt = fwrite (ptr, size, nitems, stream);
- PROGRESS (1);
- return rslt;
- }
-
- int
- link ()
- {
- fprintf (stderr, "link not available!\n");
- mpw_abort ();
- }
-
- int
- fork ()
- {
- fprintf (stderr, "fork not available!\n");
- mpw_abort ();
- }
-
- int
- vfork ()
- {
- fprintf (stderr, "vfork not available!\n");
- mpw_abort ();
- return (-1);
- }
-
- int
- pipe (int *fd)
- {
- fprintf (stderr, "pipe not available!\n");
- mpw_abort ();
- return (-1);
- }
-
- #ifndef USE_MW_HEADERS
- int
- execvp (char *file, char **argv)
- {
- fprintf (stderr, "execvp not available!\n");
- mpw_abort ();
- return (-1);
- }
-
- int
- execv (char *path, char **argv)
- {
- fprintf (stderr, "execv not available!\n");
- mpw_abort ();
- return (-1);
- }
- #endif
-
- int
- kill (int pid, int sig)
- {
- fprintf (stderr, "kill not available!\n");
- mpw_abort ();
- return (-1);
- }
-
- int
- wait (int *status)
- {
- *status = 0;
- return 0;
- }
-
- #ifndef USE_MW_HEADERS
- int
- sleep (int seconds)
- {
- unsigned long start_time, now;
-
- time (&start_time);
-
- while (1)
- {
- PROGRESS (1);
- time (&now);
- if (now > start_time + seconds)
- return 0;
- }
- }
- #endif
-
- void
- putenv (char *str)
- {
- /* The GCC driver calls this to do things for collect2, but we
- don't care about collect2. */
- }
-
- int
- chmod (char *path, int mode)
- {
- /* Pretend it was all OK. */
- return 0;
- }
-
- #ifndef USE_MW_HEADERS
- int
- getuid ()
- {
- /* One value is as good as another... */
- return 0;
- }
-
- int
- getgid ()
- {
- /* One value is as good as another... */
- return 0;
- }
- #endif
-
- /* Instead of coredumping, which is not a normal Mac facility, we
- drop into Macsbug. If we then "g" from Macsbug, the program will
- exit cleanly. */
-
- void
- mpw_abort ()
- {
- /* Make sure no output still buffered up, then zap into MacsBug. */
- fflush(stdout);
- fflush(stderr);
- printf("## Abort! ##\n");
- #ifdef MPW_SADE
- SysError(8005);
- #else
- Debugger();
- #endif
- /* "g" in MacsBug will then cause a regular error exit. */
- exit (1);
- }
-
- /* Imitation getrusage based on the ANSI clock() function. */
-
- int
- getrusage (int who, struct rusage *rusage)
- {
- int clk = clock ();
-
- #if 0
- rusage->ru_utime.tv_sec = clk / CLOCKS_PER_SEC;
- rusage->ru_utime.tv_usec = ((clk * 1000) / CLOCKS_PER_SEC) * 1000;
- rusage->ru_stime.tv_sec = 0;
- rusage->ru_stime.tv_usec = 0;
- #endif
- }
-
- int
- sbrk ()
- {
- return 0;
- }
-
- #ifndef USE_MW_HEADERS
- int
- isatty (int fd)
- {
- return 0;
- }
-
- /* This is inherited from Timothy Murray's Posix library. */
-
- #include "utime.h"
-
- int
- utime (char *filename, struct utimbuf *times)
- {
- CInfoPBRec cipbr;
- HFileInfo *fpb = (HFileInfo *) &cipbr;
- DirInfo *dpb = (DirInfo *) &cipbr;
- unsigned char pname[256];
- short err;
-
- strcpy ((char *) pname, filename);
- c2pstr (pname);
-
- dpb->ioDrDirID = 0L;
- fpb->ioNamePtr = pname;
- fpb->ioVRefNum = 0;
- fpb->ioFDirIndex = 0;
- fpb->ioFVersNum = 0;
- err = PBGetCatInfo (&cipbr, 0);
- if (err != noErr) {
- errno = ENOENT;
- return -1;
- }
- dpb->ioDrDirID = 0L;
- fpb->ioFlMdDat = times->modtime;
- fpb->ioFlCrDat = times->actime;
- err = PBSetCatInfo (&cipbr, 0);
- if (err != noErr) {
- errno = EACCES;
- return -1;
- }
- return 0;
- }
-
- int
- mkdir (char *path, int mode)
- {
- errno = ENOSYS;
- return -1;
- }
-
- int
- rmdir ()
- {
- errno = ENOSYS;
- return -1;
- }
- #endif
-
- chown ()
- {
- errno = ENOSYS;
- return -1;
- }
-
- char *myenviron[] = {NULL};
-
- char **environ = myenviron;
-
- #ifndef USE_MW_HEADERS
-
- /* Minimal 'stat' emulation: tells directories from files and
- gives length and mtime.
-
- Derived from code written by Guido van Rossum, CWI, Amsterdam
- and placed by him in the public domain. */
-
- extern int __uid, __gid;
-
- int __uid = 0;
- int __gid = 0;
-
- /* Bits in ioFlAttrib: */
- #define LOCKBIT (1<<0) /* File locked */
- #define DIRBIT (1<<4) /* It's a directory */
-
- /* Macified "stat" in which filename is given relative to a directory,
- specified by long DirID. */
-
- static int
- _stat (char *name, long dirid, struct stat *buf)
- {
- CInfoPBRec cipbr;
- HFileInfo *fpb = (HFileInfo*) &cipbr;
- DirInfo *dpb = (DirInfo*) &cipbr;
- Str255 pname;
- short err;
-
- /* Make a temp copy of the name and pascalize. */
- strcpy ((char *) pname, name);
- c2pstr (pname);
-
- cipbr.dirInfo.ioDrDirID = dirid;
- cipbr.hFileInfo.ioNamePtr = pname;
- cipbr.hFileInfo.ioVRefNum = 0;
- cipbr.hFileInfo.ioFDirIndex = 0;
- cipbr.hFileInfo.ioFVersNum = 0;
- err = PBGetCatInfo (&cipbr, 0);
- if (err != noErr)
- {
- errno = ENOENT;
- return -1;
- }
- /* Mac files are readable if they can be accessed at all. */
- buf->st_mode = 0444;
- /* Mark unlocked files as writeable. */
- if (!(fpb->ioFlAttrib & LOCKBIT))
- buf->st_mode |= 0222;
- if (fpb->ioFlAttrib & DIRBIT)
- {
- /* Mark directories as "executable". */
- buf->st_mode |= 0111 | S_IFDIR;
- buf->st_size = dpb->ioDrNmFls;
- buf->st_rsize = 0;
- }
- else
- {
- buf->st_mode |= S_IFREG;
- /* Mark apps as "executable". */
- if (fpb->ioFlFndrInfo.fdType == 'APPL')
- buf->st_mode |= 0111;
- /* Fill in the sizes of data and resource forks. */
- buf->st_size = fpb->ioFlLgLen;
- buf->st_rsize = fpb->ioFlRLgLen;
- }
- /* Fill in various times. */
- buf->st_atime = fpb->ioFlCrDat;
- buf->st_mtime = fpb->ioFlMdDat;
- buf->st_ctime = fpb->ioFlCrDat;
- /* Set up an imitation inode number. */
- buf->st_ino = (unsigned short) fpb->ioDirID;
- /* Set up an imitation device. */
- GetVRefNum (buf->st_ino, &buf->st_dev);
- buf->st_uid = __uid;
- buf->st_gid = __gid;
- /* buf->st_FlFndrInfo = fpb->ioFlFndrInfo; */
- return 0;
- }
-
- /* stat() sets up an empty dirid. */
-
- int
- stat (char *path, struct stat *buf)
- {
- long rslt, errnum;
- char tmpname[256];
-
- mpwify_filename (path, tmpname);
- if (DebugPI)
- fprintf (stderr, "# stat (%s, %x)", tmpname, buf);
- PROGRESS (1);
- rslt = _stat (tmpname, 0L, buf);
- errnum = errno;
- if (DebugPI)
- {
- fprintf (stderr, " -> %d", rslt);
- if (rslt != 0)
- fprintf (stderr, " (errno is %d)", errnum);
- fprintf (stderr, "\n");
- fflush (stderr);
- }
- if (rslt != 0)
- errno = errnum;
- return rslt;
- }
-
- int
- fstat (int fd, struct stat *buf)
- {
- FCBPBRec fcb;
- FILE *fp;
- Str255 pathname;
- long dirid = 0L, temp;
- long rslt, errnum;
- short err;
-
- if (DebugPI < 0)
- DebugPI = (*(getenv ("DEBUG_PATHNAMES")) == '1' ? 1 : 0);
- if (DebugPI)
- fprintf (stderr, "# fstat (%d, %x)", fd, buf);
- PROGRESS (1);
- pathname[0] = 0;
- #ifdef FIOFNAME
- /* Use an MPW-specific ioctl to get the pathname associated with
- the file descriptor. */
- ioctl (fd, FIOFNAME, (long *) pathname);
- #else
- you lose
- #endif
- if (DebugPI)
- fprintf (stderr, " (name is %s)", pathname);
- dirid = 0L /* fcb.ioFCBParID */ ;
- rslt = _stat ((char *) pathname, dirid, buf);
- errnum = errno;
- if (DebugPI)
- {
- fprintf (stderr, " -> %d", rslt);
- if (rslt != 0)
- fprintf (stderr, " (errno is %d)", errnum);
- fprintf (stderr, "\n");
- fflush (stderr);
- }
- if (rslt != 0)
- errno = errnum;
- return rslt;
- }
-
- #endif /* n USE_MW_HEADERS */
-
- chdir ()
- {
- errno = ENOSYS;
- return (-1);
- }
-
- char *
- getcwd (char *buf, int size)
- {
- if (buf == NULL)
- buf = (char *) malloc (size);
- strcpy(buf, ":");
- return buf;
- }
-
- /* This should probably be more elaborate for MPW. */
-
- char *
- getpwd ()
- {
- return ":";
- }
-
- int
- mpw_open (char *filename, int arg2, int arg3)
- {
- #undef open
- int fd, errnum = 0;
- char tmpname[256];
-
- mpwify_filename (filename, tmpname);
- fd = open (tmpname, arg2);
- errnum = errno;
-
- if (DebugPI)
- {
- fprintf (stderr, "# open (%s, %d, %d)", tmpname, arg2, arg3);
- fprintf (stderr, " -> %d", fd);
- if (fd == -1)
- fprintf (stderr, " (errno is %d)", errnum);
- fprintf (stderr, "\n");
- }
- if (fd == -1)
- errno = errnum;
- return fd;
- }
-
- int
- mpw_access (char *filename, unsigned int cmd)
- {
- #undef access
-
- int rslt, errnum = 0;
- struct stat st;
- char tmpname[256];
-
- mpwify_filename (filename, tmpname);
- if (cmd & R_OK || cmd & X_OK)
- {
- rslt = stat (tmpname, &st);
- errnum = errno;
- if (rslt >= 0)
- {
- if (((st.st_mode & 004 == 0) && (cmd & R_OK))
- || ((st.st_mode & 002 == 0) && (cmd & W_OK))
- || ((st.st_mode & 001 == 0) && (cmd & X_OK)))
- {
- rslt = -1;
- errnum = EACCES;
- }
- }
- }
- if (DebugPI)
- {
- fprintf (stderr, "# mpw_access (%s, %d)", tmpname, cmd);
- fprintf (stderr, " -> %d", rslt);
- if (rslt != 0)
- fprintf (stderr, " (errno is %d)", errnum);
- fprintf (stderr, "\n");
- }
- if (rslt != 0)
- errno = errnum;
- return rslt;
- }
-
- /* The MPW library creat() has no mode argument. */
-
- int
- mpw_creat (char *path, /* mode_t */ int mode)
- {
- #undef creat
-
- #ifdef USE_MW_HEADERS
- return creat (path, mode);
- #else
- return creat (path);
- #endif
- }
-
- /* This is a hack to get control in an MPW tool before it crashes the
- machine. */
-
- mpw_special_init (name)
- char *name;
- {
- if (strstr (name, "DEBUG"))
- DebugStr("\pat beginning of program");
- }
-
- static int current_umask;
-
- int
- umask(int mask)
- {
- int oldmask = current_umask;
-
- current_umask = mask;
- return oldmask;
- }
-
- /* Cursor-spinning stuff that includes metering of spin rate and delays. */
-
- /* Nonzero when cursor spinning has been set up properly. */
-
- int cursor_inited;
-
- /* Nonzero if spin should be measured and excessive delays reported. */
-
- int measure_spin;
-
- /* Nonzero if spin histogram and rate data should be written out. */
-
- int dump_spin_data;
-
- long warning_threshold = 400000;
-
- long bucket_size = 1024;
-
- long bucket_power = 10;
-
- long numbuckets = 300;
-
- int *delay_counts;
-
- int overflow_count;
-
- char *current_progress;
-
- static UnsignedWide last_microseconds;
-
- static char *last_spin_file = "";
-
- static int last_spin_line;
-
- void
- warn_if_spin_delay (char *file, int line)
- {
- long diff, ix;
- UnsignedWide now;
-
- Microseconds(&now);
-
- diff = now.lo - last_microseconds.lo;
-
- if (diff > warning_threshold)
- fprintf (stderr, "# %s: %ld.%06ld sec delay getting from %s:%d to %s:%d\n",
- (current_progress ? current_progress : ""),
- diff / 1000000, diff % 1000000,
- last_spin_file, last_spin_line, file, line);
- if (dump_spin_data)
- {
- if (diff >= 0)
- {
- ix = diff >> bucket_power;
- if (ix >= 0 && ix < numbuckets && delay_counts != NULL)
- ++delay_counts[ix];
- else
- ++overflow_count;
- }
- else
- fprintf (stderr, "raw diff is %ld (?)\n", diff);
- }
- }
-
- void
- record_for_spin_delay (char *file, int line)
- {
- Microseconds (&last_microseconds);
- last_spin_file = file;
- last_spin_line = line;
- }
-
- void
- mpw_start_progress (char *str, int n, char *file, int line)
- {
- int i;
- char *measure, *threshold;
-
- if (!cursor_inited)
- {
- InitCursorCtl (nil);
- cursor_inited = 1;
- record_for_spin_delay (file, line);
- measure = getenv ("MEASURE_SPIN");
- if (measure != NULL && measure[0] != '\0')
- {
- measure_spin = 1;
- if (strcmp (measure, "all") == 0)
- dump_spin_data = 1;
- }
- threshold = getenv ("SPIN_WARN_THRESHOLD");
- if (threshold != NULL && threshold[0] != '\0')
- warning_threshold = atol (threshold);
- if (dump_spin_data)
- {
- if (delay_counts == NULL)
- delay_counts = (int *) malloc (numbuckets * sizeof (int));
- for (i = 0; i < numbuckets; ++i)
- delay_counts[i] = 0;
- overflow_count = 0;
- }
- }
- current_progress = str;
-
- sys_nerr = errno_max ();
-
- mpw_special_init (str);
- }
-
- void
- mpw_progress (int n)
- {
- SpinCursor (32);
- }
-
- void
- mpw_progress_measured (int n, char *file, int line)
- {
- if (measure_spin)
- warn_if_spin_delay (file, line);
- SpinCursor (32);
- if (measure_spin)
- record_for_spin_delay (file, line);
- }
-
- void
- mpw_end_progress (char *str, char *file, int line)
- {
- long i, delay, count = 0, sum = 0, avgdelay, spinrate;
- long curpower = 0, curgroup = 0;
-
- /* Warn if it's been a while since the last spin. */
- if (measure_spin)
- warn_if_spin_delay (file, line);
-
- /* Dump all the nonzero delay counts and an approximation of the delay. */
- if (dump_spin_data && delay_counts != NULL)
- {
- for (i = 0; i < numbuckets; ++i)
- {
- delay = (i + 1) * bucket_size;
- sum += delay_counts[i] * (i + 1);
- count += delay_counts[i];
- if (delay <= (1 << curpower))
- {
- curgroup += delay_counts[i];
- }
- else
- {
- if (curgroup > 0)
- fprintf (stderr,
- "# %s: %d delays between %ld.%06ld and %ld.%06ld sec\n",
- (str ? str : ""),
- curgroup,
- (1 << curpower) / 1000000,
- (1 << curpower) % 1000000,
- (1 << (curpower + 1)) / 1000000,
- (1 << (curpower + 1)) % 1000000);
- ++curpower;
- curgroup = 0;
- }
- }
- if (count > 0)
- {
- avgdelay = (sum * bucket_size) / count;
- spinrate = 1000000 / avgdelay;
- fprintf (stderr, "# %s: Average spin rate is %d times/sec\n",
- (str ? str : ""), spinrate);
- }
- }
- }
-
- #ifdef PROGRESS_TEST
-
- /* Test program. */
-
- main ()
- {
- int i, j;
- double x = 1.0, y = 2.4;
- long start = Microseconds (), tm; FIXME
-
- START_PROGRESS ("hi", 0);
-
- for (i = 0; i < 1000; ++i)
- {
- PROGRESS (1);
-
- for (j = 0; j < (i * 100); ++j)
- {
- x += (x * y) / j;
- }
- }
-
- END_PROGRESS ("hi");
-
- tm = Microseconds () - start;
-
- printf ("Total time is %d.%d secs\n", tm / 1000000, tm % 1000000);
- }
-
- #endif
-
- #ifdef USE_MW_HEADERS
- /* Empty definitions for Metrowerks' SIOUX console library. */
-
- #ifndef __CONSOLE__
- #include <console.h>
- #endif
-
- short
- InstallConsole(short fd)
- {
- #pragma unused (fd)
- return 0;
- }
-
- void
- RemoveConsole(void)
- {
- }
-
- long
- WriteCharsToConsole(char *buf, long n)
- {
- #pragma unused (buf, n)
- return 0;
- }
-
- long ReadCharsFromConsole(char *buf, long n)
- {
- #pragma unused (buf, n)
- return 0;
- }
-
- extern char *
- __ttyname(long fd)
- {
- static char *__devicename = "null device";
-
- if (fd >= 0 && fd <= 2)
- return (__devicename);
- return NULL;
- }
-
- #endif
-