static int lock_file_1 (char *lfname, int force) { int err; int symlink_errno; USE_SAFE_ALLOCA; /* Call this first because it can GC. */ printmax_t boot = get_boot_time (); Lisp_Object luser_name = Fuser_login_name (Qnil); char const *user_name = STRINGP (luser_name) ? SSDATA (luser_name) : ""; Lisp_Object lhost_name = Fsystem_name (); char const *host_name = STRINGP (lhost_name) ? SSDATA (lhost_name) : ""; ptrdiff_t lock_info_size = (strlen (user_name) + strlen (host_name) + 2 * INT_STRLEN_BOUND (printmax_t) + sizeof "@.:"); char *lock_info_str = SAFE_ALLOCA (lock_info_size); printmax_t pid = getpid (); esprintf (lock_info_str, boot ? "%s@%s.%"pMd":%"pMd : "%s@%s.%"pMd, user_name, host_name, pid, boot); err = symlink (lock_info_str, lfname); if (errno == EEXIST && force) { unlink (lfname); err = symlink (lock_info_str, lfname); } symlink_errno = errno; SAFE_FREE (); errno = symlink_errno; return err == 0; }
char * __attribute_warn_unused_result__ anytostr (inttype i, char *buf) { verify (TYPE_SIGNED (inttype) == inttype_is_signed); char *p = buf + INT_STRLEN_BOUND (inttype); *p = 0; #if inttype_is_signed if (i < 0) { do *--p = '0' - i % 10; while ((i /= 10) != 0); *--p = '-'; } else #endif { do *--p = '0' + i % 10; while ((i /= 10) != 0); } return p; }
char * rpl_strerror (int n) { char *result = strerror (n); if (result == NULL || result[0] == '\0') { static char const fmt[] = "Unknown error (%d)"; static char mesg[sizeof fmt + INT_STRLEN_BOUND (n)]; sprintf (mesg, fmt, n); return mesg; } return result; }
static void print_context_label (char const *mark, struct file_data *inf, char const *label) { if (label) fprintf (outfile, "%s %s\n", mark, label); else { char buf[MAX (INT_STRLEN_BOUND (int) + 32, INT_STRLEN_BOUND (time_t) + 11)]; struct tm const *tm = localtime (&inf->stat.st_mtime); int nsec = TIMESPEC_NS (inf->stat.st_mtim); if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, 0, nsec))) { long sec = inf->stat.st_mtime; verify (info_preserved, sizeof inf->stat.st_mtime <= sizeof sec); sprintf (buf, "%ld.%.9d", sec, nsec); } fprintf (outfile, "%s %s\t%s\n", mark, inf->name, buf); } }
char * __attribute_warn_unused_result__ anytostr (inttype i, char *buf) { char *p = buf + INT_STRLEN_BOUND (inttype); *p = 0; if (i < 0) { do *--p = '0' - i % 10; while ((i /= 10) != 0); *--p = '-'; } else { do *--p = '0' + i % 10; while ((i /= 10) != 0); } return p; }
char * inttostr (inttype i, char *buf) { char *p = buf + INT_STRLEN_BOUND (inttype); *p = 0; if (i < 0) { do *--p = '0' - i % 10; while ((i /= 10) != 0); *--p = '-'; } else { do *--p = '0' + i % 10; while ((i /= 10) != 0); } return p; }
static void print_context_label (char const *mark, struct file_data *inf, char const *name, char const *label) { if (label) fprintf (outfile, "%s %s\n", mark, label); else { char buf[MAX (INT_STRLEN_BOUND (int) + 32, INT_STRLEN_BOUND (time_t) + 11)]; struct tm const *tm = localtime (&inf->stat.st_mtime); int nsec = get_stat_mtime_ns (&inf->stat); if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, 0, nsec))) { verify (TYPE_IS_INTEGER (time_t)); if (LONG_MIN <= TYPE_MINIMUM (time_t) && TYPE_MAXIMUM (time_t) <= LONG_MAX) { long int sec = inf->stat.st_mtime; sprintf (buf, "%ld.%.9d", sec, nsec); } else if (TYPE_MAXIMUM (time_t) <= INTMAX_MAX) { intmax_t sec = inf->stat.st_mtime; sprintf (buf, "%"PRIdMAX".%.9d", sec, nsec); } else { uintmax_t sec = inf->stat.st_mtime; sprintf (buf, "%"PRIuMAX".%.9d", sec, nsec); } } fprintf (outfile, "%s %s\t%s\n", mark, name, buf); } }
char * strerror (int n) #undef strerror { static char buf[STACKBUF_LEN]; size_t len; /* Cast away const, due to the historical signature of strerror; callers should not be modifying the string. */ const char *msg = strerror_override (n); if (msg) return (char *) msg; msg = strerror (n); /* Our strerror_r implementation might use the system's strerror buffer, so all other clients of strerror have to see the error copied into a buffer that we manage. This is not thread-safe, even if the system strerror is, but portable programs shouldn't be using strerror if they care about thread-safety. */ if (!msg || !*msg) { static char const fmt[] = "Unknown error %d"; verify (sizeof buf >= sizeof (fmt) + INT_STRLEN_BOUND (n)); sprintf (buf, fmt, n); errno = EINVAL; return buf; } /* Fix STACKBUF_LEN if this ever aborts. */ len = strlen (msg); if (sizeof buf <= len) abort (); memcpy (buf, msg, len + 1); return buf; }
char * rpl_strerror (int n) { char const *msg = NULL; /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */ switch (n) { # if GNULIB_defined_ETXTBSY case ETXTBSY: msg = "Text file busy"; break; # endif # if GNULIB_defined_ESOCK /* native Windows platforms */ /* EWOULDBLOCK is the same as EAGAIN. */ case EINPROGRESS: msg = "Operation now in progress"; break; case EALREADY: msg = "Operation already in progress"; break; case ENOTSOCK: msg = "Socket operation on non-socket"; break; case EDESTADDRREQ: msg = "Destination address required"; break; case EMSGSIZE: msg = "Message too long"; break; case EPROTOTYPE: msg = "Protocol wrong type for socket"; break; case ENOPROTOOPT: msg = "Protocol not available"; break; case EPROTONOSUPPORT: msg = "Protocol not supported"; break; case ESOCKTNOSUPPORT: msg = "Socket type not supported"; break; case EOPNOTSUPP: msg = "Operation not supported"; break; case EPFNOSUPPORT: msg = "Protocol family not supported"; break; case EAFNOSUPPORT: msg = "Address family not supported by protocol"; break; case EADDRINUSE: msg = "Address already in use"; break; case EADDRNOTAVAIL: msg = "Cannot assign requested address"; break; case ENETDOWN: msg = "Network is down"; break; case ENETUNREACH: msg = "Network is unreachable"; break; case ENETRESET: msg = "Network dropped connection on reset"; break; case ECONNABORTED: msg = "Software caused connection abort"; break; case ECONNRESET: msg = "Connection reset by peer"; break; case ENOBUFS: msg = "No buffer space available"; break; case EISCONN: msg = "Transport endpoint is already connected"; break; case ENOTCONN: msg = "Transport endpoint is not connected"; break; case ESHUTDOWN: msg = "Cannot send after transport endpoint shutdown"; break; case ETOOMANYREFS: msg = "Too many references: cannot splice"; break; case ETIMEDOUT: msg = "Connection timed out"; break; case ECONNREFUSED: msg = "Connection refused"; break; case ELOOP: msg = "Too many levels of symbolic links"; break; case EHOSTDOWN: msg = "Host is down"; break; case EHOSTUNREACH: msg = "No route to host"; break; case EPROCLIM: msg = "Too many processes"; break; case EUSERS: msg = "Too many users"; break; case EDQUOT: msg = "Disk quota exceeded"; break; case ESTALE: msg = "Stale NFS file handle"; break; case EREMOTE: msg = "Object is remote"; break; # if HAVE_WINSOCK2_H /* WSA_INVALID_HANDLE maps to EBADF */ /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ /* WSA_INVALID_PARAMETER maps to EINVAL */ case WSA_OPERATION_ABORTED: msg = "Overlapped operation aborted"; break; case WSA_IO_INCOMPLETE: msg = "Overlapped I/O event object not in signaled state"; break; case WSA_IO_PENDING: msg = "Overlapped operations will complete later"; break; /* WSAEINTR maps to EINTR */ /* WSAEBADF maps to EBADF */ /* WSAEACCES maps to EACCES */ /* WSAEFAULT maps to EFAULT */ /* WSAEINVAL maps to EINVAL */ /* WSAEMFILE maps to EMFILE */ /* WSAEWOULDBLOCK maps to EWOULDBLOCK */ /* WSAEINPROGRESS is EINPROGRESS */ /* WSAEALREADY is EALREADY */ /* WSAENOTSOCK is ENOTSOCK */ /* WSAEDESTADDRREQ is EDESTADDRREQ */ /* WSAEMSGSIZE is EMSGSIZE */ /* WSAEPROTOTYPE is EPROTOTYPE */ /* WSAENOPROTOOPT is ENOPROTOOPT */ /* WSAEPROTONOSUPPORT is EPROTONOSUPPORT */ /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */ /* WSAEOPNOTSUPP is EOPNOTSUPP */ /* WSAEPFNOSUPPORT is EPFNOSUPPORT */ /* WSAEAFNOSUPPORT is EAFNOSUPPORT */ /* WSAEADDRINUSE is EADDRINUSE */ /* WSAEADDRNOTAVAIL is EADDRNOTAVAIL */ /* WSAENETDOWN is ENETDOWN */ /* WSAENETUNREACH is ENETUNREACH */ /* WSAENETRESET is ENETRESET */ /* WSAECONNABORTED is ECONNABORTED */ /* WSAECONNRESET is ECONNRESET */ /* WSAENOBUFS is ENOBUFS */ /* WSAEISCONN is EISCONN */ /* WSAENOTCONN is ENOTCONN */ /* WSAESHUTDOWN is ESHUTDOWN */ /* WSAETOOMANYREFS is ETOOMANYREFS */ /* WSAETIMEDOUT is ETIMEDOUT */ /* WSAECONNREFUSED is ECONNREFUSED */ /* WSAELOOP is ELOOP */ /* WSAENAMETOOLONG maps to ENAMETOOLONG */ /* WSAEHOSTDOWN is EHOSTDOWN */ /* WSAEHOSTUNREACH is EHOSTUNREACH */ /* WSAENOTEMPTY maps to ENOTEMPTY */ /* WSAEPROCLIM is EPROCLIM */ /* WSAEUSERS is EUSERS */ /* WSAEDQUOT is EDQUOT */ /* WSAESTALE is ESTALE */ /* WSAEREMOTE is EREMOTE */ case WSASYSNOTREADY: msg = "Network subsystem is unavailable"; break; case WSAVERNOTSUPPORTED: msg = "Winsock.dll version out of range"; break; case WSANOTINITIALISED: msg = "Successful WSAStartup not yet performed"; break; case WSAEDISCON: msg = "Graceful shutdown in progress"; break; case WSAENOMORE: case WSA_E_NO_MORE: msg = "No more results"; break; case WSAECANCELLED: case WSA_E_CANCELLED: msg = "Call was canceled"; break; case WSAEINVALIDPROCTABLE: msg = "Procedure call table is invalid"; break; case WSAEINVALIDPROVIDER: msg = "Service provider is invalid"; break; case WSAEPROVIDERFAILEDINIT: msg = "Service provider failed to initialize"; break; case WSASYSCALLFAILURE: msg = "System call failure"; break; case WSASERVICE_NOT_FOUND: msg = "Service not found"; break; case WSATYPE_NOT_FOUND: msg = "Class type not found"; break; case WSAEREFUSED: msg = "Database query was refused"; break; case WSAHOST_NOT_FOUND: msg = "Host not found"; break; case WSATRY_AGAIN: msg = "Nonauthoritative host not found"; break; case WSANO_RECOVERY: msg = "Nonrecoverable error"; break; case WSANO_DATA: msg = "Valid name, no data record of requested type"; break; /* WSA_QOS_* omitted */ # endif # endif # if GNULIB_defined_ENOMSG case ENOMSG: msg = "No message of desired type"; break; # endif # if GNULIB_defined_EIDRM case EIDRM: msg = "Identifier removed"; break; # endif # if GNULIB_defined_ENOLINK case ENOLINK: msg = "Link has been severed"; break; # endif # if GNULIB_defined_EPROTO case EPROTO: msg = "Protocol error"; break; # endif # if GNULIB_defined_EMULTIHOP case EMULTIHOP: msg = "Multihop attempted"; break; # endif # if GNULIB_defined_EBADMSG case EBADMSG: msg = "Bad message"; break; # endif # if GNULIB_defined_EOVERFLOW case EOVERFLOW: msg = "Value too large for defined data type"; break; # endif # if GNULIB_defined_ENOTSUP case ENOTSUP: msg = "Not supported"; break; # endif # if GNULIB_defined_ESTALE case ESTALE: msg = "Stale NFS file handle"; break; # endif # if GNULIB_defined_EDQUOT case EDQUOT: msg = "Disk quota exceeded"; break; # endif # if GNULIB_defined_ECANCELED case ECANCELED: msg = "Operation canceled"; break; # endif } if (msg) return (char *) msg; { char *result = strerror (n); if (result == NULL || result[0] == '\0') { static char const fmt[] = "Unknown error (%d)"; static char msg_buf[sizeof fmt + INT_STRLEN_BOUND (n)]; sprintf (msg_buf, fmt, n); return msg_buf; } return result; } }
** abstraction : a stopwatch ** operations: reset_watch, get_time */ #define INLINE EXTERN_INLINE #include <config.h> #include <inttypes.h> #include <stdio.h> #include <intprops.h> #include <systime.h> static struct timespec TV1; static int watch_not_started = 1; /* flag */ static char time_string[INT_STRLEN_BOUND (uintmax_t) + sizeof "." + LOG10_TIMESPEC_RESOLUTION]; /* Reset the stopwatch to zero. */ static void reset_watch (void) { TV1 = current_timespec (); watch_not_started = 0; } /* This call returns the time since the last reset_watch call. The time is returned as a string with the format <seconds>.<nanoseconds> If reset_watch was not called yet, exit. */
void lock_file (Lisp_Object fn) { register Lisp_Object attack, orig_fn, encoded_fn; register char *lfname, *locker; ptrdiff_t locker_size; lock_info_type lock_info; printmax_t pid; struct gcpro gcpro1; USE_SAFE_ALLOCA; /* Don't do locking if the user has opted out. */ if (! create_lockfiles) return; /* Don't do locking while dumping Emacs. Uncompressing wtmp files uses call-process, which does not work in an uninitialized Emacs. */ if (! NILP (Vpurify_flag)) return; orig_fn = fn; GCPRO1 (fn); fn = Fexpand_file_name (fn, Qnil); encoded_fn = ENCODE_FILE (fn); /* Create the name of the lock-file for file fn */ MAKE_LOCK_NAME (lfname, encoded_fn); /* See if this file is visited and has changed on disk since it was visited. */ { register Lisp_Object subject_buf; subject_buf = get_truename_buffer (orig_fn); if (!NILP (subject_buf) && NILP (Fverify_visited_file_modtime (subject_buf)) && !NILP (Ffile_exists_p (fn))) call1 (intern ("ask-user-about-supersession-threat"), fn); } UNGCPRO; /* Try to lock the lock. */ if (lock_if_free (&lock_info, lfname) <= 0) /* Return now if we have locked it, or if lock creation failed */ return; /* Else consider breaking the lock */ locker_size = (strlen (lock_info.user) + strlen (lock_info.host) + INT_STRLEN_BOUND (printmax_t) + sizeof "@ (pid )"); locker = SAFE_ALLOCA (locker_size); pid = lock_info.pid; esprintf (locker, "%s@%s (pid %"pMd")", lock_info.user, lock_info.host, pid); FREE_LOCK_INFO (lock_info); attack = call2 (intern ("ask-user-about-lock"), fn, build_string (locker)); SAFE_FREE (); if (!NILP (attack)) /* User says take the lock */ { lock_file_1 (lfname, 1); return; } /* User says ignore the lock */ }
/* * Insert the line number (of the given position) into the line buffer. */ void plinenum(off_t pos) { LINENUM linenum = 0; int i; if (linenums == OPT_ONPLUS) { /* * Get the line number and put it in the current line. * {{ Note: since find_linenum calls forw_raw_line, * it may seek in the input file, requiring the caller * of plinenum to re-seek if necessary. }} * {{ Since forw_raw_line modifies linebuf, we must * do this first, before storing anything in linebuf. }} */ linenum = find_linenum(pos); } /* * Display a status column if the -J option is set. */ if (status_col) { linebuf[curr] = ' '; if (start_attnpos != -1 && pos >= start_attnpos && pos < end_attnpos) attr[curr] = AT_NORMAL|AT_HILITE; else attr[curr] = AT_NORMAL; curr++; column++; } /* * Display the line number at the start of each line * if the -N option is set. */ if (linenums == OPT_ONPLUS) { char buf[INT_STRLEN_BOUND(pos) + 2]; int n; linenumtoa(linenum, buf); n = strlen(buf); if (n < MIN_LINENUM_WIDTH) n = MIN_LINENUM_WIDTH; sprintf(linebuf+curr, "%*s ", n, buf); n++; /* One space after the line number. */ for (i = 0; i < n; i++) attr[curr+i] = AT_NORMAL; curr += n; column += n; lmargin += n; } /* * Append enough spaces to bring us to the lmargin. */ while (column < lmargin) { linebuf[curr] = ' '; attr[curr++] = AT_NORMAL; column++; } }