aboutsummaryrefslogtreecommitdiffstats
path: root/src/msdos.c
diff options
context:
space:
mode:
authorPaul Eggert2014-04-16 12:43:46 -0700
committerPaul Eggert2014-04-16 12:43:46 -0700
commit290d7ac277986bd118e594a8100b3f40e4492cb1 (patch)
treed63a3aa61cac577dd119665edaffe2def8d194e2 /src/msdos.c
parent37eccff4f72c5a36dcd4b89d417b0047aab84e50 (diff)
parentb262bde327db2cd9b2f01f2d3ed946d0b188cb9d (diff)
downloademacs-290d7ac277986bd118e594a8100b3f40e4492cb1.tar.gz
emacs-290d7ac277986bd118e594a8100b3f40e4492cb1.zip
Merge from emacs-24; up to 2014-04-16T15:28:26Z!monnier@iro.umontreal.ca
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 6b677bb2f02..21794341222 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/>. */
50#include <unistd.h> /* for chdir, dup, dup2, etc. */ 50#include <unistd.h> /* for chdir, dup, dup2, etc. */
51#include <dir.h> /* for getdisk */ 51#include <dir.h> /* for getdisk */
52#pragma pack(0) /* dir.h does a pack(4), which isn't GCC's default */ 52#pragma pack(0) /* dir.h does a pack(4), which isn't GCC's default */
53#undef opendir
54#include <dirent.h> /* for opendir */
53#include <fcntl.h> 55#include <fcntl.h>
54#include <io.h> /* for setmode */ 56#include <io.h> /* for setmode */
55#include <dpmi.h> /* for __dpmi_xxx stuff */ 57#include <dpmi.h> /* for __dpmi_xxx stuff */
@@ -1883,18 +1885,6 @@ dos_get_saved_screen (char **screen, int *rows, int *cols)
1883#endif 1885#endif
1884} 1886}
1885 1887
1886#ifndef HAVE_X_WINDOWS
1887
1888/* We are not X, but we can emulate it well enough for our needs... */
1889void
1890check_window_system (void)
1891{
1892 if (! FRAME_MSDOS_P (SELECTED_FRAME ()))
1893 error ("Not running under a window system");
1894}
1895
1896#endif
1897
1898 1888
1899/* ----------------------- Keyboard control ---------------------- 1889/* ----------------------- Keyboard control ----------------------
1900 * 1890 *
@@ -3875,6 +3865,9 @@ int setpgid (int pid, int pgid) { return 0; }
3875int setpriority (int x, int y, int z) { return 0; } 3865int setpriority (int x, int y, int z) { return 0; }
3876pid_t setsid (void) { return 0; } 3866pid_t setsid (void) { return 0; }
3877 3867
3868
3869/* Gnulib support and emulation. */
3870
3878#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4 3871#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4
3879ssize_t 3872ssize_t
3880readlink (const char *name, char *dummy1, size_t dummy2) 3873readlink (const char *name, char *dummy1, size_t dummy2)
@@ -3886,6 +3879,38 @@ readlink (const char *name, char *dummy1, size_t dummy2)
3886} 3879}
3887#endif 3880#endif
3888 3881
3882/* dir_pathname is set by sys_opendir and used in readlinkat and in
3883 fstatat, when they get a special FD of zero, which means use the
3884 last directory opened by opendir. */
3885static char dir_pathname[MAXPATHLEN];
3886DIR *
3887sys_opendir (const char *dirname)
3888{
3889 _fixpath (dirname, dir_pathname);
3890 return opendir (dirname);
3891}
3892
3893ssize_t
3894readlinkat (int fd, char const *name, char *buffer, size_t buffer_size)
3895{
3896 /* Rely on a hack: an open directory is modeled as file descriptor 0,
3897 as in fstatat. FIXME: Add proper support for readlinkat. */
3898 char fullname[MAXPATHLEN];
3899
3900 if (fd != AT_FDCWD)
3901 {
3902 if (strlen (dir_pathname) + strlen (name) + 1 >= MAXPATHLEN)
3903 {
3904 errno = ENAMETOOLONG;
3905 return -1;
3906 }
3907 sprintf (fullname, "%s/%s", dir_pathname, name);
3908 name = fullname;
3909 }
3910
3911 return readlink (name, buffer, buffer_size);
3912}
3913
3889char * 3914char *
3890careadlinkat (int fd, char const *filename, 3915careadlinkat (int fd, char const *filename,
3891 char *buffer, size_t buffer_size, 3916 char *buffer, size_t buffer_size,
@@ -3913,6 +3938,82 @@ careadlinkat (int fd, char const *filename,
3913 return buffer; 3938 return buffer;
3914} 3939}
3915 3940
3941/* Emulate faccessat(2). */
3942int
3943faccessat (int dirfd, const char * path, int mode, int flags)
3944{
3945 /* We silently ignore FLAGS. */
3946 flags = flags;
3947
3948 if (dirfd != AT_FDCWD
3949 && !(IS_DIRECTORY_SEP (path[0])
3950 || IS_DEVICE_SEP (path[1])))
3951 {
3952 errno = EBADF;
3953 return -1;
3954 }
3955
3956 return access (path, mode);
3957}
3958
3959/* Emulate fstatat. */
3960int
3961fstatat (int fd, char const *name, struct stat *st, int flags)
3962{
3963 /* Rely on a hack: an open directory is modeled as file descriptor 0.
3964 This is good enough for the current usage in Emacs, but is fragile.
3965
3966 FIXME: Add proper support for fdopendir, fstatat, readlinkat.
3967 Gnulib does this and can serve as a model. */
3968 char fullname[MAXPATHLEN];
3969
3970 flags = flags;
3971
3972 if (fd != AT_FDCWD)
3973 {
3974 char lastc = dir_pathname[strlen (dir_pathname) - 1];
3975
3976 if (strlen (dir_pathname) + strlen (name) + IS_DIRECTORY_SEP (lastc)
3977 >= MAXPATHLEN)
3978 {
3979 errno = ENAMETOOLONG;
3980 return -1;
3981 }
3982
3983 sprintf (fullname, "%s%s%s",
3984 dir_pathname, IS_DIRECTORY_SEP (lastc) ? "" : "/", name);
3985 name = fullname;
3986 }
3987
3988#if __DJGPP__ > 2 || __DJGPP_MINOR__ > 3
3989 return (flags & AT_SYMLINK_NOFOLLOW) ? lstat (name, st) : stat (name, st);
3990#else
3991 return stat (name, st);
3992#endif
3993}
3994
3995#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 4
3996/* Emulate the Posix unsetenv. DJGPP v2.04 has this in the library. */
3997int
3998unsetenv (const char *name)
3999{
4000 char *var;
4001 size_t name_len;
4002 int retval;
4003
4004 if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
4005 {
4006 errno = EINVAL;
4007 return -1;
4008 }
4009
4010 /* DJGPP's 'putenv' deletes the entry if it doesn't include '='. */
4011 putenv (name);
4012
4013 return 0;
4014}
4015#endif
4016
3916 4017
3917#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2 4018#if __DJGPP__ == 2 && __DJGPP_MINOR__ < 2
3918 4019
@@ -4038,7 +4139,7 @@ dos_yield_time_slice (void)
4038/* We don't have to call timer_check here 4139/* We don't have to call timer_check here
4039 because wait_reading_process_output takes care of that. */ 4140 because wait_reading_process_output takes care of that. */
4040int 4141int
4041sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, 4142sys_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
4042 struct timespec *timeout, void *ignored) 4143 struct timespec *timeout, void *ignored)
4043{ 4144{
4044 int check_input; 4145 int check_input;