X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/a9650e970d9f515b4b64bd0009d28125b4276b63..8833692b29ba11c34413d6793cf6d222ccdd930b:/src/sysdep.c diff --git a/src/sysdep.c b/src/sysdep.c index 418c50d5e7..53affbf3db 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -6,8 +6,8 @@ This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -130,6 +130,35 @@ static const int baud_convert[] = 1800, 2400, 4800, 9600, 19200, 38400 }; +/* If FD is not already open, arrange for it to be open with FLAGS. */ +static void +force_open (int fd, int flags) +{ + if (dup2 (fd, fd) < 0 && errno == EBADF) + { + int n = open (NULL_DEVICE, flags); + if (n < 0 || (fd != n && (dup2 (n, fd) < 0 || emacs_close (n) != 0))) + { + emacs_perror (NULL_DEVICE); + exit (EXIT_FAILURE); + } + } +} + +/* Make sure stdin, stdout, and stderr are open to something, so that + their file descriptors are not hijacked by later system calls. */ +void +init_standard_fds (void) +{ + /* Open stdin for *writing*, and stdout and stderr for *reading*. + That way, any attempt to do normal I/O will result in an error, + just as if the files were closed, and the file descriptors will + not be reused by later opens. */ + force_open (STDIN_FILENO, O_WRONLY); + force_open (STDOUT_FILENO, O_RDONLY); + force_open (STDERR_FILENO, O_RDONLY); +} + /* Return the current working directory. The result should be freed with 'free'. Return NULL on errors. */ char * @@ -1408,6 +1437,12 @@ setup_pty (int fd) void init_system_name (void) { + if (!build_details) + { + /* Set system-name to nil so that the build is deterministic. */ + Vsystem_name = Qnil; + return; + } char *hostname_alloc = NULL; char *hostname; #ifndef HAVE_GETHOSTNAME @@ -2113,7 +2148,7 @@ init_random (void) { bool success = false; #ifndef WINDOWSNT - int fd = emacs_open ("/dev/urandom", O_RDONLY | O_BINARY, 0); + int fd = emacs_open ("/dev/urandom", O_RDONLY, 0); if (0 <= fd) { success = emacs_read (fd, &v, sizeof v) == sizeof v; @@ -2293,7 +2328,6 @@ emacs_fopen (char const *file, char const *mode) switch (*m++) { case '+': omode = O_RDWR; break; - case 'b': bflag = O_BINARY; break; case 't': bflag = O_TEXT; break; default: /* Ignore. */ break; } @@ -3015,7 +3049,7 @@ system_process_attributes (Lisp_Object pid) struct timespec tnow, tstart, tboot, telapsed, us_time; double pcpu, pmem; Lisp_Object attrs = Qnil; - Lisp_Object cmd_str, decoded_cmd; + Lisp_Object decoded_cmd; ptrdiff_t count; CHECK_NUMBER_OR_FLOAT (pid); @@ -3072,7 +3106,7 @@ system_process_attributes (Lisp_Object pid) else q = NULL; /* Command name is encoded in locale-coding-system; decode it. */ - cmd_str = make_unibyte_string (cmd, cmdsize); + AUTO_STRING_WITH_LEN (cmd_str, cmd, cmdsize); decoded_cmd = code_convert_string_norecord (cmd_str, Vlocale_coding_system, 0); attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); @@ -3205,7 +3239,7 @@ system_process_attributes (Lisp_Object pid) sprintf (cmdline, "[%.*s]", cmdsize, cmd); } /* Command line is encoded in locale-coding-system; decode it. */ - cmd_str = make_unibyte_string (q, nread); + AUTO_STRING_WITH_LEN (cmd_str, q, nread); decoded_cmd = code_convert_string_norecord (cmd_str, Vlocale_coding_system, 0); unbind_to (count, Qnil); @@ -3340,13 +3374,13 @@ system_process_attributes (Lisp_Object pid) make_float (100.0 / 0x8000 * pinfo.pr_pctmem)), attrs); - decoded_cmd = (code_convert_string_norecord - (build_unibyte_string (pinfo.pr_fname), - Vlocale_coding_system, 0)); + AUTO_STRING (fname, pinfo.pr_fname); + decoded_cmd = code_convert_string_norecord (fname, + Vlocale_coding_system, 0); attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs); - decoded_cmd = (code_convert_string_norecord - (build_unibyte_string (pinfo.pr_psargs), - Vlocale_coding_system, 0)); + AUTO_STRING (psargs, pinfo.pr_psargs); + decoded_cmd = code_convert_string_norecord (psargs, + Vlocale_coding_system, 0); attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); } unbind_to (count, Qnil); @@ -3411,9 +3445,8 @@ system_process_attributes (Lisp_Object pid) if (gr) attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); - decoded_comm = (code_convert_string_norecord - (build_unibyte_string (proc.ki_comm), - Vlocale_coding_system, 0)); + AUTO_STRING (comm, proc.ki_comm); + decoded_comm = code_convert_string_norecord (comm, Vlocale_coding_system, 0); attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); { @@ -3524,10 +3557,9 @@ system_process_attributes (Lisp_Object pid) args[i] = ' '; } - decoded_comm = - (code_convert_string_norecord - (build_unibyte_string (args), - Vlocale_coding_system, 0)); + AUTO_STRING (comm, args); + decoded_comm = code_convert_string_norecord (comm, + Vlocale_coding_system, 0); attrs = Fcons (Fcons (Qargs, decoded_comm), attrs); } @@ -3535,6 +3567,146 @@ system_process_attributes (Lisp_Object pid) return attrs; } +#elif defined DARWIN_OS + +static struct timespec +timeval_to_timespec (struct timeval t) +{ + return make_timespec (t.tv_sec, t.tv_usec * 1000); +} + +static Lisp_Object +make_lisp_timeval (struct timeval t) +{ + return make_lisp_time (timeval_to_timespec (t)); +} + +Lisp_Object +system_process_attributes (Lisp_Object pid) +{ + int proc_id; + int pagesize = getpagesize (); + unsigned long npages; + int fscale; + struct passwd *pw; + struct group *gr; + char *ttyname; + size_t len; + char args[MAXPATHLEN]; + struct timeval starttime; + struct timespec t, now; + struct rusage *rusage; + dev_t tdev; + uid_t uid; + gid_t gid; + + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID}; + struct kinfo_proc proc; + size_t proclen = sizeof proc; + + Lisp_Object attrs = Qnil; + Lisp_Object decoded_comm; + + CHECK_NUMBER_OR_FLOAT (pid); + CONS_TO_INTEGER (pid, int, proc_id); + mib[3] = proc_id; + + if (sysctl (mib, 4, &proc, &proclen, NULL, 0) != 0) + return attrs; + + uid = proc.kp_eproc.e_ucred.cr_uid; + attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs); + + block_input (); + pw = getpwuid (uid); + unblock_input (); + if (pw) + attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs); + + gid = proc.kp_eproc.e_pcred.p_svgid; + attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs); + + block_input (); + gr = getgrgid (gid); + unblock_input (); + if (gr) + attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs); + + decoded_comm = (code_convert_string_norecord + (build_unibyte_string (proc.kp_proc.p_comm), + Vlocale_coding_system, 0)); + + attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs); + { + char state[2] = {'\0', '\0'}; + switch (proc.kp_proc.p_stat) + { + case SRUN: + state[0] = 'R'; + break; + + case SSLEEP: + state[0] = 'S'; + break; + + case SZOMB: + state[0] = 'Z'; + break; + + case SSTOP: + state[0] = 'T'; + break; + + case SIDL: + state[0] = 'I'; + break; + } + attrs = Fcons (Fcons (Qstate, build_string (state)), attrs); + } + + attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (proc.kp_eproc.e_ppid)), + attrs); + attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (proc.kp_eproc.e_pgid)), + attrs); + + tdev = proc.kp_eproc.e_tdev; + block_input (); + ttyname = tdev == NODEV ? NULL : devname (tdev, S_IFCHR); + unblock_input (); + if (ttyname) + attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs); + + attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (proc.kp_eproc.e_tpgid)), + attrs); + + rusage = proc.kp_proc.p_ru; + if (rusage) + { + attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (rusage->ru_minflt)), + attrs); + attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (rusage->ru_majflt)), + attrs); + + attrs = Fcons (Fcons (Qutime, make_lisp_timeval (rusage->ru_utime)), + attrs); + attrs = Fcons (Fcons (Qstime, make_lisp_timeval (rusage->ru_stime)), + attrs); + t = timespec_add (timeval_to_timespec (rusage->ru_utime), + timeval_to_timespec (rusage->ru_stime)); + attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs); + } + + starttime = proc.kp_proc.p_starttime; + attrs = Fcons (Fcons (Qnice, make_number (proc.kp_proc.p_nice)), attrs); + attrs = Fcons (Fcons (Qstart, make_lisp_timeval (starttime)), attrs); + + now = current_timespec (); + t = timespec_sub (now, timeval_to_timespec (starttime)); + attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs); + + return attrs; +} + /* The WINDOWSNT implementation is in w32.c. The MSDOS implementation is in dosfns.c. */ #elif !defined (WINDOWSNT) && !defined (MSDOS)