Opened 10 years ago

Closed 9 years ago

#384 closed bug (fixed (in master))

OS X: Problem opening Angband using Quicksilver

Reported by: Adam Randall <randalla@…> Owned by:
Milestone: 3.1.0 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 (3)

test_exec.c (2.0 KB) - added by roustk@… 10 years ago.
Find uid of owner of this executable on Darwin (Mac OS X 10.4.11)
test_SysConf.c (265 bytes) - added by roustk@… 10 years ago.
Example using SCDynamicStoreCopyConsoleUser
SCDynamicStoreCopySpecific.h (6.4 KB) - added by roustk@… 10 years ago.
Apple's SCDynamicStoreCopySpecific.h header (from 10.4.11)

Download all attachments as: .zip

Change History (9)

comment:1 Changed 10 years ago by roustk@…

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

Changed 10 years ago by roustk@…

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

comment:2 Changed 10 years ago by roustk@…

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);

comment:3 Changed 10 years ago by roustk@…

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

Changed 10 years ago by roustk@…

Example using SCDynamicStoreCopyConsoleUser

Changed 10 years ago by roustk@…

Apple's SCDynamicStoreCopySpecific.h header (from 10.4.11)

comment:4 Changed 10 years ago by roustk@…

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

comment:5 Changed 10 years ago by Kenneth 'Bessarion' Boyd <zaimoni@…>

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.

comment:6 Changed 9 years ago by takkaria

  • Resolution set to fixed
  • Status changed from new to closed

Fixed in [01008f3] (SVN r894).

Note: See TracTickets for help on using tickets.