Ticket #384 (closed bug: fixed)

Opened 1 year ago

Last modified 5 months ago

OS X: Problem opening Angband using Quicksilver

Reported by: Adam Randall <randalla@mcn.org> Assigned to:
Milestone: 3.1.0 Version:
Keywords: mac Cc:

Description

I use the app launcher Quicksilver. Unfortunately, I cannot use it with Angband because I get an error about it wanting to write the high scores list to /var/root/Library/Angband/...

Looking at activity monitor, the Quicksilver application itself is running as my current user, and not as root. It seems odd that it would want to write to /var/root. Maybe Quicksilver is running without a home directory environment variable and Angband is choosing to use root's since it doesn't know better?

Attachments

test_exec.c (2.0 kB) - added by roustk@alumni.caltech.edu on 01/24/08 13:21:20.
Find uid of owner of this executable on Darwin (Mac OS X 10.4.11)
test_SysConf.c (265 bytes) - added by roustk@alumni.caltech.edu on 01/24/08 15:59:43.
Example using SCDynamicStoreCopyConsoleUser
SCDynamicStoreCopySpecific.h (6.4 kB) - added by roustk@alumni.caltech.edu on 01/24/08 16:02:03.
Apple's SCDynamicStoreCopySpecific.h header (from 10.4.11)

Change History

01/24/08 13:20:12 changed by roustk@alumni.caltech.edu

See also http://angband.oook.cz/forum/showthread.php?t=500

As of 3.0.9, the relevant bit of code is in z-file.c, where the current user (and his home directory) is identified using:

u = getlogin();

if (u) pw = getpwnam(u);

else pw = getpwuid(getuid());

If running in a terminal, getlogin() returns the username, so getpwnam() returns a struct passwd, including the home directory.

Not in a terminal, getlogin() is null, so getpwuid(getuid()) is supposed to return a struct passwd for the uid running the angband process. The man page for getuid claims it never fails, so it is a fair question how it returns 0 (root), rather than the real uid.

Attached is a horrible bit of code that will identify the uid that owns the executable, which might be a decent approximation of the real uid for a single-user system. Odds are this will break non-Darwin unixes, because it uses a KERN_PROCARGS2 argument to sysctl.

As written, adding this to Angband would require including <sys/sysctl.h> and verifying that this is far enough from Darwin to avoid contamination from that license. (I think its clean, because I only mimicked the sysctl call (with its mib structure. The rest is fairly far removed from their ps code.)

Kevin

01/24/08 13:21:20 changed by roustk@alumni.caltech.edu

  • attachment test_exec.c added.

Find uid of owner of this executable on Darwin (Mac OS X 10.4.11)

01/24/08 13:42:09 changed by roustk@alumni.caltech.edu

Note: I wrote the attached code assuming that argv wasn't available and I couldn't trust the path to be correct. If you can trust those, finding the executable owner is trivial:

struct stat sb;

stat(argv[0],&sb);

printf("file owner uid: %d\n",sb.st_uid);

01/24/08 15:59:04 changed by roustk@alumni.caltech.edu

Zaimoni on oook found reference to this being a known Apple bug:

http://lists.apple.com/archives/cocoa-dev/2006/Nov/msg00618.html

Based on that, I've developed a heavy-handed workaround that uses the SystemConfiguration framework and assumes that the user logged in to console is the one we want.

The function we will use is in the SystemConfiguration framework and is called SCDynamicStoreCopyConsoleUser. A minimal #include is <SystemConfiguration/SCDynamicStoreCopySpecific.h>, although the more general <SystemConfiguration/SystemConfiguration.h> works too. We will need to add "-framework SystemConfiguration" to the linker.

The z-file.h should be changed slightly around line 391. Inside the #if defined(SET_UID) side of path_parse add a variable "uid_t uid;".

After /* Look up a user (or "current" user) */ use something like:

  /* Look up a user (or "current" user) */
  if (u) pw = getpwnam(u);
  else 
  { 
    uid = getuid();
#ifdef MACH_O_CARBON
    if(uid==0) {
    /* Don't trust Macs that say root is running Angband. */
    /* Use the SystemConfiguration framework to 
         identify who is logged in on *console*.
         Assume that the console user is running Angband. */
    SCDynamicStoreCopyConsoleUser(NULL,&uid,NULL);
    }
#endif /* MACH_O_CARBON */
    pw = getpwuid(uid);
  }

  /* Nothing found? */
  if (!pw) return (1);

Someone who knows what they're looking for should see if there are any problems between the Apple license and the Angband one: http://www.opensource.apple.com/apsl/

Kevin

01/24/08 15:59:43 changed by roustk@alumni.caltech.edu

  • attachment test_SysConf.c added.

Example using SCDynamicStoreCopyConsoleUser

01/24/08 16:02:03 changed by roustk@alumni.caltech.edu

  • attachment SCDynamicStoreCopySpecific.h added.

Apple's SCDynamicStoreCopySpecific.h header (from 10.4.11)

01/24/08 16:04:49 changed by roustk@alumni.caltech.edu

Of course, I meant z-file.c (not z-file.h) in my previous comment.

01/24/08 20:20:31 changed by Kenneth 'Bessarion' Boyd <zaimoni@zaimoni.com>

APSL V2.0 is a FSF-free license but not GPL(V2) compatible, according to FSF. ( http://www.fsf.org/licensing/licenses/index_html )

That said, there's virtually no "degrees of freedom" in the implementation (the usage is dictated by the specification). Unless merely using the specification causes APSL V2.0 contamination, I wouldn't consider this code fragment contaminated.

05/11/08 22:19:00 changed by takkaria

  • status changed from new to closed.
  • resolution set to fixed.

Fixed in r894.


Add/Change #384 (OS X: Problem opening Angband using Quicksilver)




Action