Commit c4ea52a6 authored by Richard M. Stallman's avatar Richard M. Stallman
Browse files

[macintosh] (stat, fstat, mkdir, rmdir, utime, access)

(open, creat, unlink, read, write, rename, fopen, pause, alarm)
(signal, sleep, gmtime, localtime, ctime, time, index, mktemp)
(getpwuid, getpwnam, dup, dup2, isatty, getgid, getegid, getuid)
(geteuid, getpid, getenv, uname, opendir, closedir, readdir, getwd.):
New functions, replacing POSIX features.

[macintosh] (Mac2UnixPathname, Unix2MacPathname, CheckAlarm)
(InitMyPasswd, GetTempDirName, mystrchr, mystrtok, mystrcpy):
(InitEmacsPasswdDir, run_mac_command): New subroutines.

[macintosh] (targetTicks, alarm_signal_func, myPasswdName)
(myPasswd, emacsPasswdDir, emacsPasswd, myPasswdInited, mask)
(myPasswdDir, TempDirName, sys_siglist): New variables.

[macintosh] (execvp, wait, croak, fork, kill, sigsetmask)
(sigblock, request_sigio, unrequest_sigio, setpgrp, pipe, symlink)
(link, lstat, readlink, umask, chmod, sbrk, fsync, ioctl):
Define empty stubs so Emacs will link.
parent 162100b5
......@@ -30,6 +30,24 @@ Boston, MA 02111-1307, USA. */
#include "blockinput.h"
#undef NULL
#ifdef macintosh
#ifdef __MRC__
__sigfun sys_signal (int signal, __sigfun signal_func);
#elif __MWERKS__
__signal_func_ptr sys_signal (int signal, __signal_func_ptr signal_func);
#else
You lose!!!
#endif
#ifndef subprocesses
/* Nonzero means delete a process right away if it exits (process.c). */
static int delete_exited_processes;
#endif
#ifndef HAVE_X_WINDOWS
/* Search path for bitmap files (xfns.c). */
Lisp_Object Vx_bitmap_file_path;
#endif
#endif /* macintosh */
#define min(x,y) ((x) > (y) ? (y) : (x))
/* In this file, open, read and write refer to the system calls,
......@@ -152,7 +170,7 @@ extern int errno;
#undef TIOCSWINSZ
#endif
#if defined(USG) || defined(DGUX)
#if defined (USG) || defined (DGUX)
#include <sys/utsname.h>
#include <string.h>
#ifndef MEMORY_IN_STRING_H
......@@ -709,7 +727,7 @@ sys_suspend ()
}
return -1;
#else
#if defined(SIGTSTP) && !defined(MSDOS)
#if defined (SIGTSTP) && !defined (MSDOS)
{
int pgrp = EMACS_GETPGRP (0);
......@@ -738,6 +756,9 @@ sys_suspend ()
void
sys_subshell ()
{
#ifdef macintosh
error ("Can't spawn subshell");
#else
#ifndef VMS
#ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
int st;
......@@ -854,6 +875,7 @@ sys_subshell ()
restore_signal_handlers (saved_handlers);
synch_process_alive = 0;
#endif /* !VMS */
#endif /* !macintosh */
}
static void
......@@ -971,11 +993,11 @@ request_sigio ()
if (read_socket_hook)
return;
sigemptyset(&st);
sigaddset(&st, SIGIO);
sigemptyset (&st);
sigaddset (&st, SIGIO);
ioctl (input_fd, FIOASYNC, &on);
interrupts_deferred = 0;
sigprocmask(SIG_UNBLOCK, &st, (sigset_t *)0);
sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
}
void
......@@ -1139,7 +1161,7 @@ emacs_set_tty (fd, settings, flushp)
int i;
/* We have those nifty POSIX tcmumbleattr functions.
William J. Smith <wjs@wiis.wang.com> writes:
"POSIX 1003.1 defines tcsetattr() to return success if it was
"POSIX 1003.1 defines tcsetattr to return success if it was
able to perform any of the requested actions, even if some
of the requested actions could not be performed.
We must read settings back to ensure tty setup properly.
......@@ -1168,7 +1190,7 @@ emacs_set_tty (fd, settings, flushp)
&& new.c_oflag == settings->main.c_oflag
&& new.c_cflag == settings->main.c_cflag
&& new.c_lflag == settings->main.c_lflag
&& memcmp(new.c_cc, settings->main.c_cc, NCCS) == 0)
&& memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
break;
else
continue;
......@@ -1264,6 +1286,26 @@ init_sys_modes ()
{
struct emacs_tty tty;
#ifdef macintosh
Vwindow_system = intern ("mac");
Vwindow_system_version = make_number (1);
/* cus-start.el complains if delete-exited-processes and x-bitmap-file-path not defined */
#ifndef subprocesses
DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
"*Non-nil means delete processes immediately when they exit.\n\
nil means don't delete them until `list-processes' is run.");
delete_exited_processes = 0;
#endif
#ifndef HAVE_X_WINDOWS
DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
"List of directories to search for bitmap files for X.");
Vx_bitmap_file_path = decode_env_path ((char *) 0, ".");
#endif
#endif /* not macintosh */
#ifdef VMS
#if 0
static int oob_chars[2] = {0, 1 << 7}; /* catch C-g's */
......@@ -2196,7 +2238,7 @@ start_of_data ()
*/
extern char **environ;
return((char *) &environ);
return ((char *) &environ);
#else
extern int data_start;
return ((char *) &data_start);
......@@ -3485,7 +3527,7 @@ char *sys_siglist[NSIG + 1] =
#include <dirent.h>
#if defined(BROKEN_CLOSEDIR) || !defined(HAVE_CLOSEDIR)
#if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
int
closedir (dirp)
......@@ -3730,7 +3772,7 @@ mkdir (dpath, dmode)
*/
status = umask (0); /* Get current umask */
status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
fd = sys_open("/dev/null", 2);
fd = sys_open ("/dev/null", 2);
if (fd >= 0)
{
dup2 (fd, 0);
......@@ -3776,7 +3818,7 @@ rmdir (dpath)
return (-1); /* Errno is set already */
case 0: /* Child process */
fd = sys_open("/dev/null", 2);
fd = sys_open ("/dev/null", 2);
if (fd >= 0)
{
dup2 (fd, 0);
......@@ -5099,7 +5141,7 @@ hft_init ()
there's no way to determine the old mapping, so in reset_sys_modes
we need to assume that the normal map had been present. Of course, this
code also doesn't help if on a terminal emulator which doesn't understand
HFT VTD's. */
HFT VTD's. */
{
struct hfbuf buf;
struct hfkeymap keymap;
......@@ -5130,7 +5172,7 @@ hft_init ()
line_ins_del_ok = char_ins_del_ok = 0;
}
/* Reset the rubout key to backspace. */
/* Reset the rubout key to backspace. */
void
hft_reset ()
......@@ -5277,3 +5319,1569 @@ bcmp (b1, b2, length) /* This could be a macro! */
}
#endif /* no bcmp */
#endif /* not BSTRING */
/* All the Macintosh stuffs go here */
#ifdef macintosh
#include <Files.h>
#include <MacTypes.h>
#include <TextUtils.h>
#include <Folders.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <pwd.h>
#include <sys/param.h>
/* Convert a Mac pathname to Unix form. A Mac full pathname is one
that does not begin with a ':' and contains at least one ':'. A Mac
full pathname causes an '/' to be prepended to the Unix pathname.
The algorithm for the rest of the pathname is as follows:
For each segment between two ':',
if it is non-null, copy as is and then add a '/' at the end,
otherwise, insert a "../" into the Unix pathname.
Returns 1 if successful; 0 if fails. */
int
Mac2UnixPathname (const char *mfn, char *ufn, int ufnbuflen)
{
const char *p, *q, *pe;
strcpy (ufn, "");
if (*mfn == '\0')
return 1;
p = strchr (mfn, ':');
if (p != 0 && p != mfn) /* full pathname */
strcat (ufn, "/");
p = mfn;
if (*p == ':')
p++;
pe = mfn + strlen (mfn);
while (p < pe)
{
q = strchr (p, ':');
if (q)
{
if (q == p)
{ /* two consecutive ':' */
if (strlen (ufn) + 3 >= ufnbuflen)
return 0;
strcat (ufn, "../");
}
else
{
if (strlen (ufn) + (q - p) + 1 >= ufnbuflen)
return 0;
strncat (ufn, p, q - p);
strcat (ufn, "/");
}
p = q + 1;
}
else
{
if (strlen (ufn) + (pe - p) >= ufnbuflen)
return 0;
strncat (ufn, p, pe - p); /* no separator for last one */
p = pe;
}
}
return 1;
}
extern char *GetTempDirName ();
/* Convert a Unix pathname to Mac form. Approximately reverse of the
above in algorithm. */
int
Unix2MacPathname (const char *ufn, char *mfn, int mfnbuflen)
{
const char *p, *q, *pe;
char expandedPathname[MAXPATHLEN+1];
strcpy (mfn, "");
if (*ufn == '\0')
return 1;
p = ufn;
/* Check for and handle volume names. Last comparison: strangely
somewhere `/.emacs' is passed. A temporary fix for now. */
if (*p == '/' && strchr (p+1, '/') == NULL && strcmp (p, "/.emacs") != 0)
{
if (strlen (p) + 1 > mfnbuflen)
return 0;
strcpy (mfn, p+1);
strcat (mfn, ":");
return 1;
}
if (strncmp (p, "~emacs/", 7) == 0)
{ /* expand to emacs dir found by InitEmacsPasswdDir */
struct passwd *pw = getpwnam ("emacs");
p += 7;
if (strlen (pw->pw_dir) + strlen (p) > MAXPATHLEN)
return 0;
strcpy (expandedPathname, pw->pw_dir);
strcat (expandedPathname, p);
p = expandedPathname;
/* Now p points to the pathname with emacs dir prefix. */
}
else if (strncmp (p, "/tmp/", 5) == 0)
{
char *t = GetTempDirName ();
p += 5;
if (strlen (t) + strlen (p) > MAXPATHLEN)
return 0;
strcpy (expandedPathname, t);
strcat (expandedPathname, p);
p = expandedPathname;
/* Now p points to the pathname with emacs dir prefix. */
}
else if (*p != '/') /* relative pathname */
strcat (mfn, ":");
if (*p == '/')
p++;
pe = p + strlen (p);
while (p < pe)
{
q = strchr (p, '/');
if (q)
{
if (q - p == 2 && *p == '.' && *(p+1) == '.')
{
if (strlen (mfn) + 1 >= mfnbuflen)
return 0;
strcat (mfn, ":");
}
else
{
if (strlen (mfn) + (q - p) + 1 >= mfnbuflen)
return 0;
strncat (mfn, p, q - p);
strcat (mfn, ":");
}
p = q + 1;
}
else
{
if (strlen (mfn) + (pe - p) >= mfnbuflen)
return 0;
strncat (mfn, p, pe - p);
p = pe;
}
}
return 1;
}
/* The following functions with "sys_" prefix are stubs to Unix
functions that have already been implemented by CW or MPW. The
calls to them in Emacs source course are #define'd to call the sys_
versions by the header files s-mac.h. In these stubs pathnames are
converted between their Unix and Mac forms. */
/* Unix Epoch is Jan 1, 1970 while Mac Epoch is Jan 1, 1904: 66 years
+ 17 leap days */
#define MAC_UNIX_EPOCH_DIFF ((365L * 66 + 17) * 24 * 60 * 60)
/* CW Epoch is Jan 1, 1900 (aaarghhhhh!); remember, 1900 is not a leap
year! */
#define CW_UNIX_EPOCH_DIFF ((365L * 70 + 17) * 24 * 60 * 60)
/* Define our own stat function for both MrC and CW. The reason for
doing this: "stat" is both the name of a struct and function name:
can't use the same trick like that for sys_open, sys_close, etc. to
redirect Emacs's calls to our own version that converts Unix style
filenames to Mac style filename because all sorts of compilation
errors will be generated if stat is #define'd to be sys_stat. */
int
stat (const char *path, struct stat *buf)
{
char MacPathname[MAXPATHLEN+1];
CInfoPBRec cipb;
if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
return -1;
c2pstr (MacPathname);
cipb.hFileInfo.ioNamePtr = MacPathname;
cipb.hFileInfo.ioVRefNum = 0;
cipb.hFileInfo.ioDirID = 0;
cipb.hFileInfo.ioFDirIndex = 0; /* set to 0 to get information about specific dir or file */
errno = PBGetCatInfo (&cipb, false);
if (errno == -43) /* -43: fnfErr defined in Errors.h */
errno = ENOENT;
if (errno != noErr)
return -1;
if (cipb.hFileInfo.ioFlAttrib & 0x10)
{ /* bit 4 = 1 for directories */
buf->st_mode = S_IFDIR | S_IREAD | S_IEXEC;
if (!(cipb.hFileInfo.ioFlAttrib & 0x1)) /* bit 1 = 1 for locked files/directories */
buf->st_mode |= S_IWRITE;
buf->st_ino = cipb.dirInfo.ioDrDirID;
buf->st_dev = cipb.dirInfo.ioVRefNum;
buf->st_size = cipb.dirInfo.ioDrNmFls; /* size of dir = number of files and dirs */
buf->st_atime = buf->st_mtime = cipb.dirInfo.ioDrMdDat - MAC_UNIX_EPOCH_DIFF;
buf->st_ctime = cipb.dirInfo.ioDrCrDat - MAC_UNIX_EPOCH_DIFF;
}
else
{
buf->st_mode = S_IFREG | S_IREAD;
if (!(cipb.hFileInfo.ioFlAttrib & 0x1)) /* bit 1 = 1 for locked files/directories */
buf->st_mode |= S_IWRITE;
if (cipb.hFileInfo.ioFlFndrInfo.fdType == 'APPL')
buf->st_mode |= S_IEXEC;
buf->st_ino = cipb.hFileInfo.ioDirID;
buf->st_dev = cipb.hFileInfo.ioVRefNum;
buf->st_size = cipb.hFileInfo.ioFlLgLen;
buf->st_atime = buf->st_mtime = cipb.hFileInfo.ioFlMdDat - MAC_UNIX_EPOCH_DIFF;
buf->st_ctime = cipb.hFileInfo.ioFlCrDat - MAC_UNIX_EPOCH_DIFF;
}
buf->st_nlink = 1;
buf->st_uid = getuid ();
buf->st_gid = getgid ();
buf->st_rdev = 0;
return 0;
}
#if __MRC__
/* CW defines fstat in stat.mac.c while MPW does not provide this
function. Without the information of how to get from a file
descriptor in MPW StdCLib to a Mac OS file spec, it should be hard
to implement this function. Fortunately, there is only one place
where this function is called in our configuration: in fileio.c,
where only the st_dev and st_ino fields are used to determine
whether two fildes point to different i-nodes to prevent copying
a file onto itself equal. What we have here probably needs
improvement. */
int
fstat (int fildes, struct stat *buf)
{
buf->st_dev = 0;
buf->st_ino = fildes;
return 0; /* success */
}
#endif /* __MRC__ */
/* From Think Reference code example */
int
mkdir (const char *dirname, int mode)
{
#pragma unused (mode)
HFileParam hfpb;
char MacPathname[MAXPATHLEN+1];
if (Unix2MacPathname (dirname, MacPathname, MAXPATHLEN+1) == 0)
return -1;
c2pstr (MacPathname);
hfpb.ioNamePtr = MacPathname;
hfpb.ioVRefNum = 0; /*ignored unless name is invalid */
hfpb.ioDirID = 0; /*parent is the root */
/* Just return the Mac OSErr code for now. */
errno = PBDirCreate ((HParmBlkPtr) &hfpb, false);
return errno == noErr ? 0 : -1;
}
int
rmdir (const char *dirname)
{
HFileParam hfpb;
char MacPathname[MAXPATHLEN+1];
if (Unix2MacPathname (dirname, MacPathname, MAXPATHLEN+1) == 0)
return -1;
c2pstr (MacPathname);
hfpb.ioNamePtr = MacPathname;
hfpb.ioVRefNum = 0; /*ignored unless name is invalid */
hfpb.ioDirID = 0; /*parent is the root */
errno = PBHDelete ((HParmBlkPtr) &hfpb, false);
return errno == noErr ? 0 : -1;
}
#ifdef __MRC__
/* No implementation yet. */
int
execvp (const char *path, ...)
{
return -1;
}
#endif /* __MRC__ */
int
utime (const char *path, const struct utimbuf *times)
{
char MacPathname[MAXPATHLEN+1];
CInfoPBRec cipb;
if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
return -1;
c2pstr (MacPathname);
cipb.hFileInfo.ioNamePtr = MacPathname;
cipb.hFileInfo.ioVRefNum = 0;
cipb.hFileInfo.ioDirID = 0;
/* Set to 0 to get information about specific dir or file. */
cipb.hFileInfo.ioFDirIndex = 0;
errno = PBGetCatInfo (&cipb, false);
if (errno != noErr)
return -1;
if (cipb.hFileInfo.ioFlAttrib & 0x10)
{ /* bit 4 = 1 for directories */
if (times)
cipb.dirInfo.ioDrMdDat = times->modtime + MAC_UNIX_EPOCH_DIFF;
else
GetDateTime (&cipb.dirInfo.ioDrMdDat);
}
else
{
if (times)
cipb.hFileInfo.ioFlMdDat = times->modtime + MAC_UNIX_EPOCH_DIFF;
else
GetDateTime (&cipb.hFileInfo.ioFlMdDat);
}
errno = PBSetCatInfo (&cipb, false);
return errno == noErr ? 0 : -1;
}
#define F_OK 0
#define X_OK 1
#define W_OK 2
/* Like stat, but test for access mode in hfpb.ioFlAttrib. */
int
access (const char *path, int mode)
{
char MacPathname[MAXPATHLEN+1];
CInfoPBRec cipb;
if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
return -1;
c2pstr (MacPathname);
cipb.hFileInfo.ioNamePtr = MacPathname;
cipb.hFileInfo.ioVRefNum = 0;
cipb.hFileInfo.ioDirID = 0;
cipb.hFileInfo.ioFDirIndex = 0; /* set to 0 to get information about specific dir or file */
errno = PBGetCatInfo (&cipb, false);
if (errno != noErr)
return -1;
if (mode == F_OK) /* got this far, file exists */
return 0;
if (mode & X_OK)
if (cipb.hFileInfo.ioFlAttrib & 0x10) /* path refers to a directory */
return 0;
else
{
if (cipb.hFileInfo.ioFlFndrInfo.fdType == 'APPL')
return 0;
else
return -1;
}
if (mode & W_OK)
return (cipb.hFileInfo.ioFlAttrib & 0x1) ? -1 : 0; /* don't allow if lock bit on */
return -1;
}
#define DEV_NULL_FD 0x10000
#undef open
int
sys_open (const char *path, int oflag)
{
char MacPathname[MAXPATHLEN+1];
if (strcmp (path, "/dev/null") == 0)
return DEV_NULL_FD; /* some bogus fd to be ignored in write */
if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
return -1;
else
return open (MacPathname, oflag);
}
#undef creat
int
sys_creat (const char *path, mode_t mode)
{
char MacPathname[MAXPATHLEN+1];
if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
return -1;
else
return creat (MacPathname, mode);
}
#undef unlink
int
sys_unlink (const char *path)
{
char MacPathname[MAXPATHLEN+1];
if (Unix2MacPathname (path, MacPathname, MAXPATHLEN+1) == 0)
return -1;
else
return unlink (MacPathname);
}
#undef read
int
sys_read (int fildes, char *buf, int count)
{
if (fildes == 0)
{ /* if stdin, call (non-echoing) "getch" in console.h */
if (MacKeyPending ())
{ /* don't wait for a key if none has been pressed */
*buf = MacGetChar ();
return 1;
}
else
return 0;
}
else
return read (fildes, buf, count);
}
#undef write
int
sys_write (int fildes, char *buf, int count)
{
if (fildes == DEV_NULL_FD)
return count;
else
return write (fildes, buf, count);
}
#undef rename
int