1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <ctype.h>
26 #include <signal.h>
27 #include <stdio.h>
28 #include <setjmp.h>
29 #ifdef HAVE_PWD_H
30 #include <pwd.h>
31 #include <grp.h>
32 #endif
33 #ifdef HAVE_LIMITS_H
34 #include <limits.h>
35 #endif
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39 #ifdef HAVE_ALLOCA_H
40 #include <alloca.h>
41 #endif
42
43 #include "lisp.h"
44 45
46
47 48
49 #ifndef WINDOWSNT
50 #include "sysselect.h"
51 #endif
52
53 #include "blockinput.h"
54
55 #ifdef WINDOWSNT
56 #define read sys_read
57 #define write sys_write
58 #include <windows.h>
59 #ifndef NULL
60 #define NULL 0
61 #endif
62 #endif
63
64
65 #ifndef fwrite
66 #define sys_fwrite fwrite
67 #else
68 #undef fwrite
69 #endif
70
71 #include <sys/types.h>
72 #include <sys/stat.h>
73 #include <errno.h>
74
75 #ifdef HAVE_SETPGID
76 #if !defined (USG)
77 #undef setpgrp
78 #define setpgrp setpgid
79 #endif
80 #endif
81
82
83 #ifdef HAVE_SYS_SYSTEMINFO_H
84 #include <sys/systeminfo.h>
85 #endif
86
87 #ifdef MSDOS
88 #include <dos.h>
89 #include "dosfns.h"
90 #include "msdos.h"
91 #include <sys/param.h>
92
93 extern int etext;
94 extern unsigned start __asm__ ("start");
95 #endif
96
97 #include <sys/file.h>
98
99 #ifdef HAVE_FCNTL_H
100 #include <fcntl.h>
101 #endif
102
103 #ifndef MSDOS
104 #include <sys/ioctl.h>
105 #endif
106
107 #include "systty.h"
108 #include "syswait.h"
109
110 #if defined (USG)
111 #include <sys/utsname.h>
112 #include <memory.h>
113 #endif
114
115 extern int quit_char;
116
117 #include "keyboard.h"
118 #include "frame.h"
119 #include "window.h"
120 #include "termhooks.h"
121 #include "termchar.h"
122 #include "termopts.h"
123 #include "dispextern.h"
124 #include "process.h"
125 #include "cm.h"
126
127
128 extern Lisp_Object QCport, QCspeed, QCprocess;
129 extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
130 extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
131
132 #ifdef WINDOWSNT
133 #include <direct.h>
134
135 #define _P_WAIT 0
136 int _cdecl _spawnlp (int, const char *, const char *, ...);
137 int _cdecl _getpid (void);
138 extern char *getwd (char *);
139 #endif
140
141 #include "syssignal.h"
142 #include "systime.h"
143 #ifdef HAVE_UTIME_H
144 #include <utime.h>
145 #endif
146
147 #ifndef HAVE_UTIMES
148 #ifndef HAVE_STRUCT_UTIMBUF
149 150
151 struct utimbuf {
152 long actime;
153 long modtime;
154 };
155 #endif
156 #endif
157
158
159 #ifndef LPASS8
160 #define LPASS8 0
161 #endif
162
163 static const int baud_convert[] =
164 {
165 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
166 1800, 2400, 4800, 9600, 19200, 38400
167 };
168
169 #ifdef HAVE_SPEED_T
170 #include <termios.h>
171 #else
172 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
173 #else
174 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
175 #include <termios.h>
176 #endif
177 #endif
178 #endif
179
180 int emacs_ospeed;
181
182 void croak P_ ((char *)) NO_RETURN;
183
184
185
186 SIGMASKTYPE sigprocmask_set;
187
188
189 #if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
190
191 192 193
194 char*
195 get_current_dir_name ()
196 {
197 char *buf;
198 char *pwd;
199 struct stat dotstat, pwdstat;
200 201 202
203 if ((pwd = getenv ("PWD")) != 0
204 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
205 && stat (pwd, &pwdstat) == 0
206 && stat (".", &dotstat) == 0
207 && dotstat.st_ino == pwdstat.st_ino
208 && dotstat.st_dev == pwdstat.st_dev
209 #ifdef MAXPATHLEN
210 && strlen (pwd) < MAXPATHLEN
211 #endif
212 )
213 {
214 buf = (char *) malloc (strlen (pwd) + 1);
215 if (!buf)
216 return NULL;
217 strcpy (buf, pwd);
218 }
219 #ifdef HAVE_GETCWD
220 else
221 {
222 size_t buf_size = 1024;
223 buf = (char *) malloc (buf_size);
224 if (!buf)
225 return NULL;
226 for (;;)
227 {
228 if (getcwd (buf, buf_size) == buf)
229 break;
230 if (errno != ERANGE)
231 {
232 int tmp_errno = errno;
233 free (buf);
234 errno = tmp_errno;
235 return NULL;
236 }
237 buf_size *= 2;
238 buf = (char *) realloc (buf, buf_size);
239 if (!buf)
240 return NULL;
241 }
242 }
243 #else
244 else
245 {
246
247 buf = (char *) malloc (MAXPATHLEN + 1);
248 if (!buf)
249 return NULL;
250 if (getwd (buf) == NULL)
251 {
252 int tmp_errno = errno;
253 free (buf);
254 errno = tmp_errno;
255 return NULL;
256 }
257 }
258 #endif
259 return buf;
260 }
261 #endif
262
263
264
265
266 void
267 discard_tty_input ()
268 {
269 #ifndef WINDOWSNT
270 struct emacs_tty buf;
271
272 if (noninteractive)
273 return;
274
275 #ifdef MSDOS
276 while (dos_keyread () != -1)
277 ;
278 #else
279 {
280 struct tty_display_info *tty;
281 for (tty = tty_list; tty; tty = tty->next)
282 {
283 if (tty->input)
284 {
285 EMACS_GET_TTY (fileno (tty->input), &buf);
286 EMACS_SET_TTY (fileno (tty->input), &buf, 0);
287 }
288 }
289 }
290 #endif
291 #endif
292 }
293
294
295 #ifdef SIGTSTP
296
297 298 299 300
301
302 void
303 stuff_char (char c)
304 {
305 if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
306 return;
307
308
309 #ifdef TIOCSTI
310 ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
311 #else
312 error ("Cannot stuff terminal input characters in this version of Unix");
313 #endif
314 }
315
316 #endif
317
318 void
319 init_baud_rate (int fd)
320 {
321 if (noninteractive)
322 emacs_ospeed = 0;
323 else
324 {
325 #ifdef DOS_NT
326 emacs_ospeed = 15;
327 #else
328 #ifdef HAVE_TERMIOS
329 struct termios sg;
330
331 sg.c_cflag = B9600;
332 tcgetattr (fd, &sg);
333 emacs_ospeed = cfgetospeed (&sg);
334 #else
335 #ifdef HAVE_TERMIO
336 struct termio sg;
337
338 sg.c_cflag = B9600;
339 #ifdef HAVE_TCATTR
340 tcgetattr (fd, &sg);
341 #else
342 ioctl (fd, TCGETA, &sg);
343 #endif
344 emacs_ospeed = sg.c_cflag & CBAUD;
345 #else
346 struct sgttyb sg;
347
348 sg.sg_ospeed = B9600;
349 if (ioctl (fd, TIOCGETP, &sg) < 0)
350 abort ();
351 emacs_ospeed = sg.sg_ospeed;
352 #endif
353 #endif
354 #endif
355 }
356
357 baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
358 ? baud_convert[emacs_ospeed] : 9600);
359 if (baud_rate == 0)
360 baud_rate = 1200;
361 }
362
363
364
365 void
366 set_exclusive_use (fd)
367 int fd;
368 {
369 #ifdef FIOCLEX
370 ioctl (fd, FIOCLEX, 0);
371 #endif
372
373 }
374
375 #ifndef subprocesses
376
377 wait_without_blocking ()
378 {
379 croak ("wait_without_blocking");
380 synch_process_alive = 0;
381 }
382
383 #endif
384
385 int wait_debugging; 386
387
388 SIGTYPE
389 wait_for_termination_signal ()
390 {}
391
392 393
394
395 void
396 wait_for_termination (pid)
397 int pid;
398 {
399 while (1)
400 {
401 #ifdef subprocesses
402 #if defined (BSD_SYSTEM) || defined (HPUX)
403 404 405
406 407 408 409
410 sigsetmask (sigmask (SIGCHLD));
411 if (0 > kill (pid, 0))
412 {
413 sigsetmask (SIGEMPTYMASK);
414 kill (getpid (), SIGCHLD);
415 break;
416 }
417 if (wait_debugging)
418 sleep (1);
419 else
420 sigpause (SIGEMPTYMASK);
421 #else
422 #ifdef WINDOWSNT
423 wait (0);
424 break;
425 #else
426 sigblock (sigmask (SIGCHLD));
427 errno = 0;
428 if (kill (pid, 0) == -1 && errno == ESRCH)
429 {
430 sigunblock (sigmask (SIGCHLD));
431 break;
432 }
433
434 sigsuspend (&empty_mask);
435 #endif
436 #endif
437 #else
438 break;
439 #endif
440 }
441 }
442
443 #ifdef subprocesses
444
445 446 447 448
449
450 void
451 flush_pending_output (channel)
452 int channel;
453 {
454 #ifdef HAVE_TERMIOS
455 456
457 #else
458 #ifdef TCFLSH
459 ioctl (channel, TCFLSH, 1);
460 #else
461 #ifdef TIOCFLUSH
462 int zero = 0;
463 464 465
466 ioctl (channel, TIOCFLUSH, &zero);
467 #endif
468 #endif
469 #endif
470 }
471
472 473 474 475
476
477 void
478 child_setup_tty (out)
479 int out;
480 {
481 #ifndef DOS_NT
482 struct emacs_tty s;
483
484 EMACS_GET_TTY (out, &s);
485
486 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
487 s.main.c_oflag |= OPOST;
488 s.main.c_oflag &= ~ONLCR;
489 #ifdef NLDLY
490 491
492 #ifdef FFDLY
493 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
494
495 #else
496 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY);
497
498 #endif
499 #endif
500 s.main.c_lflag &= ~ECHO;
501 s.main.c_lflag |= ISIG;
502 #ifdef IUCLC
503 s.main.c_iflag &= ~IUCLC;
504 #endif
505 #ifdef ISTRIP
506 s.main.c_iflag &= ~ISTRIP;
507 #endif
508 #ifdef OLCUC
509 s.main.c_oflag &= ~OLCUC;
510 #endif
511 s.main.c_oflag &= ~TAB3;
512 s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8;
513 s.main.c_cc[VERASE] = CDISABLE;
514 s.main.c_cc[VKILL] = CDISABLE;
515
516 #ifdef HPUX
517 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600;
518 #endif
519
520 #ifdef SIGNALS_VIA_CHARACTERS
521 522
523 if (s.main.c_cc[VQUIT] == CDISABLE)
524 s.main.c_cc[VQUIT] = '\\'&037;
525 if (s.main.c_cc[VINTR] == CDISABLE)
526 s.main.c_cc[VINTR] = 'C'&037;
527 #endif
528
529 #ifdef AIX
530 531
532 s.main.c_iflag &= ~IGNBRK;
533 s.main.c_iflag &= ~BRKINT;
534 535 536
537 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600;
538 #endif
539
540 #else
541
542 s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
543 | CBREAK | TANDEM);
544 s.main.sg_flags |= LPASS8;
545 s.main.sg_erase = 0377;
546 s.main.sg_kill = 0377;
547 s.lmode = LLITOUT | s.lmode;
548
549 550 551 552 553 554 555 556
557 s.main.c_lflag &= ~ICANON;
558 s.main.c_cc[VMIN] = 1;
559 s.main.c_cc[VTIME] = 0;
560
561 #endif
562
563 EMACS_SET_TTY (out, &s, 0);
564
565 #endif
566 }
567
568 #endif
569
570
571 struct save_signal
572 {
573 int code;
574 SIGTYPE (*handler) P_ ((int));
575 };
576
577 static void save_signal_handlers P_ ((struct save_signal *));
578 static void restore_signal_handlers P_ ((struct save_signal *));
579
580
581
582 void
583 sys_suspend ()
584 {
585 #if defined (SIGTSTP) && !defined (MSDOS)
586
587 {
588 int pgrp = EMACS_GETPGRP (0);
589 EMACS_KILLPG (pgrp, SIGTSTP);
590 }
591
592 #else
593 594 595
596 sys_subshell ();
597
598 #endif
599 }
600
601
602
603 void
604 sys_subshell ()
605 {
606 #ifdef DOS_NT
607 int st;
608 char oldwd[MAXPATHLEN+1];
609 #endif
610 int pid;
611 struct save_signal saved_handlers[5];
612 Lisp_Object dir;
613 unsigned char *str = 0;
614 int len;
615
616 saved_handlers[0].code = SIGINT;
617 saved_handlers[1].code = SIGQUIT;
618 saved_handlers[2].code = SIGTERM;
619 #ifdef SIGIO
620 saved_handlers[3].code = SIGIO;
621 saved_handlers[4].code = 0;
622 #else
623 saved_handlers[3].code = 0;
624 #endif
625
626 627
628
629 dir = intern ("default-directory");
630 if (NILP (Fboundp (dir)))
631 goto xyzzy;
632 dir = Fsymbol_value (dir);
633 if (!STRINGP (dir))
634 goto xyzzy;
635
636 dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
637 str = (unsigned char *) alloca (SCHARS (dir) + 2);
638 len = SCHARS (dir);
639 bcopy (SDATA (dir), str, len);
640 if (str[len - 1] != '/') str[len++] = '/';
641 str[len] = 0;
642 xyzzy:
643
644 #ifdef DOS_NT
645 pid = 0;
646 save_signal_handlers (saved_handlers);
647 synch_process_alive = 1;
648 #else
649 pid = vfork ();
650 if (pid == -1)
651 error ("Can't spawn subshell");
652 #endif
653
654 if (pid == 0)
655 {
656 char *sh = 0;
657
658 #ifdef DOS_NT
659 getwd (oldwd);
660 if (sh == 0)
661 sh = (char *) egetenv ("SUSPEND");
662 #endif
663 if (sh == 0)
664 sh = (char *) egetenv ("SHELL");
665 if (sh == 0)
666 sh = "sh";
667
668
669 if (str)
670 chdir ((char *) str);
671
672 #ifdef subprocesses
673 close_process_descs ();
674 #endif
675
676 #ifdef SET_EMACS_PRIORITY
677 {
678 extern EMACS_INT emacs_priority;
679
680 if (emacs_priority < 0)
681 nice (-emacs_priority);
682 }
683 #endif
684
685 #ifdef MSDOS
686 {
687 char *epwd = getenv ("PWD");
688 char old_pwd[MAXPATHLEN+1+4];
689
690
691 if (epwd)
692 {
693 strcpy (old_pwd, epwd);
694 if (str[len - 1] == '/')
695 str[len - 1] = '\0';
696 setenv ("PWD", str, 1);
697 }
698 st = system (sh);
699 chdir (oldwd);
700 if (epwd)
701 putenv (old_pwd);
702 }
703 #else
704 #ifdef WINDOWSNT
705
706 pid = _spawnlp (_P_WAIT, sh, sh, NULL);
707 chdir (oldwd);
708 if (pid == -1)
709 write (1, "Can't execute subshell", 22);
710 #else
711 execlp (sh, sh, (char *) 0);
712 write (1, "Can't execute subshell", 22);
713 _exit (1);
714 #endif
715 #endif
716 }
717
718
719 #ifndef MSDOS
720 save_signal_handlers (saved_handlers);
721 synch_process_alive = 1;
722 #endif
723
724 #ifndef DOS_NT
725 wait_for_termination (pid);
726 #endif
727 restore_signal_handlers (saved_handlers);
728 synch_process_alive = 0;
729 }
730
731 static void
732 save_signal_handlers (saved_handlers)
733 struct save_signal *saved_handlers;
734 {
735 while (saved_handlers->code)
736 {
737 saved_handlers->handler
738 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
739 saved_handlers++;
740 }
741 }
742
743 static void
744 restore_signal_handlers (saved_handlers)
745 struct save_signal *saved_handlers;
746 {
747 while (saved_handlers->code)
748 {
749 signal (saved_handlers->code, saved_handlers->handler);
750 saved_handlers++;
751 }
752 }
753
754 #ifndef SIGIO
755
756 void
757 init_sigio (int fd)
758 {
759 }
760
761 void
762 reset_sigio (int fd)
763 {
764 }
765
766 void
767 request_sigio (void)
768 {
769 }
770
771 void
772 unrequest_sigio (void)
773 {
774 }
775
776 #else
777 #ifdef F_SETFL
778
779 int old_fcntl_flags[MAXDESC];
780
781 void
782 init_sigio (fd)
783 int fd;
784 {
785 #ifdef FASYNC
786 old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
787 fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC);
788 #endif
789 interrupts_deferred = 0;
790 }
791
792 void
793 reset_sigio (fd)
794 int fd;
795 {
796 #ifdef FASYNC
797 fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
798 #endif
799 }
800
801 #ifdef FASYNC
802
803
804
805 void
806 request_sigio ()
807 {
808 if (noninteractive)
809 return;
810
811 #ifdef SIGWINCH
812 sigunblock (sigmask (SIGWINCH));
813 #endif
814 sigunblock (sigmask (SIGIO));
815
816 interrupts_deferred = 0;
817 }
818
819 void
820 unrequest_sigio (void)
821 {
822 if (noninteractive)
823 return;
824
825 #if 0
826 if (x_display_list)
827 return;
828 #endif
829
830 #ifdef SIGWINCH
831 sigblock (sigmask (SIGWINCH));
832 #endif
833 sigblock (sigmask (SIGIO));
834 interrupts_deferred = 1;
835 }
836
837 #else
838 #ifndef MSDOS
839
840 void
841 request_sigio ()
842 {
843 if (noninteractive || read_socket_hook)
844 return;
845
846 croak ("request_sigio");
847 }
848
849 void
850 unrequest_sigio ()
851 {
852 if (noninteractive || read_socket_hook)
853 return;
854
855 croak ("unrequest_sigio");
856 }
857
858 #endif
859 #endif
860 #endif
861 #endif
862
863
864
865
866 867 868
869 int
870 emacs_get_tty (fd, settings)
871 int fd;
872 struct emacs_tty *settings;
873 {
874
875 #ifdef HAVE_TCATTR
876
877 bzero (&settings->main, sizeof (settings->main));
878 if (tcgetattr (fd, &settings->main) < 0)
879 return -1;
880
881 #else
882 #ifdef HAVE_TERMIO
883
884 if (ioctl (fd, TCGETA, &settings->main) < 0)
885 return -1;
886
887 #else
888 #ifndef DOS_NT
889
890 if (ioctl (fd, TIOCGETP, &settings->main) < 0)
891 return -1;
892 #endif
893 #endif
894 #endif
895
896
897 #ifdef HAVE_LTCHARS
898 if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
899 return -1;
900 #endif
901
902
903 #ifdef HAVE_TCHARS
904 if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
905 || ioctl (fd, TIOCLGET, &settings->lmode) < 0)
906 return -1;
907 #endif
908
909
910 return 0;
911 }
912
913
914 915 916
917
918 int
919 emacs_set_tty (fd, settings, flushp)
920 int fd;
921 struct emacs_tty *settings;
922 int flushp;
923 {
924
925 #ifdef HAVE_TCATTR
926 int i;
927 928 929 930 931 932 933
934
935 for (i = 0 ; i < 10 ; i++)
936 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
937 {
938 if (errno == EINTR)
939 continue;
940 else
941 return -1;
942 }
943 else
944 {
945 struct termios new;
946
947 bzero (&new, sizeof (new));
948
949 tcgetattr (fd, &new);
950 951 952 953
954 if ( new.c_iflag == settings->main.c_iflag
955 && new.c_oflag == settings->main.c_oflag
956 && new.c_cflag == settings->main.c_cflag
957 && new.c_lflag == settings->main.c_lflag
958 && memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
959 break;
960 else
961 continue;
962 }
963
964 #else
965 #ifdef HAVE_TERMIO
966
967 if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
968 return -1;
969
970 #else
971 #ifndef DOS_NT
972
973 if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
974 return -1;
975 #endif
976
977 #endif
978 #endif
979
980
981 #ifdef HAVE_LTCHARS
982 if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
983 return -1;
984 #endif
985
986
987 #ifdef HAVE_TCHARS
988 if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
989 || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
990 return -1;
991 #endif
992
993
994 return 0;
995 }
996
997
998
999 #ifdef F_SETOWN
1000 int old_fcntl_owner[MAXDESC];
1001 #endif
1002
1003 1004 1005
1006
1007 #if defined (USG)
1008 unsigned char _sobuf[BUFSIZ+8];
1009 #else
1010 char _sobuf[BUFSIZ];
1011 #endif
1012
1013 #ifdef HAVE_LTCHARS
1014 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
1015 #endif
1016 #ifdef HAVE_TCHARS
1017 static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
1018 #endif
1019
1020 1021
1022
1023 void
1024 init_all_sys_modes (void)
1025 {
1026 struct tty_display_info *tty;
1027 for (tty = tty_list; tty; tty = tty->next)
1028 init_sys_modes (tty);
1029 }
1030
1031
1032
1033 void
1034 init_sys_modes (tty_out)
1035 struct tty_display_info *tty_out;
1036 {
1037 struct emacs_tty tty;
1038
1039 Vtty_erase_char = Qnil;
1040
1041 if (noninteractive)
1042 return;
1043
1044 if (!tty_out->output)
1045 return;
1046
1047 if (! tty_out->old_tty)
1048 tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
1049
1050 EMACS_GET_TTY (fileno (tty_out->input), tty_out->old_tty);
1051
1052 tty = *tty_out->old_tty;
1053
1054 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1055 XSETINT (Vtty_erase_char, tty.main.c_cc[VERASE]);
1056
1057 tty.main.c_iflag |= (IGNBRK);
1058 tty.main.c_iflag &= ~ICRNL;
1059 #ifdef INLCR 1060
1061 tty.main.c_iflag &= ~INLCR;
1062 #endif
1063 #ifdef ISTRIP
1064 tty.main.c_iflag &= ~ISTRIP;
1065 #endif
1066 tty.main.c_lflag &= ~ECHO;
1067 tty.main.c_lflag &= ~ICANON;
1068 #ifdef IEXTEN
1069 tty.main.c_lflag &= ~IEXTEN;
1070 #endif
1071 tty.main.c_lflag |= ISIG;
1072 if (tty_out->flow_control)
1073 {
1074 tty.main.c_iflag |= IXON;
1075 #ifdef IXANY
1076 tty.main.c_iflag &= ~IXANY;
1077 #endif
1078 }
1079 else
1080 tty.main.c_iflag &= ~IXON;
1081 tty.main.c_oflag &= ~ONLCR; 1082
1083 tty.main.c_oflag &= ~TAB3;
1084 #ifdef CS8
1085 if (tty_out->meta_key)
1086 {
1087 tty.main.c_cflag |= CS8;
1088 tty.main.c_cflag &= ~PARENB;
1089 }
1090 #endif
1091 if (tty_out->input == stdin)
1092 {
1093 tty.main.c_cc[VINTR] = quit_char;
1094 1095 1096
1097 tty.main.c_cc[VQUIT] = quit_char;
1098 }
1099 else
1100 {
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
1116 tty.main.c_cc[VINTR] = CDISABLE;
1117 tty.main.c_cc[VQUIT] = CDISABLE;
1118 }
1119 tty.main.c_cc[VMIN] = 1;
1120 tty.main.c_cc[VTIME] = 0;
1121 #ifdef VSWTCH
1122 tty.main.c_cc[VSWTCH] = CDISABLE; 1123
1124 #endif
1125
1126 #if defined (__mips__) || defined (HAVE_TCATTR)
1127 #ifdef VSUSP
1128 tty.main.c_cc[VSUSP] = CDISABLE;
1129 #endif
1130 #ifdef V_DSUSP
1131 tty.main.c_cc[V_DSUSP] = CDISABLE;
1132 #endif
1133 #ifdef VDSUSP
1134 tty.main.c_cc[VDSUSP] = CDISABLE;
1135 #endif
1136 #ifdef VLNEXT
1137 tty.main.c_cc[VLNEXT] = CDISABLE;
1138 #endif
1139 #ifdef VREPRINT
1140 tty.main.c_cc[VREPRINT] = CDISABLE;
1141 #endif
1142 #ifdef VWERASE
1143 tty.main.c_cc[VWERASE] = CDISABLE;
1144 #endif
1145 #ifdef VDISCARD
1146 tty.main.c_cc[VDISCARD] = CDISABLE;
1147 #endif
1148
1149 if (tty_out->flow_control)
1150 {
1151 #ifdef VSTART
1152 tty.main.c_cc[VSTART] = '\021';
1153 #endif
1154 #ifdef VSTOP
1155 tty.main.c_cc[VSTOP] = '\023';
1156 #endif
1157 }
1158 else
1159 {
1160 #ifdef VSTART
1161 tty.main.c_cc[VSTART] = CDISABLE;
1162 #endif
1163 #ifdef VSTOP
1164 tty.main.c_cc[VSTOP] = CDISABLE;
1165 #endif
1166 }
1167 #endif
1168
1169 #ifdef AIX
1170 tty.main.c_cc[VSTRT] = CDISABLE;
1171 tty.main.c_cc[VSTOP] = CDISABLE;
1172 tty.main.c_cc[VSUSP] = CDISABLE;
1173 tty.main.c_cc[VDSUSP] = CDISABLE;
1174 if (tty_out->flow_control)
1175 {
1176 #ifdef VSTART
1177 tty.main.c_cc[VSTART] = '\021';
1178 #endif
1179 #ifdef VSTOP
1180 tty.main.c_cc[VSTOP] = '\023';
1181 #endif
1182 }
1183 1184 1185 1186
1187 tty.main.c_iflag &= ~IGNBRK;
1188 tty.main.c_iflag &= ~BRKINT;
1189 #endif
1190 #else
1191 #ifndef DOS_NT
1192 XSETINT (Vtty_erase_char, tty.main.sg_erase);
1193 tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1194 if (meta_key)
1195 tty.main.sg_flags |= ANYP;
1196 tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
1197 #endif
1198 #endif
1199
1200 1201 1202 1203 1204
1205 #ifndef HAVE_TERMIO
1206 #ifdef HAVE_TCHARS
1207 1208
1209 tty.tchars = new_tchars;
1210 tty.tchars.t_intrc = quit_char;
1211 if (tty_out->flow_control)
1212 {
1213 tty.tchars.t_startc = '\021';
1214 tty.tchars.t_stopc = '\023';
1215 }
1216
1217 tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | tty_out->old_tty.lmode;
1218
1219 #endif
1220 #endif
1221
1222 #ifdef HAVE_LTCHARS
1223 tty.ltchars = new_ltchars;
1224 #endif
1225 #ifdef MSDOS
1226 if (!tty_out->term_initted)
1227 internal_terminal_init ();
1228 dos_ttraw (tty_out);
1229 #endif
1230
1231 EMACS_SET_TTY (fileno (tty_out->input), &tty, 0);
1232
1233 1234
1235
1236 #ifdef TCXONC
1237 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
1238 #endif
1239 #ifdef TIOCSTART
1240 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
1241 #endif
1242
1243 #if defined (HAVE_TERMIOS) || defined (HPUX)
1244 #ifdef TCOON
1245 if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
1246 #endif
1247 #endif
1248
1249 #ifdef F_SETFL
1250 #ifdef F_GETOWN
1251 if (interrupt_input)
1252 {
1253 old_fcntl_owner[fileno (tty_out->input)] =
1254 fcntl (fileno (tty_out->input), F_GETOWN, 0);
1255 fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
1256 init_sigio (fileno (tty_out->input));
1257 #ifdef HAVE_GPM
1258 if (gpm_tty == tty_out)
1259 {
1260
1261 fcntl (gpm_fd, F_SETOWN, getpid ());
1262 fcntl (gpm_fd, F_SETFL, fcntl (gpm_fd, F_GETFL, 0) | O_NONBLOCK);
1263 init_sigio (gpm_fd);
1264 }
1265 #endif
1266 }
1267 #endif
1268 #endif
1269
1270 #ifdef _IOFBF
1271 1272 1273
1274 setvbuf (tty_out->output, (char *) _sobuf, _IOFBF, sizeof _sobuf);
1275 #else
1276 setbuf (tty_out->output, (char *) _sobuf);
1277 #endif
1278
1279 if (tty_out->terminal->set_terminal_modes_hook)
1280 tty_out->terminal->set_terminal_modes_hook (tty_out->terminal);
1281
1282 if (!tty_out->term_initted)
1283 {
1284 Lisp_Object tail, frame;
1285 FOR_EACH_FRAME (tail, frame)
1286 {
1287
1288 if (FRAME_TERMCAP_P (XFRAME (frame))
1289 && FRAME_TTY (XFRAME (frame)) == tty_out)
1290 init_frame_faces (XFRAME (frame));
1291 }
1292 }
1293
1294 if (tty_out->term_initted && no_redraw_on_reenter)
1295 {
1296 1297
1298 }
1299 else
1300 {
1301 Lisp_Object tail, frame;
1302 frame_garbaged = 1;
1303 FOR_EACH_FRAME (tail, frame)
1304 {
1305 if ((FRAME_TERMCAP_P (XFRAME (frame))
1306 || FRAME_MSDOS_P (XFRAME (frame)))
1307 && FRAME_TTY (XFRAME (frame)) == tty_out)
1308 FRAME_GARBAGED_P (XFRAME (frame)) = 1;
1309 }
1310 }
1311
1312 tty_out->term_initted = 1;
1313 }
1314
1315 1316
1317
1318 int
1319 tabs_safe_p (int fd)
1320 {
1321 struct emacs_tty etty;
1322
1323 EMACS_GET_TTY (fd, &etty);
1324 return EMACS_TTY_TABS_OK (&etty);
1325 }
1326
1327 1328 1329
1330
1331 void
1332 get_tty_size (int fd, int *widthp, int *heightp)
1333 {
1334
1335 #ifdef TIOCGWINSZ
1336
1337
1338 struct winsize size;
1339
1340 if (ioctl (fd, TIOCGWINSZ, &size) == -1)
1341 *widthp = *heightp = 0;
1342 else
1343 {
1344 *widthp = size.ws_col;
1345 *heightp = size.ws_row;
1346 }
1347
1348 #else
1349 #ifdef TIOCGSIZE
1350
1351
1352 struct ttysize size;
1353
1354 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1355 *widthp = *heightp = 0;
1356 else
1357 {
1358 *widthp = size.ts_cols;
1359 *heightp = size.ts_lines;
1360 }
1361
1362 #else
1363 #ifdef MSDOS
1364 *widthp = ScreenCols ();
1365 *heightp = ScreenRows ();
1366 #else
1367 *widthp = 0;
1368 *heightp = 0;
1369 #endif
1370 #endif
1371 #endif
1372 }
1373
1374 1375
1376
1377 int
1378 set_window_size (fd, height, width)
1379 int fd, height, width;
1380 {
1381 #ifdef TIOCSWINSZ
1382
1383
1384 struct winsize size;
1385 size.ws_row = height;
1386 size.ws_col = width;
1387
1388 if (ioctl (fd, TIOCSWINSZ, &size) == -1)
1389 return 0;
1390 else
1391 return 1;
1392
1393 #else
1394 #ifdef TIOCSSIZE
1395
1396
1397 struct ttysize size;
1398 size.ts_lines = height;
1399 size.ts_cols = width;
1400
1401 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1402 return 0;
1403 else
1404 return 1;
1405 #else
1406 return -1;
1407 #endif
1408 #endif
1409 }
1410
1411
1412
1413
1414
1415 void
1416 reset_all_sys_modes (void)
1417 {
1418 struct tty_display_info *tty;
1419 for (tty = tty_list; tty; tty = tty->next)
1420 reset_sys_modes (tty);
1421 }
1422
1423 1424
1425
1426 void
1427 reset_sys_modes (tty_out)
1428 struct tty_display_info *tty_out;
1429 {
1430 if (noninteractive)
1431 {
1432 fflush (stdout);
1433 return;
1434 }
1435 if (!tty_out->term_initted)
1436 return;
1437
1438 if (!tty_out->output)
1439 return;
1440
1441
1442
1443 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1444
1445
1446 if (tty_out->TS_clr_line)
1447 {
1448 emacs_tputs (tty_out, tty_out->TS_clr_line, 1, cmputc);
1449 }
1450 else
1451 {
1452 int i;
1453 tty_turn_off_insert (tty_out);
1454
1455 for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
1456 {
1457 fputc (' ', tty_out->output);
1458 }
1459 }
1460
1461 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1462 fflush (tty_out->output);
1463
1464 if (tty_out->terminal->reset_terminal_modes_hook)
1465 tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
1466
1467 #ifdef BSD_SYSTEM
1468
1469 fsync (fileno (tty_out->output));
1470 #endif
1471
1472 #ifdef F_SETFL
1473 #ifdef F_SETOWN
1474 if (interrupt_input)
1475 {
1476 reset_sigio (fileno (tty_out->input));
1477 fcntl (fileno (tty_out->input), F_SETOWN,
1478 old_fcntl_owner[fileno (tty_out->input)]);
1479 }
1480 #endif
1481 #ifdef O_NDELAY
1482 fcntl (fileno (tty_out->input), F_SETFL,
1483 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY);
1484 #endif
1485 #endif
1486
1487 if (tty_out->old_tty)
1488 while (EMACS_SET_TTY (fileno (tty_out->input),
1489 tty_out->old_tty, 0) < 0 && errno == EINTR)
1490 ;
1491
1492 #ifdef MSDOS
1493 dos_ttcooked ();
1494 #endif
1495
1496 }
1497
1498 #ifdef HAVE_PTYS
1499
1500
1501
1502 void
1503 setup_pty (fd)
1504 int fd;
1505 {
1506 1507 1508 1509 1510 1511 1512
1513
1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528
1529 #ifdef FIONBIO
1530 #if defined(UNIX98_PTYS)
1531 {
1532 int on = 1;
1533 ioctl (fd, FIONBIO, &on);
1534 }
1535 #endif
1536 #endif
1537 }
1538 #endif
1539
1540 #if !defined(CANNOT_DUMP) || !defined(SYSTEM_MALLOC)
1541
1542
1543 1544 1545 1546 1547 1548
1549
1550 #if !(defined (__NetBSD__) && defined (__ELF__))
1551 #ifndef HAVE_TEXT_START
1552 char *
1553 start_of_text ()
1554 {
1555 #ifdef TEXT_START
1556 return ((char *) TEXT_START);
1557 #else
1558 extern int _start ();
1559 return ((char *) _start);
1560 #endif
1561 }
1562 #endif
1563 #endif
1564
1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589
1590
1591 #ifndef start_of_data
1592 char *
1593 start_of_data ()
1594 {
1595 #ifdef DATA_START
1596 return ((char *) DATA_START);
1597 #else
1598 #ifdef ORDINARY_LINK
1599 1600 1601 1602 1603 1604
1605 extern char **environ;
1606
1607 return ((char *) &environ);
1608 #else
1609 extern int data_start;
1610 return ((char *) &data_start);
1611 #endif
1612 #endif
1613 }
1614 #endif
1615 #endif
1616
1617 1618
1619
1620 extern Lisp_Object Vsystem_name;
1621
1622 #ifdef HAVE_SOCKETS
1623 #include <sys/socket.h>
1624 #include <netdb.h>
1625 #endif
1626
1627 #ifdef TRY_AGAIN
1628 #ifndef HAVE_H_ERRNO
1629 extern int h_errno;
1630 #endif
1631 #endif
1632
1633 void
1634 init_system_name ()
1635 {
1636 #ifndef HAVE_GETHOSTNAME
1637 struct utsname uts;
1638 uname (&uts);
1639 Vsystem_name = build_string (uts.nodename);
1640 #else
1641 unsigned int hostname_size = 256;
1642 char *hostname = (char *) alloca (hostname_size);
1643
1644 1645 1646 1647
1648 for (;;)
1649 {
1650 gethostname (hostname, hostname_size - 1);
1651 hostname[hostname_size - 1] = '\0';
1652
1653
1654 if (strlen (hostname) < hostname_size - 1)
1655 break;
1656
1657 hostname_size <<= 1;
1658 hostname = (char *) alloca (hostname_size);
1659 }
1660 #ifdef HAVE_SOCKETS
1661 1662 1663
1664 #ifndef CANNOT_DUMP
1665 if (initialized)
1666 #endif
1667 if (! index (hostname, '.'))
1668 {
1669 int count;
1670 #ifdef HAVE_GETADDRINFO
1671 struct addrinfo *res;
1672 struct addrinfo hints;
1673 int ret;
1674
1675 memset (&hints, 0, sizeof(hints));
1676 hints.ai_socktype = SOCK_STREAM;
1677 hints.ai_flags = AI_CANONNAME;
1678
1679 for (count = 0;; count++)
1680 {
1681 if ((ret = getaddrinfo (hostname, NULL, &hints, &res)) == 0
1682 || ret != EAI_AGAIN)
1683 break;
1684
1685 if (count >= 5)
1686 break;
1687 Fsleep_for (make_number (1), Qnil);
1688 }
1689
1690 if (ret == 0)
1691 {
1692 struct addrinfo *it = res;
1693 while (it)
1694 {
1695 char *fqdn = it->ai_canonname;
1696 if (fqdn && index (fqdn, '.')
1697 && strcmp (fqdn, "localhost.localdomain") != 0)
1698 break;
1699 it = it->ai_next;
1700 }
1701 if (it)
1702 {
1703 hostname = alloca (strlen (it->ai_canonname) + 1);
1704 strcpy (hostname, it->ai_canonname);
1705 }
1706 freeaddrinfo (res);
1707 }
1708 #else
1709 struct hostent *hp;
1710 for (count = 0;; count++)
1711 {
1712
1713 #ifdef TRY_AGAIN
1714 h_errno = 0;
1715 #endif
1716 hp = gethostbyname (hostname);
1717 #ifdef TRY_AGAIN
1718 if (! (hp == 0 && h_errno == TRY_AGAIN))
1719 #endif
1720
1721 break;
1722
1723 if (count >= 5)
1724 break;
1725 Fsleep_for (make_number (1), Qnil);
1726 }
1727
1728 if (hp)
1729 {
1730 char *fqdn = (char *) hp->h_name;
1731
1732 if (!index (fqdn, '.'))
1733 {
1734 1735
1736 char **alias = hp->h_aliases;
1737 while (*alias
1738 && (!index (*alias, '.')
1739 || !strcmp (*alias, "localhost.localdomain")))
1740 alias++;
1741 if (*alias)
1742 fqdn = *alias;
1743 }
1744 hostname = fqdn;
1745 }
1746 #endif
1747 }
1748 #endif
1749 Vsystem_name = build_string (hostname);
1750 #endif
1751 {
1752 unsigned char *p;
1753 for (p = SDATA (Vsystem_name); *p; p++)
1754 if (*p == ' ' || *p == '\t')
1755 *p = '-';
1756 }
1757 }
1758
1759 #ifndef MSDOS
1760 #if !defined (HAVE_SELECT)
1761
1762 #include "sysselect.h"
1763 #undef select
1764
1765 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
1766 1767
1768 int *x = &x_windows_lose_if_no_select_system_call;
1769 #endif
1770
1771 1772 1773
1774
1775 #define SELECT_PAUSE 1
1776 int select_alarmed;
1777
1778
1779
1780 jmp_buf read_alarm_throw;
1781
1782 1783
1784
1785 int read_alarm_should_throw;
1786
1787 SIGTYPE
1788 select_alarm ()
1789 {
1790 select_alarmed = 1;
1791 signal (SIGALRM, SIG_IGN);
1792 SIGNAL_THREAD_CHECK (SIGALRM);
1793 if (read_alarm_should_throw)
1794 longjmp (read_alarm_throw, 1);
1795 }
1796
1797 #ifndef WINDOWSNT
1798
1799 int
1800 sys_select (nfds, rfds, wfds, efds, timeout)
1801 int nfds;
1802 SELECT_TYPE *rfds, *wfds, *efds;
1803 EMACS_TIME *timeout;
1804 {
1805 1806
1807 int ravail = 0;
1808 SELECT_TYPE orfds;
1809 int timeoutval;
1810 int *local_timeout;
1811 extern int proc_buffered_char[];
1812 #ifndef subprocesses
1813 int process_tick = 0, update_tick = 0;
1814 #else
1815 extern int process_tick, update_tick;
1816 #endif
1817 unsigned char buf;
1818
1819 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
1820 1821
1822 if (!NILP (Vinitial_window_system))
1823 return select (nfds, rfds, wfds, efds, timeout);
1824 #endif
1825 timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
1826 local_timeout = &timeoutval;
1827 FD_ZERO (&orfds);
1828 if (rfds)
1829 {
1830 orfds = *rfds;
1831 FD_ZERO (rfds);
1832 }
1833 if (wfds)
1834 FD_ZERO (wfds);
1835 if (efds)
1836 FD_ZERO (efds);
1837
1838 1839
1840 if (*local_timeout == 100000 && process_tick == update_tick
1841 && FD_ISSET (0, &orfds))
1842 {
1843 int fd;
1844 for (fd = 1; fd < nfds; ++fd)
1845 if (FD_ISSET (fd, &orfds))
1846 goto hardway;
1847 if (! detect_input_pending ())
1848 read_input_waiting ();
1849 FD_SET (0, rfds);
1850 return 1;
1851 }
1852
1853 hardway:
1854 1855 1856 1857
1858 while (1)
1859 {
1860 register int to_check, fd;
1861
1862 if (rfds)
1863 {
1864 for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
1865 {
1866 if (FD_ISSET (fd, &orfds))
1867 {
1868 int avail = 0, status = 0;
1869
1870 if (fd == 0)
1871 avail = detect_input_pending ();
1872 else
1873 {
1874 #ifdef FIONREAD
1875 status = ioctl (fd, FIONREAD, &avail);
1876 #else
1877 1878
1879 if (proc_buffered_char[fd] >= 0)
1880 avail = 1;
1881 else
1882 {
1883 avail = read (fd, &buf, 1);
1884 if (avail > 0)
1885 proc_buffered_char[fd] = buf;
1886 }
1887 #endif
1888 }
1889 if (status >= 0 && avail > 0)
1890 {
1891 FD_SET (fd, rfds);
1892 ravail++;
1893 }
1894 }
1895 }
1896 }
1897 if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
1898 break;
1899
1900 turn_on_atimers (0);
1901 signal (SIGALRM, select_alarm);
1902 select_alarmed = 0;
1903 alarm (SELECT_PAUSE);
1904
1905
1906 while (select_alarmed == 0 && *local_timeout != 0
1907 && process_tick == update_tick)
1908 {
1909 1910 1911
1912 if (FD_ISSET (0, &orfds))
1913 {
1914 read_input_waiting ();
1915 if (detect_input_pending ())
1916 select_alarmed = 1;
1917 }
1918 else
1919 pause ();
1920 }
1921 (*local_timeout) -= SELECT_PAUSE;
1922
1923
1924 turn_on_atimers (1);
1925
1926 if (*local_timeout == 0)
1927 break;
1928 }
1929 return ravail;
1930 }
1931 #endif
1932
1933 1934
1935
1936 void
1937 read_input_waiting ()
1938 {
1939 1940
1941 int nread, i;
1942 extern int quit_char;
1943
1944 if (read_socket_hook)
1945 {
1946 struct input_event hold_quit;
1947
1948 EVENT_INIT (hold_quit);
1949 hold_quit.kind = NO_EVENT;
1950
1951 read_alarm_should_throw = 0;
1952 if (! setjmp (read_alarm_throw))
1953 nread = (*read_socket_hook) (0, 1, &hold_quit);
1954 else
1955 nread = -1;
1956
1957 if (hold_quit.kind != NO_EVENT)
1958 kbd_buffer_store_event (&hold_quit);
1959 }
1960 else
1961 {
1962 struct input_event e;
1963 char buf[3];
1964 nread = read (fileno (stdin), buf, 1);
1965 EVENT_INIT (e);
1966
1967
1968 e.kind = ASCII_KEYSTROKE_EVENT;
1969 e.frame_or_window = selected_frame;
1970 e.modifiers = 0;
1971 for (i = 0; i < nread; i++)
1972 {
1973 1974
1975 if (read_socket_hook == 0)
1976 {
1977
1978 if (meta_key == 1 && (buf[i] & 0x80))
1979 e.modifiers = meta_modifier;
1980 if (meta_key != 2)
1981 buf[i] &= ~0x80;
1982 }
1983
1984 XSETINT (e.code, buf[i]);
1985 kbd_buffer_store_event (&e);
1986 1987
1988 if (buf[i] == quit_char)
1989 break;
1990 }
1991 }
1992 }
1993
1994 #if !defined (HAVE_SELECT)
1995 #define select sys_select
1996 #endif
1997
1998 #endif
1999 #endif
2000
2001
2002
2003
2004 sigset_t empty_mask, full_mask;
2005
2006 #ifndef WINDOWSNT
2007
2008 signal_handler_t
2009 sys_signal (int signal_number, signal_handler_t action)
2010 {
2011 struct sigaction new_action, old_action;
2012 sigemptyset (&new_action.sa_mask);
2013 new_action.sa_handler = action;
2014 new_action.sa_flags = 0;
2015 #if defined (SA_RESTART)
2016 2017 2018 2019 2020
2021 2022 2023 2024
2025 2026
2027 # if defined (BROKEN_SA_RESTART) || defined(SYNC_INPUT)
2028 if (noninteractive)
2029 # endif
2030 new_action.sa_flags = SA_RESTART;
2031 #endif
2032 sigaction (signal_number, &new_action, &old_action);
2033 return (old_action.sa_handler);
2034 }
2035
2036 #endif
2037
2038 #ifndef __GNUC__
2039 2040
2041 sigset_t
2042 sys_sigmask (int sig)
2043 {
2044 sigset_t mask;
2045 sigemptyset (&mask);
2046 sigaddset (&mask, sig);
2047 return mask;
2048 }
2049 #endif
2050
2051 2052 2053 2054
2055
2056 sigset_t
2057 sys_sigblock (sigset_t new_mask)
2058 {
2059 sigset_t old_mask;
2060 sigprocmask (SIG_BLOCK, &new_mask, &old_mask);
2061 return (old_mask);
2062 }
2063
2064 sigset_t
2065 sys_sigunblock (sigset_t new_mask)
2066 {
2067 sigset_t old_mask;
2068 sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask);
2069 return (old_mask);
2070 }
2071
2072 sigset_t
2073 sys_sigsetmask (sigset_t new_mask)
2074 {
2075 sigset_t old_mask;
2076 sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
2077 return (old_mask);
2078 }
2079
2080
2081 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2082 static char *my_sys_siglist[NSIG];
2083 # ifdef sys_siglist
2084 # undef sys_siglist
2085 # endif
2086 # define sys_siglist my_sys_siglist
2087 #endif
2088
2089 void
2090 init_signals ()
2091 {
2092 sigemptyset (&empty_mask);
2093 sigfillset (&full_mask);
2094
2095 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2096 if (! initialized)
2097 {
2098 # ifdef SIGABRT
2099 sys_siglist[SIGABRT] = "Aborted";
2100 # endif
2101 # ifdef SIGAIO
2102 sys_siglist[SIGAIO] = "LAN I/O interrupt";
2103 # endif
2104 # ifdef SIGALRM
2105 sys_siglist[SIGALRM] = "Alarm clock";
2106 # endif
2107 # ifdef SIGBUS
2108 sys_siglist[SIGBUS] = "Bus error";
2109 # endif
2110 # ifdef SIGCLD
2111 sys_siglist[SIGCLD] = "Child status changed";
2112 # endif
2113 # ifdef SIGCHLD
2114 sys_siglist[SIGCHLD] = "Child status changed";
2115 # endif
2116 # ifdef SIGCONT
2117 sys_siglist[SIGCONT] = "Continued";
2118 # endif
2119 # ifdef SIGDANGER
2120 sys_siglist[SIGDANGER] = "Swap space dangerously low";
2121 # endif
2122 # ifdef SIGDGNOTIFY
2123 sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
2124 # endif
2125 # ifdef SIGEMT
2126 sys_siglist[SIGEMT] = "Emulation trap";
2127 # endif
2128 # ifdef SIGFPE
2129 sys_siglist[SIGFPE] = "Arithmetic exception";
2130 # endif
2131 # ifdef SIGFREEZE
2132 sys_siglist[SIGFREEZE] = "SIGFREEZE";
2133 # endif
2134 # ifdef SIGGRANT
2135 sys_siglist[SIGGRANT] = "Monitor mode granted";
2136 # endif
2137 # ifdef SIGHUP
2138 sys_siglist[SIGHUP] = "Hangup";
2139 # endif
2140 # ifdef SIGILL
2141 sys_siglist[SIGILL] = "Illegal instruction";
2142 # endif
2143 # ifdef SIGINT
2144 sys_siglist[SIGINT] = "Interrupt";
2145 # endif
2146 # ifdef SIGIO
2147 sys_siglist[SIGIO] = "I/O possible";
2148 # endif
2149 # ifdef SIGIOINT
2150 sys_siglist[SIGIOINT] = "I/O intervention required";
2151 # endif
2152 # ifdef SIGIOT
2153 sys_siglist[SIGIOT] = "IOT trap";
2154 # endif
2155 # ifdef SIGKILL
2156 sys_siglist[SIGKILL] = "Killed";
2157 # endif
2158 # ifdef SIGLOST
2159 sys_siglist[SIGLOST] = "Resource lost";
2160 # endif
2161 # ifdef SIGLWP
2162 sys_siglist[SIGLWP] = "SIGLWP";
2163 # endif
2164 # ifdef SIGMSG
2165 sys_siglist[SIGMSG] = "Monitor mode data available";
2166 # endif
2167 # ifdef SIGPHONE
2168 sys_siglist[SIGWIND] = "SIGPHONE";
2169 # endif
2170 # ifdef SIGPIPE
2171 sys_siglist[SIGPIPE] = "Broken pipe";
2172 # endif
2173 # ifdef SIGPOLL
2174 sys_siglist[SIGPOLL] = "Pollable event occurred";
2175 # endif
2176 # ifdef SIGPROF
2177 sys_siglist[SIGPROF] = "Profiling timer expired";
2178 # endif
2179 # ifdef SIGPTY
2180 sys_siglist[SIGPTY] = "PTY I/O interrupt";
2181 # endif
2182 # ifdef SIGPWR
2183 sys_siglist[SIGPWR] = "Power-fail restart";
2184 # endif
2185 # ifdef SIGQUIT
2186 sys_siglist[SIGQUIT] = "Quit";
2187 # endif
2188 # ifdef SIGRETRACT
2189 sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode";
2190 # endif
2191 # ifdef SIGSAK
2192 sys_siglist[SIGSAK] = "Secure attention";
2193 # endif
2194 # ifdef SIGSEGV
2195 sys_siglist[SIGSEGV] = "Segmentation violation";
2196 # endif
2197 # ifdef SIGSOUND
2198 sys_siglist[SIGSOUND] = "Sound completed";
2199 # endif
2200 # ifdef SIGSTOP
2201 sys_siglist[SIGSTOP] = "Stopped (signal)";
2202 # endif
2203 # ifdef SIGSTP
2204 sys_siglist[SIGSTP] = "Stopped (user)";
2205 # endif
2206 # ifdef SIGSYS
2207 sys_siglist[SIGSYS] = "Bad argument to system call";
2208 # endif
2209 # ifdef SIGTERM
2210 sys_siglist[SIGTERM] = "Terminated";
2211 # endif
2212 # ifdef SIGTHAW
2213 sys_siglist[SIGTHAW] = "SIGTHAW";
2214 # endif
2215 # ifdef SIGTRAP
2216 sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
2217 # endif
2218 # ifdef SIGTSTP
2219 sys_siglist[SIGTSTP] = "Stopped (user)";
2220 # endif
2221 # ifdef SIGTTIN
2222 sys_siglist[SIGTTIN] = "Stopped (tty input)";
2223 # endif
2224 # ifdef SIGTTOU
2225 sys_siglist[SIGTTOU] = "Stopped (tty output)";
2226 # endif
2227 # ifdef SIGURG
2228 sys_siglist[SIGURG] = "Urgent I/O condition";
2229 # endif
2230 # ifdef SIGUSR1
2231 sys_siglist[SIGUSR1] = "User defined signal 1";
2232 # endif
2233 # ifdef SIGUSR2
2234 sys_siglist[SIGUSR2] = "User defined signal 2";
2235 # endif
2236 # ifdef SIGVTALRM
2237 sys_siglist[SIGVTALRM] = "Virtual timer expired";
2238 # endif
2239 # ifdef SIGWAITING
2240 sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
2241 # endif
2242 # ifdef SIGWINCH
2243 sys_siglist[SIGWINCH] = "Window size changed";
2244 # endif
2245 # ifdef SIGWIND
2246 sys_siglist[SIGWIND] = "SIGWIND";
2247 # endif
2248 # ifdef SIGXCPU
2249 sys_siglist[SIGXCPU] = "CPU time limit exceeded";
2250 # endif
2251 # ifdef SIGXFSZ
2252 sys_siglist[SIGXFSZ] = "File size limit exceeded";
2253 # endif
2254 }
2255 #endif
2256 }
2257
2258 #ifndef HAVE_RANDOM
2259 #ifdef random
2260 #define HAVE_RANDOM
2261 #endif
2262 #endif
2263
2264 2265 2266 2267
2268
2269 #ifndef RAND_BITS
2270 # ifdef HAVE_RANDOM
2271 # define RAND_BITS 31
2272 # else
2273 # ifdef HAVE_LRAND48
2274 # define RAND_BITS 31
2275 # define random lrand48
2276 # else
2277 # define RAND_BITS 15
2278 # if RAND_MAX == 32767
2279 # define random rand
2280 # else
2281 # if RAND_MAX == 2147483647
2282 # define random() (rand () >> 16)
2283 # else
2284 # ifdef USG
2285 # define random rand
2286 # else
2287 # define random() (rand () >> 16)
2288 # endif
2289 # endif
2290 # endif
2291 # endif
2292 # endif
2293 #endif
2294
2295 void
2296 seed_random (arg)
2297 long arg;
2298 {
2299 #ifdef HAVE_RANDOM
2300 srandom ((unsigned int)arg);
2301 #else
2302 # ifdef HAVE_LRAND48
2303 srand48 (arg);
2304 # else
2305 srand ((unsigned int)arg);
2306 # endif
2307 #endif
2308 }
2309
2310 2311 2312 2313
2314 long
2315 get_random ()
2316 {
2317 long val = random ();
2318 #if VALBITS > RAND_BITS
2319 val = (val << RAND_BITS) ^ random ();
2320 #if VALBITS > 2*RAND_BITS
2321 val = (val << RAND_BITS) ^ random ();
2322 #if VALBITS > 3*RAND_BITS
2323 val = (val << RAND_BITS) ^ random ();
2324 #if VALBITS > 4*RAND_BITS
2325 val = (val << RAND_BITS) ^ random ();
2326 #endif
2327 #endif
2328 #endif
2329 #endif
2330 return val & ((1L << VALBITS) - 1);
2331 }
2332
2333 #ifndef HAVE_STRERROR
2334 #ifndef WINDOWSNT
2335 char *
2336 strerror (errnum)
2337 int errnum;
2338 {
2339 extern char *sys_errlist[];
2340 extern int sys_nerr;
2341
2342 if (errnum >= 0 && errnum < sys_nerr)
2343 return sys_errlist[errnum];
2344 return (char *) "Unknown error";
2345 }
2346 #endif
2347 #endif
2348
2349 int
2350 emacs_open (path, oflag, mode)
2351 const char *path;
2352 int oflag, mode;
2353 {
2354 register int rtnval;
2355
2356 while ((rtnval = open (path, oflag, mode)) == -1
2357 && (errno == EINTR))
2358 QUIT;
2359 return (rtnval);
2360 }
2361
2362 int
2363 emacs_close (fd)
2364 int fd;
2365 {
2366 int did_retry = 0;
2367 register int rtnval;
2368
2369 while ((rtnval = close (fd)) == -1
2370 && (errno == EINTR))
2371 did_retry = 1;
2372
2373 2374 2375
2376 if (rtnval == -1 && did_retry && errno == EBADF)
2377 return 0;
2378
2379 return rtnval;
2380 }
2381
2382 int
2383 emacs_read (fildes, buf, nbyte)
2384 int fildes;
2385 char *buf;
2386 unsigned int nbyte;
2387 {
2388 register int rtnval;
2389
2390 while ((rtnval = read (fildes, buf, nbyte)) == -1
2391 && (errno == EINTR))
2392 QUIT;
2393 return (rtnval);
2394 }
2395
2396 int
2397 emacs_write (fildes, buf, nbyte)
2398 int fildes;
2399 const char *buf;
2400 unsigned int nbyte;
2401 {
2402 register int rtnval, bytes_written;
2403
2404 bytes_written = 0;
2405
2406 while (nbyte > 0)
2407 {
2408 rtnval = write (fildes, buf, nbyte);
2409
2410 if (rtnval == -1)
2411 {
2412 if (errno == EINTR)
2413 {
2414 #ifdef SYNC_INPUT
2415 2416
2417 process_pending_signals ();
2418 #endif
2419 continue;
2420 }
2421 else
2422 return (bytes_written ? bytes_written : -1);
2423 }
2424
2425 buf += rtnval;
2426 nbyte -= rtnval;
2427 bytes_written += rtnval;
2428 }
2429 return (bytes_written);
2430 }
2431
2432 #ifdef USG
2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446
2447
2448 2449 2450 2451
2452
2453 #ifndef MAXPATHLEN
2454
2455 #define MAXPATHLEN 1024
2456 #endif
2457
2458 #ifndef HAVE_GETWD
2459
2460 char *
2461 getwd (pathname)
2462 char *pathname;
2463 {
2464 char *npath, *spath;
2465 extern char *getcwd ();
2466
2467 BLOCK_INPUT;
2468 spath = npath = getcwd ((char *) 0, MAXPATHLEN);
2469 if (spath == 0)
2470 {
2471 UNBLOCK_INPUT;
2472 return spath;
2473 }
2474 2475
2476 while (*npath && *npath != '/')
2477 npath++;
2478 strcpy (pathname, npath);
2479 free (spath);
2480 UNBLOCK_INPUT;
2481 return pathname;
2482 }
2483
2484 #endif
2485
2486 2487 2488 2489 2490
2491
2492 #ifndef HAVE_RENAME
2493
2494 rename (from, to)
2495 const char *from;
2496 const char *to;
2497 {
2498 if (access (from, 0) == 0)
2499 {
2500 unlink (to);
2501 if (link (from, to) == 0)
2502 if (unlink (from) == 0)
2503 return (0);
2504 }
2505 return (-1);
2506 }
2507
2508 #endif
2509
2510
2511 #if defined(HPUX) && !defined(HAVE_PERROR)
2512
2513 2514
2515
2516 perror ()
2517 {
2518 }
2519 #endif
2520
2521 #ifndef HAVE_DUP2
2522
2523 2524 2525 2526 2527
2528
2529 dup2 (oldd, newd)
2530 int oldd;
2531 int newd;
2532 {
2533 register int fd, ret;
2534
2535 emacs_close (newd);
2536
2537 #ifdef F_DUPFD
2538 return fcntl (oldd, F_DUPFD, newd);
2539 #else
2540 fd = dup (old);
2541 if (fd == -1)
2542 return -1;
2543 if (fd == new)
2544 return new;
2545 ret = dup2 (old,new);
2546 emacs_close (fd);
2547 return ret;
2548 #endif
2549 }
2550
2551 #endif
2552
2553 2554 2555 2556 2557
2558
2559 #ifdef subprocesses
2560 #ifndef HAVE_GETTIMEOFDAY
2561 #ifdef HAVE_TIMEVAL
2562
2563
2564 int
2565 gettimeofday (tp, tzp)
2566 struct timeval *tp;
2567 struct timezone *tzp;
2568 {
2569 extern long time ();
2570
2571 tp->tv_sec = time ((long *)0);
2572 tp->tv_usec = 0;
2573 if (tzp != 0)
2574 tzp->tz_minuteswest = -1;
2575 return 0;
2576 }
2577
2578 #endif
2579 #endif
2580 #endif
2581
2582 2583 2584
2585
2586 void
2587 croak (badfunc)
2588 char *badfunc;
2589 {
2590 printf ("%s not yet implemented\r\n", badfunc);
2591 reset_all_sys_modes ();
2592 exit (1);
2593 }
2594
2595 #endif
2596
2597
2598
2599 #ifdef SYSV_SYSTEM_DIR
2600
2601 #include <dirent.h>
2602
2603 #if !defined (HAVE_CLOSEDIR)
2604
2605 int
2606 closedir (DIR *dirp )
2607 {
2608 int rtnval;
2609
2610 rtnval = emacs_close (dirp->dd_fd);
2611 xfree ((char *) dirp);
2612
2613 return rtnval;
2614 }
2615 #endif
2616 #endif
2617
2618
2619 int
2620 set_file_times (filename, atime, mtime)
2621 const char *filename;
2622 EMACS_TIME atime, mtime;
2623 {
2624 #ifdef HAVE_UTIMES
2625 struct timeval tv[2];
2626 tv[0] = atime;
2627 tv[1] = mtime;
2628 return utimes (filename, tv);
2629 #else
2630 struct utimbuf utb;
2631 utb.actime = EMACS_SECS (atime);
2632 utb.modtime = EMACS_SECS (mtime);
2633 return utime (filename, &utb);
2634 #endif
2635 }
2636
2637
2638
2639 #ifndef HAVE_MKDIR
2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653
2654
2655 2656 2657
2658 int
2659 mkdir (dpath, dmode)
2660 char *dpath;
2661 int dmode;
2662 {
2663 int cpid, status, fd;
2664 struct stat statbuf;
2665
2666 if (stat (dpath, &statbuf) == 0)
2667 {
2668 errno = EEXIST;
2669 return -1;
2670 }
2671
2672
2673 if (errno != ENOENT)
2674 return -1;
2675
2676 synch_process_alive = 1;
2677 switch (cpid = fork ())
2678 {
2679
2680 case -1:
2681 return (-1);
2682
2683 case 0:
2684 2685 2686 2687 2688 2689
2690 status = umask (0);
2691 status = umask (status | (0777 & ~dmode));
2692 fd = emacs_open ("/dev/null", O_RDWR, 0);
2693 if (fd >= 0)
2694 {
2695 dup2 (fd, 0);
2696 dup2 (fd, 1);
2697 dup2 (fd, 2);
2698 }
2699 execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
2700 _exit (-1);
2701
2702 default:
2703 wait_for_termination (cpid);
2704 }
2705
2706 if (synch_process_death != 0 || synch_process_retcode != 0
2707 || synch_process_termsig != 0)
2708 {
2709 errno = EIO;
2710 return -1;
2711 }
2712
2713 return 0;
2714 }
2715 #endif
2716
2717 #ifndef HAVE_RMDIR
2718 int
2719 rmdir (dpath)
2720 char *dpath;
2721 {
2722 int cpid, status, fd;
2723 struct stat statbuf;
2724
2725 if (stat (dpath, &statbuf) != 0)
2726 {
2727
2728 return -1;
2729 }
2730
2731 synch_process_alive = 1;
2732 switch (cpid = fork ())
2733 {
2734
2735 case -1:
2736 return (-1);
2737
2738 case 0:
2739 fd = emacs_open ("/dev/null", O_RDWR, 0);
2740 if (fd >= 0)
2741 {
2742 dup2 (fd, 0);
2743 dup2 (fd, 1);
2744 dup2 (fd, 2);
2745 }
2746 execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
2747 _exit (-1);
2748
2749 default:
2750 wait_for_termination (cpid);
2751 }
2752
2753 if (synch_process_death != 0 || synch_process_retcode != 0
2754 || synch_process_termsig != 0)
2755 {
2756 errno = EIO;
2757 return -1;
2758 }
2759
2760 return 0;
2761 }
2762 #endif
2763
2764
2765 #ifndef BSTRING
2766
2767 #ifndef bzero
2768
2769 void
2770 bzero (b, length)
2771 register char *b;
2772 register int length;
2773 {
2774 while (length-- > 0)
2775 *b++ = 0;
2776 }
2777
2778 #endif
2779 #endif
2780
2781 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
2782 #undef bcopy
2783
2784 2785
2786 bcopy (b1, b2, length)
2787 register char *b1;
2788 register char *b2;
2789 register int length;
2790 {
2791 while (length-- > 0)
2792 *b2++ = *b1++;
2793 }
2794 #endif
2795
2796 #ifndef BSTRING
2797 #ifndef bcmp
2798 int
2799 bcmp (b1, b2, length)
2800 register char *b1;
2801 register char *b2;
2802 register int length;
2803 {
2804 while (length-- > 0)
2805 if (*b1++ != *b2++)
2806 return 1;
2807
2808 return 0;
2809 }
2810 #endif
2811 #endif
2812
2813 #ifndef HAVE_STRSIGNAL
2814 char *
2815 strsignal (code)
2816 int code;
2817 {
2818 char *signame = 0;
2819
2820 if (0 <= code && code < NSIG)
2821 {
2822
2823 signame = (char *) sys_siglist[code];
2824 }
2825
2826 return signame;
2827 }
2828 #endif
2829
2830 #ifdef HAVE_TERMIOS
2831
2832 int serial_open (char *port)
2833 {
2834 int fd = -1;
2835
2836 fd = emacs_open ((char*) port,
2837 O_RDWR
2838 #ifdef O_NONBLOCK
2839 | O_NONBLOCK
2840 #else
2841 | O_NDELAY
2842 #endif
2843 #ifdef O_NOCTTY
2844 | O_NOCTTY
2845 #endif
2846 , 0);
2847 if (fd < 0)
2848 {
2849 error ("Could not open %s: %s",
2850 port, emacs_strerror (errno));
2851 }
2852 #ifdef TIOCEXCL
2853 ioctl (fd, TIOCEXCL, (char *) 0);
2854 #endif
2855
2856 return fd;
2857 }
2858 #endif
2859
2860 #ifdef HAVE_TERMIOS
2861
2862 #if !defined (HAVE_CFMAKERAW)
2863
2864
2865 static void cfmakeraw (struct termios *termios_p)
2866 {
2867 termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
2868 termios_p->c_oflag &= ~OPOST;
2869 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
2870 termios_p->c_cflag &= ~(CSIZE|PARENB);
2871 termios_p->c_cflag |= CS8;
2872 }
2873 #endif
2874
2875 #if !defined (HAVE_CFSETSPEED)
2876
2877 static int cfsetspeed (struct termios *termios_p, speed_t vitesse)
2878 {
2879 return (cfsetispeed (termios_p, vitesse)
2880 + cfsetospeed (termios_p, vitesse));
2881 }
2882 #endif
2883
2884
2885 void
2886 serial_configure (struct Lisp_Process *p,
2887 Lisp_Object contact)
2888 {
2889 Lisp_Object childp2 = Qnil;
2890 Lisp_Object tem = Qnil;
2891 struct termios attr;
2892 int err = -1;
2893 char summary[4] = "???";
2894
2895 childp2 = Fcopy_sequence (p->childp);
2896
2897
2898 err = tcgetattr (p->outfd, &attr);
2899 if (err != 0)
2900 error ("tcgetattr() failed: %s", emacs_strerror (errno));
2901 cfmakeraw (&attr);
2902 #if defined (CLOCAL)
2903 attr.c_cflag |= CLOCAL;
2904 #endif
2905 #if defined (CREAD)
2906 attr.c_cflag |= CREAD;
2907 #endif
2908
2909
2910 if (!NILP (Fplist_member (contact, QCspeed)))
2911 tem = Fplist_get (contact, QCspeed);
2912 else
2913 tem = Fplist_get (p->childp, QCspeed);
2914 CHECK_NUMBER (tem);
2915 err = cfsetspeed (&attr, XINT (tem));
2916 if (err != 0)
2917 error ("cfsetspeed(%d) failed: %s", XINT (tem), emacs_strerror (errno));
2918 childp2 = Fplist_put (childp2, QCspeed, tem);
2919
2920
2921 if (!NILP (Fplist_member (contact, QCbytesize)))
2922 tem = Fplist_get (contact, QCbytesize);
2923 else
2924 tem = Fplist_get (p->childp, QCbytesize);
2925 if (NILP (tem))
2926 tem = make_number (8);
2927 CHECK_NUMBER (tem);
2928 if (XINT (tem) != 7 && XINT (tem) != 8)
2929 error (":bytesize must be nil (8), 7, or 8");
2930 summary[0] = XINT(tem) + '0';
2931 #if defined (CSIZE) && defined (CS7) && defined (CS8)
2932 attr.c_cflag &= ~CSIZE;
2933 attr.c_cflag |= ((XINT (tem) == 7) ? CS7 : CS8);
2934 #else
2935
2936 if (XINT (tem) != 8)
2937 error ("Bytesize cannot be changed");
2938 #endif
2939 childp2 = Fplist_put (childp2, QCbytesize, tem);
2940
2941
2942 if (!NILP (Fplist_member (contact, QCparity)))
2943 tem = Fplist_get (contact, QCparity);
2944 else
2945 tem = Fplist_get (p->childp, QCparity);
2946 if (!NILP (tem) && !EQ (tem, Qeven) && !EQ (tem, Qodd))
2947 error (":parity must be nil (no parity), `even', or `odd'");
2948 #if defined (PARENB) && defined (PARODD) && defined (IGNPAR) && defined (INPCK)
2949 attr.c_cflag &= ~(PARENB | PARODD);
2950 attr.c_iflag &= ~(IGNPAR | INPCK);
2951 if (NILP (tem))
2952 {
2953 summary[1] = 'N';
2954 }
2955 else if (EQ (tem, Qeven))
2956 {
2957 summary[1] = 'E';
2958 attr.c_cflag |= PARENB;
2959 attr.c_iflag |= (IGNPAR | INPCK);
2960 }
2961 else if (EQ (tem, Qodd))
2962 {
2963 summary[1] = 'O';
2964 attr.c_cflag |= (PARENB | PARODD);
2965 attr.c_iflag |= (IGNPAR | INPCK);
2966 }
2967 #else
2968
2969 if (!NILP (tem))
2970 error ("Parity cannot be configured");
2971 #endif
2972 childp2 = Fplist_put (childp2, QCparity, tem);
2973
2974
2975 if (!NILP (Fplist_member (contact, QCstopbits)))
2976 tem = Fplist_get (contact, QCstopbits);
2977 else
2978 tem = Fplist_get (p->childp, QCstopbits);
2979 if (NILP (tem))
2980 tem = make_number (1);
2981 CHECK_NUMBER (tem);
2982 if (XINT (tem) != 1 && XINT (tem) != 2)
2983 error (":stopbits must be nil (1 stopbit), 1, or 2");
2984 summary[2] = XINT (tem) + '0';
2985 #if defined (CSTOPB)
2986 attr.c_cflag &= ~CSTOPB;
2987 if (XINT (tem) == 2)
2988 attr.c_cflag |= CSTOPB;
2989 #else
2990
2991 if (XINT (tem) != 1)
2992 error ("Stopbits cannot be configured");
2993 #endif
2994 childp2 = Fplist_put (childp2, QCstopbits, tem);
2995
2996
2997 if (!NILP (Fplist_member (contact, QCflowcontrol)))
2998 tem = Fplist_get (contact, QCflowcontrol);
2999 else
3000 tem = Fplist_get (p->childp, QCflowcontrol);
3001 if (!NILP (tem) && !EQ (tem, Qhw) && !EQ (tem, Qsw))
3002 error (":flowcontrol must be nil (no flowcontrol), `hw', or `sw'");
3003 #if defined (CRTSCTS)
3004 attr.c_cflag &= ~CRTSCTS;
3005 #endif
3006 #if defined (CNEW_RTSCTS)
3007 attr.c_cflag &= ~CNEW_RTSCTS;
3008 #endif
3009 #if defined (IXON) && defined (IXOFF)
3010 attr.c_iflag &= ~(IXON | IXOFF);
3011 #endif
3012 if (NILP (tem))
3013 {
3014
3015 }
3016 else if (EQ (tem, Qhw))
3017 {
3018 #if defined (CRTSCTS)
3019 attr.c_cflag |= CRTSCTS;
3020 #elif defined (CNEW_RTSCTS)
3021 attr.c_cflag |= CNEW_RTSCTS;
3022 #else
3023 error ("Hardware flowcontrol (RTS/CTS) not supported");
3024 #endif
3025 }
3026 else if (EQ (tem, Qsw))
3027 {
3028 #if defined (IXON) && defined (IXOFF)
3029 attr.c_iflag |= (IXON | IXOFF);
3030 #else
3031 error ("Software flowcontrol (XON/XOFF) not supported");
3032 #endif
3033 }
3034 childp2 = Fplist_put (childp2, QCflowcontrol, tem);
3035
3036
3037 err = tcsetattr (p->outfd, TCSANOW, &attr);
3038 if (err != 0)
3039 error ("tcsetattr() failed: %s", emacs_strerror (errno));
3040
3041 childp2 = Fplist_put (childp2, QCsummary, build_string (summary));
3042 p->childp = childp2;
3043
3044 }
3045 #endif
3046
3047
3048
3049 #ifdef HAVE_PROCFS
3050
3051
3052
3053 Lisp_Object
3054 list_system_processes ()
3055 {
3056 Lisp_Object procdir, match, proclist, next;
3057 struct gcpro gcpro1, gcpro2;
3058 register Lisp_Object tail;
3059
3060 GCPRO2 (procdir, match);
3061 3062 3063
3064 procdir = build_string ("/proc");
3065 match = build_string ("[0-9]+");
3066 proclist = directory_files_internal (procdir, Qnil, match, Qt, 0, Qnil);
3067
3068 3069
3070 for (tail = proclist; CONSP (tail); tail = next)
3071 {
3072 next = XCDR (tail);
3073 XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil));
3074 }
3075 UNGCPRO;
3076
3077 3078
3079 proclist = Fnreverse (proclist);
3080 return proclist;
3081 }
3082
3083 3084
3085 #elif !defined (WINDOWSNT) && !defined (MSDOS)
3086
3087 Lisp_Object
3088 list_system_processes ()
3089 {
3090 return Qnil;
3091 }
3092
3093 #endif
3094
3095 #ifdef GNU_LINUX
3096 static void
3097 time_from_jiffies (unsigned long long tval, long hz,
3098 time_t *sec, unsigned *usec)
3099 {
3100 unsigned long long ullsec;
3101
3102 *sec = tval / hz;
3103 ullsec = *sec;
3104 tval -= ullsec * hz;
3105
3106 if (hz <= 1000000)
3107 *usec = tval * 1000000 / hz;
3108 else
3109 *usec = tval / (hz / 1000000);
3110 }
3111
3112 static Lisp_Object
3113 ltime_from_jiffies (unsigned long long tval, long hz)
3114 {
3115 time_t sec;
3116 unsigned usec;
3117
3118 time_from_jiffies (tval, hz, &sec, &usec);
3119
3120 return list3 (make_number ((sec >> 16) & 0xffff),
3121 make_number (sec & 0xffff),
3122 make_number (usec));
3123 }
3124
3125 static void
3126 get_up_time (time_t *sec, unsigned *usec)
3127 {
3128 FILE *fup;
3129
3130 *sec = *usec = 0;
3131
3132 BLOCK_INPUT;
3133 fup = fopen ("/proc/uptime", "r");
3134
3135 if (fup)
3136 {
3137 double uptime, idletime;
3138
3139 3140 3141
3142 if (2 <= fscanf (fup, "%lf %lf", &uptime, &idletime))
3143 {
3144 *sec = uptime;
3145 *usec = (uptime - *sec) * 1000000;
3146 }
3147 fclose (fup);
3148 }
3149 UNBLOCK_INPUT;
3150 }
3151
3152 #define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
3153 #define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12))
3154
3155 static Lisp_Object
3156 procfs_ttyname (int rdev)
3157 {
3158 FILE *fdev = NULL;
3159 char name[PATH_MAX];
3160
3161 BLOCK_INPUT;
3162 fdev = fopen ("/proc/tty/drivers", "r");
3163
3164 if (fdev)
3165 {
3166 unsigned major;
3167 unsigned long minor_beg, minor_end;
3168 char minor[25];
3169 char *endp;
3170
3171 while (!feof (fdev) && !ferror (fdev))
3172 {
3173 if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor)
3174 && major == MAJOR (rdev))
3175 {
3176 minor_beg = strtoul (minor, &endp, 0);
3177 if (*endp == '\0')
3178 minor_end = minor_beg;
3179 else if (*endp == '-')
3180 minor_end = strtoul (endp + 1, &endp, 0);
3181 else
3182 continue;
3183
3184 if (MINOR (rdev) >= minor_beg && MINOR (rdev) <= minor_end)
3185 {
3186 sprintf (name + strlen (name), "%u", MINOR (rdev));
3187 break;
3188 }
3189 }
3190 }
3191 fclose (fdev);
3192 }
3193 UNBLOCK_INPUT;
3194 return build_string (name);
3195 }
3196
3197 static unsigned long
3198 procfs_get_total_memory (void)
3199 {
3200 FILE *fmem = NULL;
3201 unsigned long retval = 2 * 1024 * 1024;
3202
3203 BLOCK_INPUT;
3204 fmem = fopen ("/proc/meminfo", "r");
3205
3206 if (fmem)
3207 {
3208 unsigned long entry_value;
3209 char entry_name[20];
3210
3211 while (!feof (fmem) && !ferror (fmem))
3212 {
3213 if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value)
3214 && strcmp (entry_name, "MemTotal:") == 0)
3215 {
3216 retval = entry_value;
3217 break;
3218 }
3219 }
3220 fclose (fmem);
3221 }
3222 UNBLOCK_INPUT;
3223 return retval;
3224 }
3225
3226 Lisp_Object
3227 system_process_attributes (Lisp_Object pid)
3228 {
3229 char procfn[PATH_MAX], fn[PATH_MAX];
3230 struct stat st;
3231 struct passwd *pw;
3232 struct group *gr;
3233 long clocks_per_sec;
3234 char *procfn_end;
3235 char procbuf[1025], *p, *q;
3236 int fd;
3237 ssize_t nread;
3238 const char *cmd = NULL;
3239 char *cmdline = NULL;
3240 size_t cmdsize = 0, cmdline_size;
3241 unsigned char c;
3242 int proc_id, ppid, uid, gid, pgrp, sess, tty, tpgid, thcount;
3243 unsigned long long utime, stime, cutime, cstime, start;
3244 long priority, nice, rss;
3245 unsigned long minflt, majflt, cminflt, cmajflt, vsize;
3246 time_t sec;
3247 unsigned usec;
3248 EMACS_TIME tnow, tstart, tboot, telapsed;
3249 double pcpu, pmem;
3250 Lisp_Object attrs = Qnil;
3251 Lisp_Object cmd_str, decoded_cmd, tem;
3252 struct gcpro gcpro1, gcpro2;
3253 EMACS_INT uid_eint, gid_eint;
3254
3255 CHECK_NUMBER_OR_FLOAT (pid);
3256 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
3257 sprintf (procfn, "/proc/%u", proc_id);
3258 if (stat (procfn, &st) < 0)
3259 return attrs;
3260
3261 GCPRO2 (attrs, decoded_cmd);
3262
3263
3264 uid = st.st_uid;
3265
3266 uid_eint = uid;
3267 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs);
3268 BLOCK_INPUT;
3269 pw = getpwuid (uid);
3270 UNBLOCK_INPUT;
3271 if (pw)
3272 attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
3273
3274 gid = st.st_gid;
3275 gid_eint = gid;
3276 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs);
3277 BLOCK_INPUT;
3278 gr = getgrgid (gid);
3279 UNBLOCK_INPUT;
3280 if (gr)
3281 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3282
3283 strcpy (fn, procfn);
3284 procfn_end = fn + strlen (fn);
3285 strcpy (procfn_end, "/stat");
3286 fd = emacs_open (fn, O_RDONLY, 0);
3287 if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof(procbuf) - 1)) > 0)
3288 {
3289 procbuf[nread] = '\0';
3290 p = procbuf;
3291
3292 p = strchr (p, '(');
3293 if (p != NULL)
3294 {
3295 q = strrchr (p + 1, ')');
3296
3297 if (q != NULL)
3298 {
3299 cmd = p + 1;
3300 cmdsize = q - cmd;
3301 }
3302 }
3303 else
3304 q = NULL;
3305 if (cmd == NULL)
3306 {
3307 cmd = "???";
3308 cmdsize = 3;
3309 }
3310
3311 cmd_str = make_unibyte_string (cmd, cmdsize);
3312 decoded_cmd = code_convert_string_norecord (cmd_str,
3313 Vlocale_coding_system, 0);
3314 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3315
3316 if (q)
3317 {
3318 EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint;
3319 p = q + 2;
3320
3321 sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld",
3322 &c, &ppid, &pgrp, &sess, &tty, &tpgid,
3323 &minflt, &cminflt, &majflt, &cmajflt,
3324 &utime, &stime, &cutime, &cstime,
3325 &priority, &nice, &thcount, &start, &vsize, &rss);
3326 {
3327 char state_str[2];
3328
3329 state_str[0] = c;
3330 state_str[1] = '\0';
3331 tem = build_string (state_str);
3332 attrs = Fcons (Fcons (Qstate, tem), attrs);
3333 }
3334
3335 ppid_eint = ppid;
3336 pgrp_eint = pgrp;
3337 sess_eint = sess;
3338 tpgid_eint = tpgid;
3339 thcount_eint = thcount;
3340 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid_eint)), attrs);
3341 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp_eint)), attrs);
3342 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess_eint)), attrs);
3343 attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs);
3344 attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs);
3345 attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs);
3346 attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs);
3347 attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs);
3348 attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs);
3349 clocks_per_sec = sysconf (_SC_CLK_TCK);
3350 if (clocks_per_sec < 0)
3351 clocks_per_sec = 100;
3352 attrs = Fcons (Fcons (Qutime,
3353 ltime_from_jiffies (utime, clocks_per_sec)),
3354 attrs);
3355 attrs = Fcons (Fcons (Qstime,
3356 ltime_from_jiffies (stime, clocks_per_sec)),
3357 attrs);
3358 attrs = Fcons (Fcons (Qtime,
3359 ltime_from_jiffies (stime+utime, clocks_per_sec)),
3360 attrs);
3361 attrs = Fcons (Fcons (Qcutime,
3362 ltime_from_jiffies (cutime, clocks_per_sec)),
3363 attrs);
3364 attrs = Fcons (Fcons (Qcstime,
3365 ltime_from_jiffies (cstime, clocks_per_sec)),
3366 attrs);
3367 attrs = Fcons (Fcons (Qctime,
3368 ltime_from_jiffies (cstime+cutime, clocks_per_sec)),
3369 attrs);
3370 attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs);
3371 attrs = Fcons (Fcons (Qnice, make_number (nice)), attrs);
3372 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs);
3373 EMACS_GET_TIME (tnow);
3374 get_up_time (&sec, &usec);
3375 EMACS_SET_SECS (telapsed, sec);
3376 EMACS_SET_USECS (telapsed, usec);
3377 EMACS_SUB_TIME (tboot, tnow, telapsed);
3378 time_from_jiffies (start, clocks_per_sec, &sec, &usec);
3379 EMACS_SET_SECS (tstart, sec);
3380 EMACS_SET_USECS (tstart, usec);
3381 EMACS_ADD_TIME (tstart, tboot, tstart);
3382 attrs = Fcons (Fcons (Qstart,
3383 list3 (make_number
3384 ((EMACS_SECS (tstart) >> 16) & 0xffff),
3385 make_number
3386 (EMACS_SECS (tstart) & 0xffff),
3387 make_number
3388 (EMACS_USECS (tstart)))),
3389 attrs);
3390 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs);
3391 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs);
3392 EMACS_SUB_TIME (telapsed, tnow, tstart);
3393 attrs = Fcons (Fcons (Qetime,
3394 list3 (make_number
3395 ((EMACS_SECS (telapsed) >> 16) & 0xffff),
3396 make_number
3397 (EMACS_SECS (telapsed) & 0xffff),
3398 make_number
3399 (EMACS_USECS (telapsed)))),
3400 attrs);
3401 time_from_jiffies (utime + stime, clocks_per_sec, &sec, &usec);
3402 pcpu = (sec + usec / 1000000.0) / (EMACS_SECS (telapsed) + EMACS_USECS (telapsed) / 1000000.0);
3403 if (pcpu > 1.0)
3404 pcpu = 1.0;
3405 attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs);
3406 pmem = 4.0 * 100 * rss / procfs_get_total_memory ();
3407 if (pmem > 100)
3408 pmem = 100;
3409 attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
3410 }
3411 }
3412 if (fd >= 0)
3413 emacs_close (fd);
3414
3415
3416 strcpy (procfn_end, "/cmdline");
3417 fd = emacs_open (fn, O_RDONLY, 0);
3418 if (fd >= 0)
3419 {
3420 for (cmdline_size = 0; emacs_read (fd, &c, 1) == 1; cmdline_size++)
3421 {
3422 if (isspace (c) || c == '\\')
3423 cmdline_size++;
3424 }
3425 if (cmdline_size)
3426 {
3427 cmdline = xmalloc (cmdline_size + 1);
3428 lseek (fd, 0L, SEEK_SET);
3429 cmdline[0] = '\0';
3430 if ((nread = read (fd, cmdline, cmdline_size)) >= 0)
3431 cmdline[nread++] = '\0';
3432 else
3433 {
3434 3435 3436 3437
3438 nread = 0;
3439 }
3440
3441 for (p = cmdline + nread - 1; p > cmdline && !*p; p--)
3442 nread--;
3443 for (p = cmdline; p < cmdline + nread; p++)
3444 {
3445
3446 if (isspace (*p) || *p == '\\')
3447 {
3448 memmove (p + 1, p, nread - (p - cmdline));
3449 nread++;
3450 *p++ = '\\';
3451 }
3452 else if (*p == '\0')
3453 *p = ' ';
3454 }
3455 cmdline_size = nread;
3456 }
3457 if (!cmdline_size)
3458 {
3459 if (!cmd)
3460 cmd = "???";
3461 if (!cmdsize)
3462 cmdsize = strlen (cmd);
3463 cmdline_size = cmdsize + 2;
3464 cmdline = xmalloc (cmdline_size + 1);
3465 strcpy (cmdline, "[");
3466 strcat (strncat (cmdline, cmd, cmdsize), "]");
3467 }
3468 emacs_close (fd);
3469
3470 cmd_str = make_unibyte_string (cmdline, cmdline_size);
3471 decoded_cmd = code_convert_string_norecord (cmd_str,
3472 Vlocale_coding_system, 0);
3473 xfree (cmdline);
3474 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3475 }
3476
3477 UNGCPRO;
3478 return attrs;
3479 }
3480
3481 #elif defined (SOLARIS2) && defined (HAVE_PROCFS)
3482
3483 3484
3485 #if !defined (_LP64) && defined (_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
3486 #define PROCFS_FILE_OFFSET_BITS_HACK 1
3487 #undef _FILE_OFFSET_BITS
3488 #else
3489 #define PROCFS_FILE_OFFSET_BITS_HACK 0
3490 #endif
3491
3492 #include <procfs.h>
3493
3494 #if PROCFS_FILE_OFFSET_BITS_HACK == 1
3495 #define _FILE_OFFSET_BITS 64
3496 #endif
3497
3498 Lisp_Object
3499 system_process_attributes (Lisp_Object pid)
3500 {
3501 char procfn[PATH_MAX], fn[PATH_MAX];
3502 struct stat st;
3503 struct passwd *pw;
3504 struct group *gr;
3505 char *procfn_end;
3506 struct psinfo pinfo;
3507 int fd;
3508 ssize_t nread;
3509 int proc_id, uid, gid;
3510 Lisp_Object attrs = Qnil;
3511 Lisp_Object decoded_cmd, tem;
3512 struct gcpro gcpro1, gcpro2;
3513 EMACS_INT uid_eint, gid_eint;
3514
3515 CHECK_NUMBER_OR_FLOAT (pid);
3516 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
3517 sprintf (procfn, "/proc/%u", proc_id);
3518 if (stat (procfn, &st) < 0)
3519 return attrs;
3520
3521 GCPRO2 (attrs, decoded_cmd);
3522
3523
3524 uid = st.st_uid;
3525
3526 uid_eint = uid;
3527 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs);
3528 BLOCK_INPUT;
3529 pw = getpwuid (uid);
3530 UNBLOCK_INPUT;
3531 if (pw)
3532 attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
3533
3534 gid = st.st_gid;
3535 gid_eint = gid;
3536 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs);
3537 BLOCK_INPUT;
3538 gr = getgrgid (gid);
3539 UNBLOCK_INPUT;
3540 if (gr)
3541 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3542
3543 strcpy (fn, procfn);
3544 procfn_end = fn + strlen (fn);
3545 strcpy (procfn_end, "/psinfo");
3546 fd = emacs_open (fn, O_RDONLY, 0);
3547 if (fd >= 0
3548 && (nread = read (fd, (char*)&pinfo, sizeof(struct psinfo)) > 0))
3549 {
3550 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs);
3551 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs);
3552 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs);
3553
3554 {
3555 char state_str[2];
3556 state_str[0] = pinfo.pr_lwp.pr_sname;
3557 state_str[1] = '\0';
3558 tem = build_string (state_str);
3559 attrs = Fcons (Fcons (Qstate, tem), attrs);
3560 }
3561
3562 3563
3564
3565
3566
3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577
3578
3579 attrs = Fcons (Fcons (Qtime,
3580 list3 (make_number (pinfo.pr_time.tv_sec >> 16),
3581 make_number (pinfo.pr_time.tv_sec & 0xffff),
3582 make_number (pinfo.pr_time.tv_nsec))),
3583 attrs);
3584
3585 attrs = Fcons (Fcons (Qctime,
3586 list3 (make_number (pinfo.pr_ctime.tv_sec >> 16),
3587 make_number (pinfo.pr_ctime.tv_sec & 0xffff),
3588 make_number (pinfo.pr_ctime.tv_nsec))),
3589 attrs);
3590
3591 attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
3592 attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
3593 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs);
3594
3595 attrs = Fcons (Fcons (Qstart,
3596 list3 (make_number (pinfo.pr_start.tv_sec >> 16),
3597 make_number (pinfo.pr_start.tv_sec & 0xffff),
3598 make_number (pinfo.pr_start.tv_nsec))),
3599 attrs);
3600 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs);
3601 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs);
3602
3603
3604 attrs = Fcons (Fcons (Qpcpu, (pinfo.pr_pctcpu * 100.0) / (double)0x8000), attrs);
3605 attrs = Fcons (Fcons (Qpmem, (pinfo.pr_pctmem * 100.0) / (double)0x8000), attrs);
3606
3607 decoded_cmd
3608 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_fname,
3609 strlen (pinfo.pr_fname)),
3610 Vlocale_coding_system, 0);
3611 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3612 decoded_cmd
3613 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_psargs,
3614 strlen (pinfo.pr_psargs)),
3615 Vlocale_coding_system, 0);
3616 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3617 }
3618
3619 if (fd >= 0)
3620 emacs_close (fd);
3621
3622 UNGCPRO;
3623 return attrs;
3624 }
3625
3626 3627
3628 #elif !defined (WINDOWSNT) && !defined (MSDOS)
3629
3630 Lisp_Object
3631 system_process_attributes (Lisp_Object pid)
3632 {
3633 return Qnil;
3634 }
3635
3636 #endif
3637
3638
3639 3640