diff options
| author | Paul Eggert | 2014-04-16 12:43:46 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-04-16 12:43:46 -0700 |
| commit | 290d7ac277986bd118e594a8100b3f40e4492cb1 (patch) | |
| tree | d63a3aa61cac577dd119665edaffe2def8d194e2 /src/msdos.c | |
| parent | 37eccff4f72c5a36dcd4b89d417b0047aab84e50 (diff) | |
| parent | b262bde327db2cd9b2f01f2d3ed946d0b188cb9d (diff) | |
| download | emacs-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.c | 127 |
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... */ | ||
| 1889 | void | ||
| 1890 | check_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; } | |||
| 3875 | int setpriority (int x, int y, int z) { return 0; } | 3865 | int setpriority (int x, int y, int z) { return 0; } |
| 3876 | pid_t setsid (void) { return 0; } | 3866 | pid_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 |
| 3879 | ssize_t | 3872 | ssize_t |
| 3880 | readlink (const char *name, char *dummy1, size_t dummy2) | 3873 | readlink (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. */ | ||
| 3885 | static char dir_pathname[MAXPATHLEN]; | ||
| 3886 | DIR * | ||
| 3887 | sys_opendir (const char *dirname) | ||
| 3888 | { | ||
| 3889 | _fixpath (dirname, dir_pathname); | ||
| 3890 | return opendir (dirname); | ||
| 3891 | } | ||
| 3892 | |||
| 3893 | ssize_t | ||
| 3894 | readlinkat (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 | |||
| 3889 | char * | 3914 | char * |
| 3890 | careadlinkat (int fd, char const *filename, | 3915 | careadlinkat (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). */ | ||
| 3942 | int | ||
| 3943 | faccessat (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. */ | ||
| 3960 | int | ||
| 3961 | fstatat (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. */ | ||
| 3997 | int | ||
| 3998 | unsetenv (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. */ |
| 4040 | int | 4141 | int |
| 4041 | sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, | 4142 | sys_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; |