you may have to set a reuse flag for the port still. Even unix domain sockets, despite being a file, still have a port that you may need to specify to reuse
I'm looking for a sample code to show how to set the port reusable... but nothing found... speaking about socket I didn't set any port... when I set up a Inet socket I configure a port but in UNIX sock I don't know where to set a port... can you help me? thnx + regards Gian Luca On Sep 25, 2011, at September 25, 20113:48 AM, Nehemiah Dacres wrote:
you may have to set a reuse flag for the port still. Even unix domain sockets, despite being a file, still have a port that you may need to specify to reuse _______________________________________________ launchd-dev mailing list launchd-dev@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/launchd-dev
On 26 Sep 2011, at 12:18, Gian Luca Gaiba wrote:
I didn't set any port... when I set up a Inet socket I configure a port but in UNIX sock I don't know where to set a port...
UNIX domain sockets don't need a port. In a TCP connection, the destination address consists of the IP address (the machine on which the server is running) and a port (to identify the service within that machine). For a UNIX domain socket the server is always running on the local machine, so you only need to identify the service on the machine, which is what the path does. As to your original problem, I'm not sure what's going on. The best solution to this problem is to have launchd managing your listening socket for you. I don't know of a simple sample that shows this for UNIX domain sockets, but the SampleD sample code shows it for TCP sockets. <http://developer.apple.com/library/mac/#samplecode/SampleD/> You can also look at BetterAuthorizationSample, which is rather complex but does show the UNIX domain sockets side of things. <http://developer.apple.com/library/mac/#samplecode/BetterAuthorizationSample/> If you must create your own UNIX domain socket (which, again, isn't what I recommend), you can look at the CFLocalServer sample code, which shows how to do that. <http://developer.apple.com/library/mac/samplecode/CFLocalServer/> S+E -- Quinn "The Eskimo!" <http://www.apple.com/developer/> Apple Developer Relations, Developer Technical Support, Core OS/Hardware
On Sep 27, 2011, at September 27, 201111:30 AM, Quinn The Eskimo! wrote:
UNIX domain sockets don't need a port. In a TCP connection, the destination address consists of the IP address (the machine on which the server is running) and a port (to identify the service within that machine). For a UNIX domain socket the server is always running on the local machine, so you only need to identify the service on the machine, which is what the path does.
Yes, I read about that, and that's why I didn't configure a port...
As to your original problem, I'm not sure what's going on. The best solution to this problem is to have launchd managing your listening socket for you. I don't know of a simple sample that shows this for UNIX domain sockets, but the SampleD sample code shows it for TCP sockets.
<http://developer.apple.com/library/mac/#samplecode/SampleD/>
You can also look at BetterAuthorizationSample, which is rather complex but does show the UNIX domain sockets side of things.
<http://developer.apple.com/library/mac/#samplecode/BetterAuthorizationSample/>
If you must create your own UNIX domain socket (which, again, isn't what I recommend), you can look at the CFLocalServer sample code, which shows how to do that.
<http://developer.apple.com/library/mac/samplecode/CFLocalServer/>
I have the socket managed by launchd but the problem is in testing... I have two constuctors for the socket one if it's managed by launchd and one when I run the procedure in testing mode (I.e. from xCode) that compose a UNIX socket like in CFLocalServer... I think I have done anything correctly but the socket is not reusable... this is not a "real" problem but I'd like to understand why this thing happen... The only thing I think I differ is the socket path that isn't in the standard /var directory but in /Users/myuser directory... this could be a problem? thanks and regards Gian Luca
On 28 Sep 2011, at 08:55, Gian Luca Gaiba wrote:
this is not a "real" problem but I'd like to understand why this thing happen...
IIRC deleting the sock at the path before binding its replacement to that path is accepted standard practice. That's what I do in CFLocalServer and, dusting off my copy of "UNIX Network Programming", that's what the code in there does as well. S+E -- Quinn "The Eskimo!" <http://www.apple.com/developer/> Apple Developer Relations, Developer Technical Support, Core OS/Hardware
I have a couple of questions about SMJobBless - both the sample code (http://developer.apple.com/library/mac/#samplecode/SMJobBless/Introduction/I...) and function and how it relates to a launchd secure helper tool. The primary question regards the sample SMJobBless sample code - When running the application, under what circumstances will an admin password be requested? What little I could find seemed to indicate that it should only be asking for the password when the SMJobBless function needs to install the helper tool because either the helper tool was never installed or the SMJobBless function sees that a new version needs to be installed. However, the behavior I am seeing is that an admin password will be requested each time the SMJobBless application is launched (so long as X amount of time passes between launches). Is there a bug here or are things behaving correctly? Since I am hesitant to believe there is a bug in the APIs or that the sample code is incorrect, what appears to be necessary is to first check the version of the installed helper tool vs. the version in the application package. I am doing this with the following code: ---------- VVVVVVVVVV ---------- NSDictionary* installedHelperJobData; installedHelperJobData = (NSDictionary*)SMJobCopyDictionary( kSMDomainSystemLaunchd, (CFStringRef)@"com.apple.bsd.SMJobBlessHelper" ); NSString* installedPath = [[installedHelperJobData objectForKey:@"ProgramArguments"] objectAtIndex:0]; NSURL* installedPathURL = [NSURL fileURLWithPath:installedPath]; NSDictionary* installedInfoPlist = (NSDictionary*)CFBundleCopyInfoDictionaryForURL( (CFURLRef)installedPathURL ); NSString* installedBundleVersion = [installedInfoPlist objectForKey:@"CFBundleVersion"]; NSInteger installedVersion = [installedBundleVersion integerValue]; NSLog( @"installedVersion: %ld", (long)installedVersion ); NSBundle* appBundle = [NSBundle mainBundle]; NSURL* appBundleURL = [appBundle bundleURL]; NSURL* currentHelperToolURL = [appBundleURL URLByAppendingPathComponent:@"Contents/Library/LaunchServices/com.apple.bsd.SMJobBlessHelper"]; NSDictionary* currentInfoPlist = (NSDictionary*)CFBundleCopyInfoDictionaryForURL( (CFURLRef)currentHelperToolURL ); NSString* currentBundleVersion = [currentInfoPlist objectForKey:@"CFBundleVersion"]; NSInteger currentVersion = [currentBundleVersion integerValue]; NSLog( @"currentVersion: %ld", (long)currentVersion ); ---------- ^^^^^^^^^^ ---------- I altered the sample code a little to guarantee that the version # is just an increasing integer. Is there a better way to check the version numbers? Is there some other method I should be using to determine whether or not blessHelperWithLabel should be called? Only if the two versions are different does blessHelperWithLabel get called. However, this code seems like it should be unnecessary because SMJobBless is doing a version check. Thank you.
In general I recommend that you avoid trying to check whether your helper tool is installed correctly by looking at the file system. Rather, do an IPC to the tool and, if it works, you know that everything is hunky dory. If you're concerned about version numbers, have an IPC request to ask the helper tool for its version. If that fails, or returns a low version, you then know that you need to go through the installation process. Look at how I handle this in BetterAuthorizationSample. While it doesn't use SMJobBless (one day, one day...), the basic strategy is correct IMO. <http://developer.apple.com/library/mac/samplecode/BetterAuthorizationSample/> S+E -- Quinn "The Eskimo!" <http://www.apple.com/developer/> Apple Developer Relations, Developer Technical Support, Core OS/Hardware
On Oct 3, 2011, at 12:22 PM, Quinn The Eskimo! wrote:
In general I recommend that you avoid trying to check whether your helper tool is installed correctly by looking at the file system. Rather, do an IPC to the tool and, if it works, you know that everything is hunky dory. If you're concerned about version numbers, have an IPC request to ask the helper tool for its version. If that fails, or returns a low version, you then know that you need to go through the installation process.
Look at how I handle this in BetterAuthorizationSample. While it doesn't use SMJobBless (one day, one day...), the basic strategy is correct IMO.
<http://developer.apple.com/library/mac/samplecode/BetterAuthorizationSample/>
Thank you for the reply. Ok, so if I understand you correctly, you are saying: (This is the primary item I want to be clear on…should launching the SMJobBless sample app cause a request for an admin password every time?) The SMJobBless sample application is correctly written and there should be an admin password request for every launch. Since asking for a password, with every application launch, is annoying for the user when the helper tool is already there and functioning correctly, you are also saying: It is up to the programmer to check the version number of the installed helper tool and call the SMJobBless function if necessary. The proper way to obtain the version number of the tool is to send the tool a message and have it reply with it's version number. If a connection to the tool cannot be made, call SMJobBless. If it responds with a different version number then the one expected, call SMJobBless. Thank you!
On Oct 3, 2011, at 12:22 PM, Quinn The Eskimo! wrote:
In general I recommend that you avoid trying to check whether your helper tool is installed correctly by looking at the file system. Rather, do an IPC to the tool and, if it works, you know that everything is hunky dory. If you're concerned about version numbers, have an IPC request to ask the helper tool for its version. If that fails, or returns a low version, you then know that you need to go through the installation process.
Look at how I handle this in BetterAuthorizationSample. While it doesn't use SMJobBless (one day, one day...), the basic strategy is correct IMO.
<http://developer.apple.com/library/mac/samplecode/BetterAuthorizationSample/>
I do have one other question about whether or not there may be another, good way to check the version number of the installed helper tool. Would it not be possible to create a code signing requirement using SecRequirementCreateWithString and have the requirement string be something like: info [CFBundleVersion] > "3" and then use one of the Sec*CodeCheckValidity functions to check the requirement. The easiest one to use would seem to be SecStaticCodeCheckValidity. Of course, using this function would seem to require the following code be written as well: NSDictionary* installedHelperJobData = (NSDictionary*)SMJobCopyDictionary( kSMDomainSystemLaunchd, (CFStringRef)@"com.apple.bsd.SMJobBlessHelper" ); NSString* installedPath = [[installedHelperJobData objectForKey:@"ProgramArguments"] objectAtIndex:0]; NSURL* installedPathURL = [NSURL fileURLWithPath:installedPath]; SecStaticCodeCreateWithPath( (CFURLRef)installedPathURL, kSecCSDefaultFlags, &staticCodeRef ); What do you think about this solution? It certainly seems easier then doing an IPC to the tool when one is dealing with code that is signed… I did write this code and it does seem to work…
If anyone is interested, this (probably) turned out to be a bug and one has been filed. rdar://10280469 The way the system currently works is that it will ask for an admin password every time regardless of whether or not the SMJobBless function needs to install the helper tool or not. The bug is (probably) that a admin password request should not be made if the helper tool does not need to be installed (for example, it is already installed and has the same version as the one in the app bundle). So, what this means is that the determination of whether or not the helper tool needs to be installed needs to be made before a call to SMJobBless and SMJobBless should only be called if it is already known the helper tool needs to be installed. In my case, I only need to check whether the tool is installed (SMJobCopyDictionary handles this) and, if the tool is installed, whether or not it's version is older then the version of the tool in my app bundle. Some (incomplete) code to check whether the tool is installed and what the versions are is below. There is another alternative to do a version check of the helper tool which is for the helper tool to receive a request for it's version and for it to send a version reply back. Personally, I like the method below, but wanted to mention this alternative as it may be the best path in some situations. On Oct 3, 2011, at 10:13 AM, Eric Gorr wrote:
---------- VVVVVVVVVV ---------- NSDictionary* installedHelperJobData;
installedHelperJobData = (NSDictionary*)SMJobCopyDictionary( kSMDomainSystemLaunchd, (CFStringRef)@"com.apple.bsd.SMJobBlessHelper" );
NSString* installedPath = [[installedHelperJobData objectForKey:@"ProgramArguments"] objectAtIndex:0]; NSURL* installedPathURL = [NSURL fileURLWithPath:installedPath];
NSDictionary* installedInfoPlist = (NSDictionary*)CFBundleCopyInfoDictionaryForURL( (CFURLRef)installedPathURL ); NSString* installedBundleVersion = [installedInfoPlist objectForKey:@"CFBundleVersion"]; NSInteger installedVersion = [installedBundleVersion integerValue];
NSLog( @"installedVersion: %ld", (long)installedVersion );
NSBundle* appBundle = [NSBundle mainBundle]; NSURL* appBundleURL = [appBundle bundleURL];
NSURL* currentHelperToolURL = [appBundleURL URLByAppendingPathComponent:@"Contents/Library/LaunchServices/com.apple.bsd.SMJobBlessHelper"]; NSDictionary* currentInfoPlist = (NSDictionary*)CFBundleCopyInfoDictionaryForURL( (CFURLRef)currentHelperToolURL ); NSString* currentBundleVersion = [currentInfoPlist objectForKey:@"CFBundleVersion"]; NSInteger currentVersion = [currentBundleVersion integerValue];
NSLog( @"currentVersion: %ld", (long)currentVersion ); ---------- ^^^^^^^^^^ ----------
participants (5)
-
Eric Gorr
-
Gian Luca Gaiba
-
Nehemiah Dacres
-
Quinn "The Eskimo!"
-
Quinn The Eskimo!