How to open USB device in OSX - macos

I'm finally able to get the device path ("/dev/rdisk1") - called devname here - after a search but POSIX open() fails with -1. Is this a permission issue? The camera is mounted and can be read normally via /Volumes but I need to access via /dev to control the camera via USB tether.
/* Found PENTAX DIGITAL_CAMERA */
snprintf(pslr.devname, sizeof(pslr.devname), "%s", devpath);
pslr.devname[sizeof(pslr.devname)-1] = '\0';
printf("pslr.devname %s\n", pslr.devname);
pslr.fd = open(pslr.devname, O_RDWR);
if (pslr.fd == -1) {
return NULL;
}
PS: after the discussion below I changed the permissions with sudo chmod command and then tried open but it still fails. I must be missing a step.

I checked with apple support and they say I cannot use posix functions to control a USB device in OS X.

Related

Why nfsd clears S_ISUID bit in SETATTR if I try to set S_ISUID and owner at the same time?

NFSv3 protocol specifies that SETATTR can set file/dir mode and owner at the same time (as well as few other things). And yet Linux implementation of nfsd behaves in a quite strange way:
/* Revoke setuid/setgid on chown */
if (!S_ISDIR(inode->i_mode) &&
((iap->ia_valid & ATTR_UID) || (iap->ia_valid & ATTR_GID))) {
iap->ia_valid |= ATTR_KILL_PRIV;
if (iap->ia_valid & ATTR_MODE) {
/* we're setting mode too, just clear the s*id bits */
iap->ia_mode &= ~S_ISUID;
if (iap->ia_mode & S_IXGRP)
iap->ia_mode &= ~S_ISGID;
} else {
/* set ATTR_KILL_* bits and let VFS handle it */
iap->ia_valid |= (ATTR_KILL_SUID | ATTR_KILL_SGID);
}
}
What is the reason for this? I spent a lot of time tracking it down in some old app (that for some reason could not copy a file via NFS without losing suid bit). Is it a bug? It happens even if new owner is the same.
Disabling SUID is some sort of protection against untrusted NFS servers: If administrator of your local machine doesn't trust the NFS server, it cannot afford to execute files from the server with root privileges. See also article NFS, no_root_squash and SUID - Basic NFS Security.
It is a bug in Linux implementation of NFS server. See NFS specs.

Find process where a particular system call returns a particular error

On OS X El Capitan, my log file system.log feels with hundreds of the following lines at times
03/07/2016 11:52:17.000 kernel[0]: hfs_clonefile: cluster_read failed - 34
but there is no indication of the process where this happens. Apart from that, Disk Utility could not find any fault with the file system. But I would still like to know what is going on and it seems to me that dtrace should be perfectly suited to find out that faulty process but I am stuck. I know of the function return probe but it seems to require the PID, e.g.
dtrace -n 'pidXXXX::hfs_clonefile:return { printf("ret: %d", arg1); }'
Is there a way to tell dtrace to probe all processes? And then how would I print the process name?
You can try something like this (I don't have access to an OS X machine to test it)
#!/usr/sbin/dtrace -s
# pragma D option quiet
fbt::hfs_clonefile:return
/ args[ 1 ] != 0 /
{
printf( "\n========\nprocess: %s, pid: %d, ret value: %d\n", execname, pid, args[ 1 ] );
/* get kernel and user-space stacks */
stack( 20 );
ustack( 20 );
}
For the fbt probes, args[ 1 ] is the value returned by the function.
The dTrace script will print out the process name, pid, and return value from hfs_clonefile() whenever the return value is not zero. It also adds the kernel and user space stack traces. That should be more than enough data for you to find the source of the errors.
Assuming it works on OS X, anyway.
You can use the syscall provider rather than the pid provider to do this sort of thing. Something like:
sudo dtrace -n 'syscall::hfs_clonefile*:return /errno != 0/ { printf("ret: %d\n", errno); }'
The above command is a minor variant of what's used within the built-in DTrace-based errinfo utility. You can view /usr/bin/errinfo in any editor to see how it works.
However, there's no hfs_clonefile syscall, as least as far as DTrace is concerned, on my El Capitan (10.11.5) system:
$ sudo dtrace -l -n 'syscall::hfs*:'
ID PROVIDER MODULE FUNCTION NAME
dtrace: failed to match syscall::hfs*:: No probe matches description
Also, unfortunately the syscall provider is prevented from tracing system processes by the System Integrity Protection feature introduced with El Capitan (macOS 10.11). So, you will have to disable SIP which makes your system less secure.

NFS mount System Call in linux

I am trying to mount a source directory from nfs server to a destination directory in embedded board having linux. The following command works perfectly as expected in shell prompt in the board.
mount -t nfs -o nolock 10.126.62.45:/vol/home/avinoba/Sky /mnt
What is the equivalent system call to be used in program for the command above?
I tried the below call but the mount failed with "Invalid Argument"
if(mount("10.126.62.45:/vol/home/avinoba/Sky","/mnt","nfs",MS_MGC_VAL,"nolock") == -1)
{
printf("ERROR: mount failed: %s \n",strerror(errno));
}
Please suggest what is the solution for it.
Thanks
I'm quite surprised here knowing that how this is not covered by any man page regarding NFS mounts. Diving into the kernel code, in the function nfs_validate_text_mount_data, the function nfs_parse_mount_options is responsible for parsing the multiple comma separated options passed as the fifth argument in the mount system call.
struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
if (nfs_parse_mount_options((char *)options, args) == 0)
return -EINVAL;
if (!nfs_verify_server_address(sap))
goto out_no_address;
In the above code block, the last if statement checks whether the nfs server address and socket family is defined to valid values. If they are not updated within nfs_parse_mount_options, mount would end up returning invalid parameter.
If the implementation of nfs_parse_mount_options is walked through, it can be seen that, only for the case Opt_addr, the nfs server address and the socket family is updated by parsing the options argument.
case Opt_addr:
string = match_strdup(args);
if (string == NULL)
goto out_nomem;
mnt->nfs_server.addrlen =
rpc_pton(mnt->net, string, strlen(string),
(struct sockaddr *)
&mnt->nfs_server.address,
sizeof(mnt->nfs_server.address));
kfree(string);
if (mnt->nfs_server.addrlen == 0)
goto out_invalid_address;
break;
The case Opt_addr corresponds to the option "addr=nfs server ip". So for the system call to work, defining this option is a must. As far as I have searched, this is completely missing from all the man pages which describes nfs mounts.
So now considering the problem statement, please try by changing to the below code
if(mount(":/vol/home/avinoba/Sky","/mnt","nfs",0,"nolock,addr=10.126.62.45") == -1)
{
printf("ERROR: mount failed: %s \n",strerror(errno));
}
Also note that when the addr option is put in the argument, the ip address in front of the nfs server path becomes optional. However the ':' is must,as this acts as the delimiter to parse the nfs server path.
MS_MGC_VAL should be in the top 16 bits if needed, not the bottom. If your kernel version is > 2.4, you don't need it at all.
It solved by the following call for me now.
if(system("mount -t nfs -o nolock 10.126.62.45:/vol/home/avinoba/Sky /mnt")==-1);
{
printf("ERROR: mount failed \n");
}
But still searching for the answer with mount() call as it accepts 'filesystemtype' argument as "nfs".

looking for more info on EIO error returned by readdir_r () on Mac OS X

On Mac OS X 10.6.8, some C code that calls readdir_r() sometimes gets an I/O error 5 (EIO) returned. I've seen this just a few times, always on external USB drives. Each time I've seen it, if I immediately cd to the parent direction and do an ls, I appear to see all the files. And, if I re-run the C program that saw the error, it will run fine.
On some platforms, when one gets an error like EIO, there's something else you can call that gives you much more detailed error information (e.g., hperrmsg on MPE/iX, which accesses the per-process error stack). Is there something similar on OS X?
I guess I'm assuming that the error is false
i = readdir_r (dirp, &dire, &dire_ptr);
save_errno = errno;
if (i)
{
if (i == EACCES)
...
else
{
my_perror (save_errno, "readdir_r failed: ");
espout4 ("readdir_r returned %s; errno = %s, dire_ptr = %s; parent = %s\n",
num64 (i), num64 (save_errno), fmt_p (dire_ptr), parent_dir);
espout1 (" (ERROR: readdir_r failed here, errno %s)\n", num64 (save_errno));
}
}
Update, a week later...
I've determined that the combo of the Macally case (model G-S350SU)
and the Western Digital drive was causing sporadic problems. I noticed that the WD SATA connector didn't mate tightly with the Macally socket. Using a Seagate drive with the case was fine, and using the WD drive in a different case was fine.
Of course, I'd still like to be able to get better / more detailed error information in my programs :)

Can I ask dtrace what probes are enabled?

If it matters, I am using Mac OS X, but I believe this would apply across OSs. If the answer is different per OS, I would be interested in learning about that as well.
Let's say that I open a terminal window, enable a few probes, and start collecting data with DTrace.
From a different terminal window, can I ask DTrace what probes have been enabled? If so, how?
I got the following information from Adam Leventhal on a DTrace mailing list. First, he provided this script, which works on Solaris
#!/usr/sbin/dtrace -s
#pragma D option quiet
int i;
tick-100
/i >= `dtrace_nprobes/
{
exit(0);
}
tick-100
{ printf("%4d %10s %20s %20s %10s %s\n", i,
stringof(`dtrace_probes[i]->dtpr_provider->dtpv_name),
stringof(`dtrace_probes[i]->dtpr_mod),
stringof(`dtrace_probes[i]->dtpr_func),
stringof(`dtrace_probes[i]->dtpr_name),
`dtrace_probes[i]->dtpr_ecb != NULL ? "enabled" : "disabled");
i++
}
Unfortunately, the same kernel variables are not available on Mac OS X due to a bug.

Resources