sys/unix/*.c formatting and PANICTRACE fix

I started out just reformatting the function header for regularize()
but ended up doing miscellaneous other stuff, including some code
changes.  I think the CHDIR code is a bit cleaner now, but shouldn't
have any differences in behavior.

Along the way I noticed that 'nethack -dpath' or 'nethack -d path'
modifies argv[] before PANICTRACE attempted to save argv[0], so would
break having nethack invoke gdb to get a backtrace.  ('ARGV0' seems to
be unnecessary since 'hname' holds the same value, but I didn't get rid
of it....)
This commit is contained in:
PatR
2017-09-13 15:33:43 -07:00
parent 127f74bb24
commit cd8f028352
6 changed files with 127 additions and 91 deletions

View File

@@ -547,6 +547,8 @@ X11: color didn't work when the map was displayed as text rather than tiles
X11: use grayscale monster tiles for statues X11: use grayscale monster tiles for statues
X11/USE_XPM: [post-3.6.0 issue] the 'tiles' bug of incorrect total_tiles_used X11/USE_XPM: [post-3.6.0 issue] the 'tiles' bug of incorrect total_tiles_used
for STATUES_LOOK_LIKE_MONSTERS broke XPM manipulation of tiles data for STATUES_LOOK_LIKE_MONSTERS broke XPM manipulation of tiles data
PANICTRACE: PANICTRACE_GDB used wrong value for ARGV0 when launching gdb if
'nethack -dpath' was used to specify non-default playground directory
General New Features General New Features

View File

@@ -421,7 +421,7 @@ struct plinemsg_type {
E struct plinemsg_type *plinemsg_types; E struct plinemsg_type *plinemsg_types;
#ifdef PANICTRACE #ifdef PANICTRACE
E char *ARGV0; E const char *ARGV0;
#endif #endif
#undef E #undef E

View File

@@ -333,7 +333,7 @@ NEARDATA struct savefile_info sfrestinfo, sfsaveinfo = {
struct plinemsg_type *plinemsg_types = (struct plinemsg_type *) 0; struct plinemsg_type *plinemsg_types = (struct plinemsg_type *) 0;
#ifdef PANICTRACE #ifdef PANICTRACE
char *ARGV0; const char *ARGV0;
#endif #endif
/* support for lint.h */ /* support for lint.h */

View File

@@ -97,19 +97,18 @@ char *argv[];
choose_windows(DEFAULT_WINDOW_SYS); choose_windows(DEFAULT_WINDOW_SYS);
#ifdef CHDIR /* otherwise no chdir() */ #ifdef CHDIR /* otherwise no chdir() */
/* /*
* See if we must change directory to the playground. * See if we must change directory to the playground.
* (Perhaps hack runs suid and playground is inaccessible * (Perhaps hack runs suid and playground is inaccessible
* for the player.) * for the player.)
* The environment variable HACKDIR is overridden by a * The environment variable HACKDIR is overridden by a
* -d command line option (must be the first option given) * -d command line option (must be the first option given).
*/ */
dir = nh_getenv("NETHACKDIR"); dir = nh_getenv("NETHACKDIR");
if (!dir) if (!dir)
dir = nh_getenv("HACKDIR"); dir = nh_getenv("HACKDIR");
#endif
if (argc > 1) { if (argc > 1) {
#ifdef CHDIR
if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') { if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
/* avoid matching "-dec" for DECgraphics; since the man page /* avoid matching "-dec" for DECgraphics; since the man page
* says -d directory, hope nobody's using -desomething_else * says -d directory, hope nobody's using -desomething_else
@@ -127,30 +126,33 @@ char *argv[];
if (!*dir) if (!*dir)
error("Flag -d must be followed by a directory name."); error("Flag -d must be followed by a directory name.");
} }
if (argc > 1) }
#endif /* CHDIR */ #endif /* CHDIR */
/* if (argc > 1) {
* Now we know the directory containing 'record' and /*
* may do a prscore(). Exclude `-style' - it's a Qt option. * Now we know the directory containing 'record' and
*/ * may do a prscore(). Exclude `-style' - it's a Qt option.
if (!strncmp(argv[1], "-s", 2) && strncmp(argv[1], "-style", 6)) { */
if (!strncmp(argv[1], "-s", 2) && strncmp(argv[1], "-style", 6)) {
#ifdef CHDIR #ifdef CHDIR
chdirx(dir, 0); chdirx(dir, 0);
#endif #endif
#ifdef SYSCF #ifdef SYSCF
initoptions(); initoptions();
#endif #endif
#ifdef PANICTRACE #ifdef PANICTRACE
ARGV0 = argv[0]; /* save for possible stack trace */ ARGV0 = hname; /* save for possible stack trace */
#ifndef NO_SIGNAL #ifndef NO_SIGNAL
panictrace_setsignals(TRUE); panictrace_setsignals(TRUE);
#endif #endif
#endif #endif
prscore(argc, argv); prscore(argc, argv);
exit(EXIT_SUCCESS); /* FIXME: shouldn't this be using nh_terminate() to free
} up any memory allocated by initoptions() */
} exit(EXIT_SUCCESS);
}
} /* argc > 1 */
/* /*
* Change directories before we initialize the window system so * Change directories before we initialize the window system so
@@ -168,7 +170,7 @@ char *argv[];
#endif #endif
initoptions(); initoptions();
#ifdef PANICTRACE #ifdef PANICTRACE
ARGV0 = argv[0]; /* save for possible stack trace */ ARGV0 = hname; /* save for possible stack trace */
#ifndef NO_SIGNAL #ifndef NO_SIGNAL
panictrace_setsignals(TRUE); panictrace_setsignals(TRUE);
#endif #endif
@@ -217,7 +219,7 @@ char *argv[];
* dash matches role, race, gender, or alignment. * dash matches role, race, gender, or alignment.
*/ */
/* guard against user names with hyphens in them */ /* guard against user names with hyphens in them */
int len = strlen(plname); int len = (int) strlen(plname);
/* append the current role, if any, so that last dash is ours */ /* append the current role, if any, so that last dash is ours */
if (++len < (int) sizeof plname) if (++len < (int) sizeof plname)
(void) strncat(strcat(plname, "-"), pl_character, (void) strncat(strcat(plname, "-"), pl_character,
@@ -252,17 +254,17 @@ char *argv[];
dlb_init(); /* must be before newgame() */ dlb_init(); /* must be before newgame() */
/* /*
* Initialize the vision system. This must be before mklev() on a * Initialize the vision system. This must be before mklev() on a
* new game or before a level restore on a saved game. * new game or before a level restore on a saved game.
*/ */
vision_init(); vision_init();
display_gamewindows(); display_gamewindows();
/* /*
* First, try to find and restore a save file for specified character. * First, try to find and restore a save file for specified character.
* We'll return here if new game player_selection() renames the hero. * We'll return here if new game player_selection() renames the hero.
*/ */
attempt_restore: attempt_restore:
if ((fd = restore_saved_game()) >= 0) { if ((fd = restore_saved_game()) >= 0) {
const char *fq_save = fqname(SAVEF, SAVEPREFIX, 1); const char *fq_save = fqname(SAVEF, SAVEPREFIX, 1);
@@ -283,9 +285,10 @@ attempt_restore:
resuming = TRUE; /* not starting new game */ resuming = TRUE; /* not starting new game */
wd_message(); wd_message();
if (discover || wizard) { if (discover || wizard) {
if (yn("Do you want to keep the save file?") == 'n') /* this seems like a candidate for paranoid_confirmation... */
if (yn("Do you want to keep the save file?") == 'n') {
(void) delete_savefile(); (void) delete_savefile();
else { } else {
(void) chmod(fq_save, FCMASK); /* back to readable */ (void) chmod(fq_save, FCMASK); /* back to readable */
nh_compress(fq_save); nh_compress(fq_save);
} }
@@ -316,10 +319,12 @@ attempt_restore:
wd_message(); wd_message();
} }
/* moveloop() never returns but isn't flagged NORETURN */
moveloop(resuming); moveloop(resuming);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
/*NOTREACHED*/ /*NOTREACHED*/
return (0); return 0;
} }
static void static void
@@ -363,14 +368,15 @@ char *argv[];
break; break;
#endif #endif
case 'u': case 'u':
if (argv[0][2]) if (argv[0][2]) {
(void) strncpy(plname, argv[0] + 2, sizeof(plname) - 1); (void) strncpy(plname, argv[0] + 2, sizeof plname - 1);
else if (argc > 1) { } else if (argc > 1) {
argc--; argc--;
argv++; argv++;
(void) strncpy(plname, argv[0], sizeof(plname) - 1); (void) strncpy(plname, argv[0], sizeof plname - 1);
} else } else {
raw_print("Player name expected after -u"); raw_print("Player name expected after -u");
}
break; break;
case 'I': case 'I':
case 'i': case 'i':
@@ -457,10 +463,10 @@ boolean wr;
(void) setuid(getuid()); /* Ron Wessels */ (void) setuid(getuid()); /* Ron Wessels */
#endif #endif
} else { } else {
/* non-default data files is a sign that scores may not be /* non-default data files is a sign that scores may not be
* compatible, or perhaps that a binary not fitting this * compatible, or perhaps that a binary not fitting this
* system's layout is being used. * system's layout is being used.
*/ */
#ifdef VAR_PLAYGROUND #ifdef VAR_PLAYGROUND
int len = strlen(VAR_PLAYGROUND); int len = strlen(VAR_PLAYGROUND);
@@ -483,9 +489,10 @@ boolean wr;
error("Cannot chdir to %s.", dir); error("Cannot chdir to %s.", dir);
} }
/* warn the player if we can't write the record file */ /* warn the player if we can't write the record file
/* perhaps we should also test whether . is writable */ * perhaps we should also test whether . is writable
/* unfortunately the access system-call is worthless */ * unfortunately the access system-call is worthless.
*/
if (wr) { if (wr) {
#ifdef VAR_PLAYGROUND #ifdef VAR_PLAYGROUND
fqn_prefix[LEVELPREFIX] = fqn_prefix[SCOREPREFIX]; fqn_prefix[LEVELPREFIX] = fqn_prefix[SCOREPREFIX];
@@ -576,6 +583,7 @@ boolean
authorize_wizard_mode() authorize_wizard_mode()
{ {
struct passwd *pw = get_unix_pw(); struct passwd *pw = get_unix_pw();
if (pw && sysopt.wizards && sysopt.wizards[0]) { if (pw && sysopt.wizards && sysopt.wizards[0]) {
if (check_user_string(sysopt.wizards)) if (check_user_string(sysopt.wizards))
return TRUE; return TRUE;
@@ -628,6 +636,7 @@ char *optstr;
int pwlen; int pwlen;
char *eop, *w; char *eop, *w;
char *pwname; char *pwname;
if (optstr[0] == '*') if (optstr[0] == '*')
return TRUE; /* allow any user */ return TRUE; /* allow any user */
if (!pw) if (!pw)

View File

@@ -33,7 +33,7 @@ uid_t *ruid, *euid, *suid;
if (!f) if (!f)
return -1; return -1;
return f(ruid, euid, suid); return (*f)(ruid, euid, suid);
} }
static int static int
@@ -46,7 +46,7 @@ gid_t *rgid, *egid, *sgid;
if (!f) if (!f)
return -1; return -1;
return f(rgid, egid, sgid); return (*f)(rgid, egid, sgid);
} }
#else #else
@@ -74,6 +74,7 @@ uid_t *ruid, *euid, *suid;
int retval; int retval;
int pfd[2]; int pfd[2];
struct stat st; struct stat st;
if (pipe(pfd)) if (pipe(pfd))
return -1; return -1;
retval = fstat(pfd[0], &st); retval = fstat(pfd[0], &st);
@@ -107,6 +108,7 @@ gid_t *rgid, *egid, *sgid;
int retval; int retval;
int pfd[2]; int pfd[2];
struct stat st; struct stat st;
if (pipe(pfd)) if (pipe(pfd))
return -1; return -1;
retval = fstat(pfd[0], &st); retval = fstat(pfd[0], &st);
@@ -146,6 +148,7 @@ nh_getresuid(ruid, euid, suid)
uid_t *ruid, *euid, *suid; uid_t *ruid, *euid, *suid;
{ {
int retval = real_getresuid(ruid, euid, suid); int retval = real_getresuid(ruid, euid, suid);
if (!retval && hiding_privileges) if (!retval && hiding_privileges)
*euid = *suid = *ruid; *euid = *suid = *ruid;
return retval; return retval;
@@ -155,6 +158,7 @@ uid_t
nh_getuid() nh_getuid()
{ {
uid_t ruid, euid, suid; uid_t ruid, euid, suid;
(void) real_getresuid(&ruid, &euid, &suid); (void) real_getresuid(&ruid, &euid, &suid);
return ruid; return ruid;
} }
@@ -163,6 +167,7 @@ uid_t
nh_geteuid() nh_geteuid()
{ {
uid_t ruid, euid, suid; uid_t ruid, euid, suid;
(void) real_getresuid(&ruid, &euid, &suid); (void) real_getresuid(&ruid, &euid, &suid);
if (hiding_privileges) if (hiding_privileges)
euid = ruid; euid = ruid;
@@ -174,6 +179,7 @@ nh_getresgid(rgid, egid, sgid)
gid_t *rgid, *egid, *sgid; gid_t *rgid, *egid, *sgid;
{ {
int retval = real_getresgid(rgid, egid, sgid); int retval = real_getresgid(rgid, egid, sgid);
if (!retval && hiding_privileges) if (!retval && hiding_privileges)
*egid = *sgid = *rgid; *egid = *sgid = *rgid;
return retval; return retval;
@@ -183,6 +189,7 @@ gid_t
nh_getgid() nh_getgid()
{ {
gid_t rgid, egid, sgid; gid_t rgid, egid, sgid;
(void) real_getresgid(&rgid, &egid, &sgid); (void) real_getresgid(&rgid, &egid, &sgid);
return rgid; return rgid;
} }
@@ -191,6 +198,7 @@ gid_t
nh_getegid() nh_getegid()
{ {
gid_t rgid, egid, sgid; gid_t rgid, egid, sgid;
(void) real_getresgid(&rgid, &egid, &sgid); (void) real_getresgid(&rgid, &egid, &sgid);
if (hiding_privileges) if (hiding_privileges)
egid = rgid; egid = rgid;

View File

@@ -28,7 +28,8 @@ extern int errno;
static struct stat buf; static struct stat buf;
/* see whether we should throw away this xlock file */ /* see whether we should throw away this xlock file;
if yes, close it, otherwise leave it open */
static int static int
veryold(fd) veryold(fd)
int fd; int fd;
@@ -36,10 +37,10 @@ int fd;
time_t date; time_t date;
if (fstat(fd, &buf)) if (fstat(fd, &buf))
return (0); /* cannot get status */ return 0; /* cannot get status */
#ifndef INSURANCE #ifndef INSURANCE
if (buf.st_size != sizeof(int)) if (buf.st_size != sizeof (int))
return (0); /* not an xlock file */ return 0; /* not an xlock file */
#endif #endif
#if defined(BSD) && !defined(POSIX_TYPES) #if defined(BSD) && !defined(POSIX_TYPES)
(void) time((long *) (&date)); (void) time((long *) (&date));
@@ -49,10 +50,10 @@ int fd;
if (date - buf.st_mtime < 3L * 24L * 60L * 60L) { /* recent */ if (date - buf.st_mtime < 3L * 24L * 60L * 60L) { /* recent */
int lockedpid; /* should be the same size as hackpid */ int lockedpid; /* should be the same size as hackpid */
if (read(fd, (genericptr_t) &lockedpid, sizeof(lockedpid)) if (read(fd, (genericptr_t) &lockedpid, sizeof lockedpid)
!= sizeof(lockedpid)) != sizeof lockedpid)
/* strange ... */ /* strange ... */
return (0); return 0;
/* From: Rick Adams <seismo!rick> */ /* From: Rick Adams <seismo!rick> */
/* This will work on 4.1cbsd, 4.2bsd and system 3? & 5. */ /* This will work on 4.1cbsd, 4.2bsd and system 3? & 5. */
@@ -62,10 +63,10 @@ int fd;
by more than one machine! -pem */ by more than one machine! -pem */
if (!(kill(lockedpid, 0) == -1 && errno == ESRCH)) if (!(kill(lockedpid, 0) == -1 && errno == ESRCH))
#endif #endif
return (0); return 0;
} }
(void) close(fd); (void) close(fd);
return (1); return 1;
} }
static int static int
@@ -85,8 +86,8 @@ eraseoldlocks()
} }
set_levelfile_name(lock, 0); set_levelfile_name(lock, 0);
if (unlink(fqname(lock, LEVELPREFIX, 0))) if (unlink(fqname(lock, LEVELPREFIX, 0)))
return (0); /* cannot remove it */ return 0; /* cannot remove it */
return (1); /* success! */ return 1; /* success! */
} }
void void
@@ -139,8 +140,8 @@ getlock()
error("Cannot open %s", fq_lock); error("Cannot open %s", fq_lock);
} }
if (veryold(fd) /* closes fd if true */ /* veryold() closes fd if true */
&& eraseoldlocks()) if (veryold(fd) && eraseoldlocks())
goto gotlock; goto gotlock;
(void) close(fd); (void) close(fd);
} while (i < locknum); } while (i < locknum);
@@ -157,17 +158,20 @@ getlock()
error("Cannot open %s", fq_lock); error("Cannot open %s", fq_lock);
} }
if (veryold(fd) /* closes fd if true */ && eraseoldlocks()) /* veryold() closes fd if true */
if (veryold(fd) && eraseoldlocks())
goto gotlock; goto gotlock;
(void) close(fd); (void) close(fd);
{
const char destroy_old_game_prompt[] =
"There is already a game in progress under your name. Destroy old game?";
if (iflags.window_inited) { if (iflags.window_inited) {
c = yn("There is already a game in progress under your name. " /* this is a candidate for paranoid_confirmation */
"Destroy old game?"); c = yn(destroy_old_game_prompt);
} else { } else {
(void) printf( (void) printf("\n%s [yn] ", destroy_old_game_prompt);
"\nThere is already a game in progress under your name.");
(void) printf(" Destroy old game? [yn] ");
(void) fflush(stdout); (void) fflush(stdout);
if ((c = getchar()) != EOF) { if ((c = getchar()) != EOF) {
int tmp; int tmp;
@@ -178,10 +182,11 @@ getlock()
; /* eat rest of line and newline */ ; /* eat rest of line and newline */
} }
} }
}
if (c == 'y' || c == 'Y') { if (c == 'y' || c == 'Y') {
if (eraseoldlocks()) if (eraseoldlocks()) {
goto gotlock; goto gotlock;
else { } else {
unlock_file(HLOCK); unlock_file(HLOCK);
error("Couldn't destroy old game."); error("Couldn't destroy old game.");
} }
@@ -197,8 +202,8 @@ gotlock:
if (fd == -1) { if (fd == -1) {
error("cannot creat lock file (%s).", fq_lock); error("cannot creat lock file (%s).", fq_lock);
} else { } else {
if (write(fd, (genericptr_t) &hackpid, sizeof(hackpid)) if (write(fd, (genericptr_t) &hackpid, sizeof hackpid)
!= sizeof(hackpid)) { != sizeof hackpid) {
error("cannot write lock (%s)", fq_lock); error("cannot write lock (%s)", fq_lock);
} }
if (close(fd) == -1) { if (close(fd) == -1) {
@@ -207,13 +212,15 @@ gotlock:
} }
} }
void regularize(s) /* normalize file name - we don't like .'s, /'s, spaces */ /* normalize file name - we don't like .'s, /'s, spaces */
void
regularize(s)
register char *s; register char *s;
{ {
register char *lp; register char *lp;
while ((lp = index(s, '.')) || (lp = index(s, '/')) while ((lp = index(s, '.')) != 0 || (lp = index(s, '/')) != 0
|| (lp = index(s, ' '))) || (lp = index(s, ' ')) != 0)
*lp = '_'; *lp = '_';
#if defined(SYSV) && !defined(AIX_31) && !defined(SVR4) && !defined(LINUX) \ #if defined(SYSV) && !defined(AIX_31) && !defined(SVR4) && !defined(LINUX) \
&& !defined(__APPLE__) && !defined(__APPLE__)
@@ -258,10 +265,13 @@ unsigned msec; /* milliseconds */
int int
dosh() dosh()
{ {
register char *str; char *str;
#ifdef SYSCF #ifdef SYSCF
if (!sysopt.shellers || !sysopt.shellers[0] if (!sysopt.shellers || !sysopt.shellers[0]
|| !check_user_string(sysopt.shellers)) { || !check_user_string(sysopt.shellers)) {
/* FIXME: should no longer assume a particular command keystroke,
and perhaps ought to say "unavailable" rather than "unknown" */
Norep("Unknown command '!'."); Norep("Unknown command '!'.");
return 0; return 0;
} }
@@ -284,6 +294,7 @@ child(wt)
int wt; int wt;
{ {
register int f; register int f;
suspend_nhwindows((char *) 0); /* also calls end_screen() */ suspend_nhwindows((char *) 0); /* also calls end_screen() */
#ifdef _M_UNIX #ifdef _M_UNIX
sco_mapon(); sco_mapon();
@@ -297,13 +308,13 @@ int wt;
#ifdef CHDIR #ifdef CHDIR
(void) chdir(getenv("HOME")); (void) chdir(getenv("HOME"));
#endif #endif
return (1); return 1;
} }
if (f == -1) { /* cannot fork */ if (f == -1) { /* cannot fork */
pline("Fork failed. Try again."); pline("Fork failed. Try again.");
return (0); return 0;
} }
/* fork succeeded; wait for child to exit */ /* fork succeeded; wait for child to exit */
#ifndef NO_SIGNAL #ifndef NO_SIGNAL
(void) signal(SIGINT, SIG_IGN); (void) signal(SIGINT, SIG_IGN);
(void) signal(SIGQUIT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN);
@@ -325,9 +336,9 @@ int wt;
wait_synch(); wait_synch();
} }
resume_nhwindows(); resume_nhwindows();
return (0); return 0;
} }
#endif #endif /* SHELL || DEF_PAGER || DEF_MAILREADER */
#ifdef GETRES_SUPPORT #ifdef GETRES_SUPPORT
@@ -338,34 +349,37 @@ extern int FDECL(nh_getresgid, (gid_t *, gid_t *, gid_t *));
extern gid_t NDECL(nh_getgid); extern gid_t NDECL(nh_getgid);
extern gid_t NDECL(nh_getegid); extern gid_t NDECL(nh_getegid);
int(getresuid)(ruid, euid, suid) /* the following several functions assume __STDC__ where parentheses
around the name of a function-like macro prevent macro expansion */
int (getresuid)(ruid, euid, suid)
uid_t *ruid, *euid, *suid; uid_t *ruid, *euid, *suid;
{ {
return nh_getresuid(ruid, euid, suid); return nh_getresuid(ruid, euid, suid);
} }
uid_t(getuid)() uid_t (getuid)()
{ {
return nh_getuid(); return nh_getuid();
} }
uid_t(geteuid)() uid_t (geteuid)()
{ {
return nh_geteuid(); return nh_geteuid();
} }
int(getresgid)(rgid, egid, sgid) int (getresgid)(rgid, egid, sgid)
gid_t *rgid, *egid, *sgid; gid_t *rgid, *egid, *sgid;
{ {
return nh_getresgid(rgid, egid, sgid); return nh_getresgid(rgid, egid, sgid);
} }
gid_t(getgid)() gid_t (getgid)()
{ {
return nh_getgid(); return nh_getgid();
} }
gid_t(getegid)() gid_t (getegid)()
{ {
return nh_getegid(); return nh_getegid();
} }
@@ -375,12 +389,15 @@ gid_t(getegid)()
/* XXX should be ifdef PANICTRACE_GDB, but there's no such symbol yet */ /* XXX should be ifdef PANICTRACE_GDB, but there's no such symbol yet */
#ifdef PANICTRACE #ifdef PANICTRACE
boolean boolean
file_exists(const char *path) file_exists(path)
const char *path;
{ {
struct stat sb;
/* Just see if it's there - trying to figure out if we can actually /* Just see if it's there - trying to figure out if we can actually
* execute it in all cases is too hard - we really just want to * execute it in all cases is too hard - we really just want to
* catch typos in SYSCF. */ * catch typos in SYSCF.
struct stat sb; */
if (stat(path, &sb)) { if (stat(path, &sb)) {
return FALSE; return FALSE;
} }