print description
2011年4月30日 星期六
2011年4月28日 星期四
2011年4月27日 星期三
2011年4月21日 星期四
sysctl
get or set kernel state
show value
ex:
sysctl -a | grep aio
->
kern.aiomax = 90
kern.aioprocmax = 16
kern.aiothreads = 4
kern.aiomax: 90
kern.aioprocmax: 16
kern.aiothreads: 4
modify value
ex:
sysctl -w kern.aioprocmax=1000
show value
ex:
sysctl -a | grep aio
->
kern.aiomax = 90
kern.aioprocmax = 16
kern.aiothreads = 4
kern.aiomax: 90
kern.aioprocmax: 16
kern.aiothreads: 4
modify value
ex:
sysctl -w kern.aioprocmax=1000
iometer
http://sourceforge.net/news/?group_id=40179
use iometer to test disk performance on mac
(the dynamo for mac & iometer for windows must be the same version)
(1) run dynamo on mac os
ex:
sudo ./Dynamo -i 192.168.4.112 -m 172.18.8.21
192.168.4.112 is windows IP,
172.18.8.21 is mac os IP
(2) run iometer on windows
use iometer to test disk performance on mac
(the dynamo for mac & iometer for windows must be the same version)
(1) run dynamo on mac os
ex:
sudo ./Dynamo -i 192.168.4.112 -m 172.18.8.21
192.168.4.112 is windows IP,
172.18.8.21 is mac os IP
(2) run iometer on windows
2011年4月20日 星期三
atomic operation in mac driver
SInt32 OSDecrementAtomic(volatile SInt32 * address);
SInt32 OSIncrementAtomic(volatile SInt32 * address);
2011年4月19日 星期二
find network card driver on linux
check /etc/modules.conf
ex:
cat /etc/modprobe.conf
-> alias scsi_hostadapter ata_piix alias eth1 e1000 alias eth3 e1000
ex:
cat /etc/modprobe.conf
-> alias scsi_hostadapter ata_piix alias eth1 e1000 alias eth3 e1000
mac driver plist
mac driver plist
mac driver:
1. CFBundleIdentifier
unique id for kext
ex:
com.deeplove.test
it does not need to match with IOClass
2. OSBundleLibraries
define depended libraries
we can use kextlibs to find linked libraries
ex:
kextlibs -xml GenericKext.kext
->
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.libkern</key>
<string>10.4</string>
</dict>
the match version number lib is define in OSBundleCompatibleVersion
ex:
<key>OSBundleCompatibleVersion</key>
<string>1.0</string>
3. IOKitPersonalities
ex:
<key>IOKitPersonalities</key>
<dict>
<key>MyIokitDriver</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.driver.MyIokitDriver</string>
<key>IOClass</key>
<string>com_yourcompany_driver_MyIokitDriver</string>
<key>IOKitDebug</key>
<integer>65535</integer>
<key>IOProviderClass</key>
<string>IOResources</string>
<key>IOMatchCategory</key>
<string>com_yourcompany_driver_MyIokitDriver</string>
</dict>
</dict>
CFBundleIdentifier in IOKitPersonalities must be the same with outer CFBundleIdentifier
IOProviderClass:
indicates the class of the provider objects that your driver can match on
IOMatchCategory:
allows other drivers to match on the same device as your driver,
as long as the drivers values for this property differ
2011年4月18日 星期一
create install package for kext
reference:
http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptPackaging/packaging_tutorial.html%23//apple_ref/doc/uid/20002368-CHDCBCJA
1. create dir for kext
cd /tmp
sudo mkdir tempKext
2. copy kext into dir
cd /KEXT_PROJECT_PATH/build/Release
sudo cp -R test.kext /tmp/tempKext
3. use PackageMaker to create install package
(/Developer/Application/Utilities)
drag tempKext dir into PackageMaker window
save editing result as .pmdoc file( PackageMaker file)
4. build
create .pkg file (install file)
.
http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptPackaging/packaging_tutorial.html%23//apple_ref/doc/uid/20002368-CHDCBCJA
1. create dir for kext
cd /tmp
sudo mkdir tempKext
2. copy kext into dir
cd /KEXT_PROJECT_PATH/build/Release
sudo cp -R test.kext /tmp/tempKext
3. use PackageMaker to create install package
(/Developer/Application/Utilities)
drag tempKext dir into PackageMaker window
save editing result as .pmdoc file( PackageMaker file)
4. build
create .pkg file (install file)
.
2011年4月16日 星期六
multitouch on iOS
get touch events for specific view
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSSet *touchesForTestView = [event touchesForView:testView];
}
2011年4月15日 星期五
create global variable on iOS project
ex:
test.m
int a = 3;
hello.h
extern int a;
useA.m
#import hello.h
test.m
int a = 3;
hello.h
extern int a;
useA.m
#import hello.h
NSNotificationCenter
- (void)addObserver:(id)observer selector:(SEL)aSelector :(NSString *)aName object:(id)anObject;
register to receive notification
parameter:
1. observer: the object to receive notification
2. aName: name of notification, if it is nil, we receive all notifications sent out by anObject
3. anObject: specify object we want to observe. If it is nil, we receive all notification with aName
we can register many objects to receive same notification.
- (void)postNotificationName:(NSString *)aName object:(id)anObject;
send notfication
parameter:
anObject: sender
2011年4月13日 星期三
2011年4月12日 星期二
find element in ioregistry
from client program:
#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/IOType.h>#include <IOKit/network/IOEthernetInterface.h>
int findClassesInIoregistry(io_iterator_t* iterator, char *match_name)
{
CFDictionaryRef classToMatch;
kern_return_t kernResult;
classToMatch = IOServiceMatching(match_name);
if (classToMatch == NULL)
{
return -1;
}
// use class name to match
kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,
classToMatch, iterator);
classToMatch, iterator);
if (kernResult != KERN_SUCCESS)
{
return -1;
}
return kIOReturnSuccess;
}
io_iterator_t ethernetInterfaceIterator;
result = findClassesInIoregistry(& ethernetInterfaceIterator, kIOEthernetInterfaceIterator);
if(result == kIOReturnSuccess)
{
io_service_t ethernetInterface;
while(ethernetInterface = IOIteratorNext(ethernetInterfaceIterator))
{
NSString *bsdName =
(NSString*)IORegistryEntrySearchCFProperty(ethernetInterface,
NSString *bsdName =
(NSString*)IORegistryEntrySearchCFProperty(ethernetInterface,
kIOServicePlane,
CFSTR("BSD Name"),
kCFAllocatorDefault,
kIORegistryIterateRecursively);
io_service_t ethernetController;
result = IORegistryEntryGetParentEntry(ethernetInterface,
kIOServicePlane,
ðernetController);
if(result == kIOReturnSuccess)
{
IOObjectRelease(ethernetController);
}
IOObjectRelease(ethernetInterface);
}
IOObjectRelease(ethernetInterfaceIterator);
}
if(blockDriverIter)
from driver program:
OSIterator *blockDriverIter = this->getProviderIterator();
com_my_BlockStorageDriver *blockDriver;
{
while (blockDriver = (com_my_BlockStorageDriver*)blockDriverIter->getNextObject())
{
IOLog("blockDriver %p inAct %d\n", blockDriver,
blockDriver->isInactive());
}
blockDriverIter->release();
}
2011年4月11日 星期一
IOUserClient
reference sample code from Apple:
SimpleUserClient
IOExternalMethodDispatch structure:
SimpleUserClient
IOExternalMethodDispatch structure:
struct IOExternalMethodDispatch
{
IOExternalMethodAction function;
uint32_t checkScalarInputCount;
uint32_t checkStructureInputSize;
uint32_t checkScalarOutputCount;
uint32_t checkStructureOutputSize;
};
2011年4月10日 星期日
use jquery to get or set element value
get element value:
$("#ipDiv").attr("value")
set element value:
ex:
$("#ipDiv").attr("value", "10.10.10.1");
$("#ipDiv").attr("value")
set element value:
ex:
$("#ipDiv").attr("value", "10.10.10.1");
2011年4月9日 星期六
responder chain in iOS & Cocoa
events are passed through responder chain
ex:
if first responder is view A
when view A does not handle event, it forward event to next responder, its view controller
if view controller does not handle event, it forward event to view A's parent view B
if view B does not handle event, it forward event to its view controller
Hence, sequence is
view A -> view A's view controller -> view A's parent view B -> view A's parent view B's view controller
note:
if event is passed through all view hierarchy, it is then passed to app's window. If window does not handle event, it is passed to UIApplication object
forward an event:
ex:
[self.nextResponder processEvent:event];
ex:
if first responder is view A
when view A does not handle event, it forward event to next responder, its view controller
if view controller does not handle event, it forward event to view A's parent view B
if view B does not handle event, it forward event to its view controller
Hence, sequence is
view A -> view A's view controller -> view A's parent view B -> view A's parent view B's view controller
note:
if event is passed through all view hierarchy, it is then passed to app's window. If window does not handle event, it is passed to UIApplication object
forward an event:
ex:
[self.nextResponder processEvent:event];
CMMotionManager
passive detect:
get data from callback
active detect:
get data when we need
acceleration value for different device orientations:
get data from callback
active detect:
get data when we need
acceleration value for different device orientations:
2011年4月8日 星期五
UIKit and thread
when dealing with UIKit class, we must be in the main thread
If we are not in the main thread,
and we want to modify label's text,
we must do following
->
If we are not in the main thread,
and we want to modify label's text,
we must do following
->
[textLabel performSelectorOnMainThread:@selector(setText:)
withObject:@"hello" waitUntilDone:YES];
operation is iOS SDK
Add operations into operation queue and queue will manage operation for us
operation type:
1. Block operation
2. Invocation operation
3. Plane operation
operation 執行的順序和加入operation queue的順序無關
operation type:
1. Block operation
2. Invocation operation
3. Plane operation
operation 執行的順序和加入operation queue的順序無關
share memory between app and kernel on mac os
memory allocated in the kernel cannot be written to by applications
if a buffer must be modified by an application, the buffer must be allocated by that program, not by the kernel
if a buffer must be modified by an application, the buffer must be allocated by that program, not by the kernel
2011年4月7日 星期四
mac driver debug
1. download kernel debug kit from Apple website
ex:
kernel_debug_kit_10.6.7_10j869.dmg
2. create kext symbol file
ex:
find address from crash report (/Library/Logs/DiagnosticReports/)
Thu Apr 7 15:19:35 2011
panic(cpu 0 caller 0xffffff80002cffca): Kernel trap at 0xffffff8000521c10, type 14=page fault, registers:
CR0: 0x000000008001003b, CR2: 0x0000000000000000, CR3: 0x0000000000100000, CR4: 0x0000000000000660
RAX: 0xffffff800918f260, RBX: 0xffffff8009a45c00, RCX: 0x00000000f25d0000, RDX: 0xffffff80088a5e20
RSP: 0xffffff804a4db790, RBP: 0xffffff804a4db7b0, RSI: 0x0000000020000001, RDI: 0x0000000000000000
R8: 0x000000000000000a, R9: 0x0000000000000000, R10: 0x0000000000000000, R11: 0xffffff80004f3b3a
R12: 0xffffff8008ce1000, R13: 0xffffff8009a45c00, R14: 0xffffff8009a459c0, R15: 0x0000000000000000
RFL: 0x0000000000010246, RIP: 0xffffff8000521c10, CS: 0x0000000000000008, SS: 0x0000000000000000
Error code: 0x0000000000000000
Backtrace (CPU 0), Frame : Return Address
0xffffff804a4db430 : 0xffffff8000204b99
0xffffff804a4db530 : 0xffffff80002cffca
0xffffff804a4db680 : 0xffffff80002e20da
0xffffff804a4db690 : 0xffffff8000521c10
0xffffff804a4db7b0 : 0xffffff8000521408
0xffffff804a4db7e0 : 0xffffff7f806e699a
0xffffff804a4db970 : 0xffffff7f806defca
0xffffff804a4db9e0 : 0xffffff7f806e76f9
0xffffff804a4dba30 : 0xffffff7f8067f5ad
0xffffff804a4dbaa0 : 0xffffff7f806807e2
0xffffff804a4dbba0 : 0xffffff7f80680191
0xffffff804a4dbbd0 : 0xffffff7f80680458
0xffffff804a4dbc50 : 0xffffff7f806e6d30
0xffffff804a4dbcb0 : 0xffffff80005267da
0xffffff804a4dbd20 : 0xffffff80005239bf
0xffffff804a4dbd40 : 0xffffff8000521e78
0xffffff804a4dbd70 : 0xffffff800052649f
0xffffff804a4dbda0 : 0xffffff8000523a07
0xffffff804a4dbde0 : 0xffffff80005267da
0xffffff804a4dbe50 : 0xffffff80005239bf
ex:
kernel_debug_kit_10.6.7_10j869.dmg
2. create kext symbol file
ex:
find address from crash report (/Library/Logs/DiagnosticReports/)
Thu Apr 7 15:19:35 2011
panic(cpu 0 caller 0xffffff80002cffca): Kernel trap at 0xffffff8000521c10, type 14=page fault, registers:
CR0: 0x000000008001003b, CR2: 0x0000000000000000, CR3: 0x0000000000100000, CR4: 0x0000000000000660
RAX: 0xffffff800918f260, RBX: 0xffffff8009a45c00, RCX: 0x00000000f25d0000, RDX: 0xffffff80088a5e20
RSP: 0xffffff804a4db790, RBP: 0xffffff804a4db7b0, RSI: 0x0000000020000001, RDI: 0x0000000000000000
R8: 0x000000000000000a, R9: 0x0000000000000000, R10: 0x0000000000000000, R11: 0xffffff80004f3b3a
R12: 0xffffff8008ce1000, R13: 0xffffff8009a45c00, R14: 0xffffff8009a459c0, R15: 0x0000000000000000
RFL: 0x0000000000010246, RIP: 0xffffff8000521c10, CS: 0x0000000000000008, SS: 0x0000000000000000
Error code: 0x0000000000000000
Backtrace (CPU 0), Frame : Return Address
0xffffff804a4db430 : 0xffffff8000204b99
0xffffff804a4db530 : 0xffffff80002cffca
0xffffff804a4db680 : 0xffffff80002e20da
0xffffff804a4db690 : 0xffffff8000521c10
0xffffff804a4db7b0 : 0xffffff8000521408
0xffffff804a4db7e0 : 0xffffff7f806e699a
0xffffff804a4db970 : 0xffffff7f806defca
0xffffff804a4db9e0 : 0xffffff7f806e76f9
0xffffff804a4dba30 : 0xffffff7f8067f5ad
0xffffff804a4dbaa0 : 0xffffff7f806807e2
0xffffff804a4dbba0 : 0xffffff7f80680191
0xffffff804a4dbbd0 : 0xffffff7f80680458
0xffffff804a4dbc50 : 0xffffff7f806e6d30
0xffffff804a4dbcb0 : 0xffffff80005267da
0xffffff804a4dbd20 : 0xffffff80005239bf
0xffffff804a4dbd40 : 0xffffff8000521e78
0xffffff804a4dbd70 : 0xffffff800052649f
0xffffff804a4dbda0 : 0xffffff8000523a07
0xffffff804a4dbde0 : 0xffffff80005267da
0xffffff804a4dbe50 : 0xffffff80005239bf
0xffffff804a4dbd40 : 0xffffff8000521e78
0xffffff804a4dbd70 : 0xffffff800052649f
0xffffff804a4dbda0 : 0xffffff8000523a07
0xffffff804a4dbde0 : 0xffffff80005267da
0xffffff804a4dbe50 : 0xffffff80005239bf
0xffffff804a4dbe70 : 0xffffff8000521e78
0xffffff804a4dbea0 : 0xffffff800052649f
0xffffff804a4dbed0 : 0xffffff8000523a07
0xffffff804a4dbf10 : 0xffffff7f806c276b
0xffffff804a4dbf40 : 0xffffff7f806c09f6
0xffffff804a4dbf60 : 0xffffff800028504e
0xffffff804a4dbfa0 : 0xffffff80002c7387
Kernel Extensions in backtrace (with dependencies):
com.eonpath.driver.TestC(1.0.1)@0xffffff7f806dc000->0xffffff7f806edfff
dependency: com.apple.iokit.IOSCSIBlockCommandsDevice(2.6.5)@0xffffff7f806be000
dependency: com.ift.driver.TestB(1.0.0)@0xffffff7f806ce000
dependency: com.apple.iokit.IOStorageFamily(1.6.2)@0xffffff7f80679000
dependency: com.apple.iokit.IOSCSIArchitectureModelFamily(2.6.5)@0xffffff7f806a5000
com.apple.iokit.IOSCSIBlockCommandsDevice(2.6.5)@0xffffff7f806be000->0xffffff7f806cdfff
dependency: com.apple.iokit.IOSCSIArchitectureModelFamily(2.6.5)@0xffffff7f806a5000
dependency: com.apple.iokit.IOStorageFamily(1.6.2)@0xffffff7f80679000
com.apple.iokit.IOStorageFamily(1.6.2)@0xffffff7f80679000->0xffffff7f80692fff
kextutil -n -s /tmp /System/Library/Extensions/test.kext
-s: location for symbol file
Notice: Using running kernel architecture x86_64 to generate symbols.
No kernel file specified; using running kernel for linking.
/System/Library/Extensions/mpioDriver.kext appears to be loadable (not including linkage for on-disk libraries).
Enter the hexadecimal load addresses for these extensions
(press Return to skip symbol generation for an extension):
com.apple.iokit.IOSCSIArchitectureModelFamily: 0xffffff7f806a5000
com.apple.iokit.IOStorageFamily: 0xffffff7f80679000
com.apple.iokit.IOSCSIBlockCommandsDevice: 0xffffff7f806be000
com.peter.driver.testB: 0xffffff7f806ce000
com.peter.driver.testC: 0xffffff7f806dc000
3. find source code line number that triggers panic:
ex:
gdb /Volumes/KernelDebugKit/mach_kernel
--> set kext-symbol-file-path /tmp
--> add-kext ~/test.kext
--> set print asm-demangle on
--> x/i 0xffffff7f806e699a
find the function mapped to this address
--> disass 0xffffff7f806e699a
show this function's content
--> info line * 0xffffff7f806e699a
show the line number of EIP in the function
kextutil -n -s /tmp /System/Library/Extensions/test.kext
-s: location for symbol file
Notice: Using running kernel architecture x86_64 to generate symbols.
No kernel file specified; using running kernel for linking.
/System/Library/Extensions/mpioDriver.kext appears to be loadable (not including linkage for on-disk libraries).
Enter the hexadecimal load addresses for these extensions
(press Return to skip symbol generation for an extension):
com.apple.iokit.IOSCSIArchitectureModelFamily: 0xffffff7f806a5000
com.apple.iokit.IOStorageFamily: 0xffffff7f80679000
com.apple.iokit.IOSCSIBlockCommandsDevice: 0xffffff7f806be000
com.peter.driver.testB: 0xffffff7f806ce000
com.peter.driver.testC: 0xffffff7f806dc000
->
.sym files are created at /tmp/
.sym files are created at /tmp/
ex:
gdb /Volumes/KernelDebugKit/mach_kernel
--> set kext-symbol-file-path /tmp
--> add-kext ~/test.kext
--> set print asm-demangle on
--> x/i 0xffffff7f806e699a
find the function mapped to this address
--> disass 0xffffff7f806e699a
show this function's content
--> info line * 0xffffff7f806e699a
show the line number of EIP in the function
note:
0xffffff7f806e699a is address for our driver in backtrace
2011年4月6日 星期三
modify entry in ioregistry
OSDictionary *dic = OSDictionary::withCapacity(6);
OSNumber *index = OSNumber::withNumber(100, 32);
dic->setObject("TEST_INDEX", index);
index->release();
this->setProperty("TEST_DIC", dic);
dic->release();
index->setValue(1);
note:
we can not modify collection directly
Following code will trigger crash
dic->setObject("testIndex", OSNumber::withNumber(200, 32));
If we want to add or delete entry in collection,
we must create new collection and use setProperty to replace old collection
OSNumber *index = OSNumber::withNumber(100, 32);
dic->setObject("TEST_INDEX", index);
index->release();
this->setProperty("TEST_DIC", dic);
dic->release();
index->setValue(1);
note:
we can not modify collection directly
Following code will trigger crash
dic->setObject("testIndex", OSNumber::withNumber(200, 32));
If we want to add or delete entry in collection,
we must create new collection and use setProperty to replace old collection
mac driver command
ioclasscount
displays the instance counts of OSObject-based C++ classes in the kernel
ex:
ioclasscount | grep My
->
com_MyCompany_driver_MyDriver = 1
kextutil:
load, diagnose problems with, and generate symbols for kernel extensions
ex:
kextutil test.kext
displays the instance counts of OSObject-based C++ classes in the kernel
ex:
ioclasscount | grep My
->
com_MyCompany_driver_MyDriver = 1
kextutil:
load, diagnose problems with, and generate symbols for kernel extensions
ex:
kextutil test.kext
iokit driver
TestIokit.h
#include <IOKit/IOService.h>
class com_MyCompany_driver_MyDriver : public IOService
{
OSDeclareDefaultStructors(com_MyCompany_driver_MyDriver)
public:
virtual bool init(OSDictionary *dictionary = 0);
virtual void free(void);
virtual IOService *probe(IOService *provider, SInt32 *score);
virtual bool start(IOService *provider);
virtual void stop(IOService *provider);
};
TestIokit.cpp
#include <IOKit/IOLib.h>
#include "MyDriver.h"
// This required macro defines the class's constructors, destructors,
// and several other methods I/O Kit requires.
OSDefineMetaClassAndStructors(com_MyCompany_driver_MyDriver, IOService)
// Define the driver's superclass.
#define super IOService
bool com_MyCompany_driver_MyDriver::init(OSDictionary *dict)
{
bool result = super::init(dict);
IOLog("Initializing\n");
return result;
}
void com_MyCompany_driver_MyDriver::free(void)
{
IOLog("Freeing\n");
super::free();
}
IOService *com_MyCompany_driver_MyDriver::probe(IOService *provider,
SInt32 *score)
{
IOService *result = super::probe(provider, score);
IOLog("Probing\n");
return result;
}
bool com_MyCompany_driver_MyDriver::start(IOService *provider)
{
bool result = super::start(provider);
IOLog("Starting\n");
return result;
}
void com_MyCompany_driver_MyDriver::stop(IOService *provider)
{
IOLog("Stopping\n");
super::stop(provider);
}
#include <IOKit/IOService.h>
class com_MyCompany_driver_MyDriver : public IOService
{
OSDeclareDefaultStructors(com_MyCompany_driver_MyDriver)
public:
virtual bool init(OSDictionary *dictionary = 0);
virtual void free(void);
virtual IOService *probe(IOService *provider, SInt32 *score);
virtual bool start(IOService *provider);
virtual void stop(IOService *provider);
};
TestIokit.cpp
#include <IOKit/IOLib.h>
#include "MyDriver.h"
// This required macro defines the class's constructors, destructors,
// and several other methods I/O Kit requires.
OSDefineMetaClassAndStructors(com_MyCompany_driver_MyDriver, IOService)
// Define the driver's superclass.
#define super IOService
bool com_MyCompany_driver_MyDriver::init(OSDictionary *dict)
{
bool result = super::init(dict);
IOLog("Initializing\n");
return result;
}
void com_MyCompany_driver_MyDriver::free(void)
{
IOLog("Freeing\n");
super::free();
}
IOService *com_MyCompany_driver_MyDriver::probe(IOService *provider,
SInt32 *score)
{
IOService *result = super::probe(provider, score);
IOLog("Probing\n");
return result;
}
bool com_MyCompany_driver_MyDriver::start(IOService *provider)
{
bool result = super::start(provider);
IOLog("Starting\n");
return result;
}
void com_MyCompany_driver_MyDriver::stop(IOService *provider)
{
IOLog("Stopping\n");
super::stop(provider);
}
gcd: Grand Central Dispatch
provide a number of predefined queues
we can create our own queue
queue is FIFO
we can create our own queue
queue is FIFO
block in Objective-C
also known as closures or lambdas
block syntax:
1. ^
2. ( parameterType parameterName )
3. { code to be executed }
ex:
// declare a block variable test
void (^test)(void);
// define block's code
test = ^ { NSLog("test"); };
// execute block
test();
ex:
void (^test)(void) = ^ { NSLog("test"); };
block syntax:
1. ^
2. ( parameterType parameterName )
3. { code to be executed }
ex:
// declare a block variable test
void (^test)(void);
// define block's code
test = ^ { NSLog("test"); };
// execute block
test();
ex:
void (^test)(void) = ^ { NSLog("test"); };
solaris service
steps to create service:
1. Create a service manifest file.
this file defines dependency and start/stop script location
ex:
nfs server's manifest file
/lib/svc/manifest/network/nfs/server.xml
content ex:
<exec_method
type='method'
name='start'
exec='/lib/svc/method/nfs-server %m'
timeout_seconds='3600' />
2. Create a methods script file to define the start, stop, and restart methods for the service.
ex:
nfs server's script
/lib/svc/method/nfs-server
3. Validate and import the service manifest using svccfg(1M).
4. Enable or start the service using svcadm(1M).
5. Verify the service is running using svcs(1).
1. Create a service manifest file.
this file defines dependency and start/stop script location
ex:
nfs server's manifest file
/lib/svc/manifest/network/nfs/server.xml
content ex:
<exec_method
type='method'
name='start'
exec='/lib/svc/method/nfs-server %m'
timeout_seconds='3600' />
2. Create a methods script file to define the start, stop, and restart methods for the service.
ex:
nfs server's script
/lib/svc/method/nfs-server
3. Validate and import the service manifest using svccfg(1M).
4. Enable or start the service using svcadm(1M).
5. Verify the service is running using svcs(1).
訂閱:
文章 (Atom)