summaryrefslogtreecommitdiff
path: root/src/msdos.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/msdos.c')
-rw-r--r--src/msdos.c127
1 files changed, 114 insertions, 13 deletions
diff --git a/src/msdos.c b/src/msdos.c
index 1af66b391ad..010a0a3746c 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -50,6 +50,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <unistd.h> /* for chdir, dup, dup2, etc. */
#include <dir.h> /* for getdisk */
#pragma pack(0) /* dir.h does a pack(4), which isn't GCC's default */
+#undef opendir
+#include <dirent.h> /* for opendir */
#include <fcntl.h>
#include <io.h> /* for setmode */
#include <dpmi.h> /* for __dpmi_xxx stuff */
@@ -1883,18 +1885,6 @@ dos_get_saved_screen (char **screen, int *rows, int *cols)
#endif
}
-#ifndef HAVE_X_WINDOWS
-
-/* We are not X, but we can emulate it well enough for our needs... */
-void
-check_window_system (void)
-{
- if (! FRAME_MSDOS_P (SELECTED_FRAME ()))
- error ("Not running under a window system");
-}
-
-#endif
-
/* ----------------------- Keyboard control ----------------------
*
@@ -3875,6 +3865,9 @@ int setpgid (int pid, int pgid) { return 0; }
int setpriority (int x, int y, int z) { return 0; }
pid_t setsid (void) { return 0; }
+
+/* Gnulib support and emulation. */
+
#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4
ssize_t
readlink (const char *name, char *dummy1, size_t dummy2)
@@ -3886,6 +3879,38 @@ readlink (const char *name, char *dummy1, size_t dummy2)
}
#endif
+/* dir_pathname is set by sys_opendir and used in readlinkat and in
+ fstatat, when they get a special FD of zero, which means use the
+ last directory opened by opendir. */
+static char dir_pathname[MAXPATHLEN];
+DIR *
+sys_opendir (const char *dirname)
+{
+ _fixpath (dirname, dir_pathname);
+ return opendir (dirname);
+}
+
+ssize_t
+readlinkat (int fd, char const *name, char *buffer, size_t buffer_size)
+{
+ /* Rely on a hack: an open directory is modeled as file descriptor 0,
+ as in fstatat. FIXME: Add proper support for readlinkat. */
+ char fullname[MAXPATHLEN];
+
+ if (fd != AT_FDCWD)
+ {
+ if (strlen (dir_pathname) + strlen (name) + 1 >= MAXPATHLEN)
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+ sprintf (fullname, "%s/%s", dir_pathname, name);
+ name = fullname;
+ }
+
+ return readlink (name, buffer, buffer_size);
+}
+
char *
careadlinkat (int fd, char const *filename,
char *buffer, size_t buffer_size,
@@ -3913,6 +3938,82 @@ careadlinkat (int fd, char const *filename,
return buffer;
}
+/* Emulate faccessat(2). */
+int
+faccessat (int dirfd, const char * path, int mode, int flags)
+{
+ /* We silently ignore FLAGS. */
+ flags = flags;
+
+ if (dirfd != AT_FDCWD
+ && !(IS_DIRECTORY_SEP (path[0])
+ || IS_DEVICE_SEP (path[1])))
+ {
+ errno = EBADF;
+ return -1;
+ }
+
+ return access (path, mode);
+}
+
+/* Emulate fstatat. */
+int
+fstatat (int fd, char const *name, struct stat *st, int flags)
+{
+ /* Rely on a hack: an open directory is modeled as file descriptor 0.
+ This is good enough for the current usage in Emacs, but is fragile.
+
+ FIXME: Add proper support for fdopendir, fstatat, readlinkat.
+ Gnulib does this and can serve as a model. */
+ char fullname[MAXPATHLEN];
+
+ flags = flags;
+
+ if (fd != AT_FDCWD)
+ {
+ char lastc = dir_pathname[strlen (dir_pathname) - 1];
+
+ if (strlen (dir_pathname) + strlen (name) + IS_DIRECTORY_SEP (lastc)
+ >= MAXPATHLEN)
+ {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ sprintf (fullname, "%s%s%s",
+ dir_pathname, IS_DIRECTORY_SEP (lastc) ? "" : "/", name);
+ name = fullname;
+ }
+
+#if __DJGPP__ > 2 || __DJGPP_MINOR__ > 3
+ return (flags & AT_SYMLINK_NOFOLLOW) ? lstat (name, st) : stat (name, st);
+#else
+ return stat (name, st);
+#endif
+}
+
+#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4
+/* Emulate the Posix unsetenv. DJGPP v2.04 has this in the library. */
+int
+unsetenv (const char *name)
+{
+ char *var;
+ size_t name_len;
+ int retval;
+
+ if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* DJGPP's 'putenv' deletes the entry if it doesn't include '='. */
+ putenv (name);
+
+ return 0;
+}
+#endif
+
#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2
@@ -4038,7 +4139,7 @@ dos_yield_time_slice (void)
/* We don't have to call timer_check here
because wait_reading_process_output takes care of that. */
int
-sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
+sys_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
struct timespec *timeout, void *ignored)
{
int check_input;