• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Problems with open() and close()
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problems with open() and close()


  • Subject: Re: Problems with open() and close()
  • From: Cem Karan <email@hidden>
  • Date: Mon, 7 Aug 2006 07:41:48 -0400

You are using pseudo-terminals, not serial port is that correct?

That is currently correct. I'm trying to make testing easier on myself so I can move over to the actual serial port with the least amount of fuss that I can get away with.


In this case the exclusive flag doesn't get cleared until both sides of the port get closed. On a serial port the t_state variable is set to 0 on close, but you pseudo-terminals are sort of 2 serial ports in one and they share most of their state.

I didn't know that, thank you! The real question then is, how do I cleanly close() them? As you can guess, I have very little experience in UNIX specific code. I would like to be able to use this wrapper for both pseudo-terminals and actual serial ports, ideally in a manner that hides any strangeness from the higher level code completely.


Thanks,
Cem Karan

On 04/08/2006, at 2:34 AM, Cem Karan wrote:

Hi all, first time poster to this list, hope that this is right list to post to...

I've adapted some code to my own uses (shown below) but have run into an odd problem, and I'm hoping that someone can explain what is going on to me. As a part of my open_TTY_OSX() function, I call ioctl(context->fileDescriptor, TIOCEXCL), which prevents any non-root program from opening the same device. Now this is where it gets odd for me. I am testing all this code using some unit tests that I wrote. The unit tests call open_TTY_OSX() and then balance the call with a call to close_TTY_OSX() on the same file descriptor. Originally, I did NOT have the ioctl(context- >fileDescriptor, TIOCNXCL) call in close_TTY_OSX(), and the result was that if I tried to open the same device again, it would fail with EBUSY. So basically:

open_TTY_OSX("/dev/ttyp1", foo) // no problem
close_TTY_OSX(foo) // no problem
open_TTY_OSX("/dev/ttyp1, bar) // Fails with EBUSY


Well, I figured that this isn't that big a deal, I just let my process exit nicely, and the restart the debugging session, right? No good. The only way for me to make things play nice is to quit XCode, and even that doesn't seem to work 100% of the time. My question is why? When I close, I reset the attributes, and I close() the descriptor. That should make the blocking part go away, right? What am I doing wrong?

Oh, note that adjAssert() is a macro like assert(); I just hacked in some extra stuff that I needed, and didn't want the names conflicting.

Thanks for any help,
Cem Karan


#define ERROR_CLOSE_FD_TTY_OSX_PRIVATE (FD) \
{ \
struct stat myStat; \
perror (NULL); \
fflush (stderr); \
fflush (stdout); \
if (FD != -1) \
{ \
printf("Closing file descriptor"); \
fstat(FD, &myStat); \
close (FD); \
} \
}


boolean_t open_TTY_OSX(char *devicePath, OSX_TTYcontext context)
{
    size_t counter;

    adjAssert((devicePath != NULL) && (context != NULL));
    if ((devicePath == NULL) || (context == NULL))
        return false;

context->fileDescriptor = open(devicePath, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (context->fileDescriptor == -1){
ERROR_CLOSE_FD_TTY_OSX_PRIVATE(context->fileDescriptor);
return false;
}


if (tcgetattr(context->fileDescriptor, &(context->original)) == -1) {
printf("Error getting tty attributes %s - %s(%d).\n",
devicePath, strerror(errno), errno);
ERROR_CLOSE_FD_TTY_OSX_PRIVATE(context->fileDescriptor);
return false;
}


memcpy(&(context->current), &(context->original), sizeof (struct termios));

    if (ioctl(context->fileDescriptor, TIOCEXCL) == -1) {
        ERROR_CLOSE_FD_TTY_OSX_PRIVATE(context->fileDescriptor);
        return false;
    }

    if (fcntl(context->fileDescriptor, F_SETFL, 0) == -1) {
        ERROR_CLOSE_FD_TTY_OSX_PRIVATE(context->fileDescriptor);
        return false;
    }

    if (fcntl(context->fileDescriptor, F_NOCACHE, 1) == -1) {
        ERROR_CLOSE_FD_TTY_OSX_PRIVATE(context->fileDescriptor);
        return false;
    }

    for (counter = 0; counter < NCCS; counter++)
        (context->current).c_cc[counter] = _POSIX_VDISABLE;

    cfmakeraw(&(context->current));

    (context->current).c_cc[VMIN]   = 1;
    (context->current).c_cc[VTIME]  = 1;
    cfsetspeed(&(context->current), B57600); 	/* Set 57600 baud */

    (context->current).c_cflag |= (CS8 | CREAD | CLOCAL);

if (tcsetattr(context->fileDescriptor, TCSANOW, &(context- >current)) == -1) {
ERROR_CLOSE_FD_TTY_OSX_PRIVATE(context->fileDescriptor);
return false;
}


    return true;
}

void close_TTY_OSX(OSX_TTYcontext context)
{
    int result;
    adjAssert(context != NULL);

    if (tcdrain(context->fileDescriptor) == -1) {
        printf("Error waiting for drain - %s(%d).\n",
            strerror(errno), errno);
    }

    if (ioctl(context->fileDescriptor, TIOCNXCL) == -1) {
        ERROR_CLOSE_FD_TTY_OSX_PRIVATE(context->fileDescriptor);
    }

if (tcsetattr(context->fileDescriptor, TCSANOW, &(context- >original)) == -1) {
printf("Error resetting tty attributes - %s(%d).\n",
strerror(errno), errno);
}


    result = close(context->fileDescriptor);
    if (result != 0)
        perror(NULL);
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >Problems with open() and close() (From: Cem Karan <email@hidden>)
 >Re: Problems with open() and close() (From: Godfrey van der Linden <email@hidden>)

  • Prev by Date: Re: How to get IPv6 address using getifaddrs and which version of glibc supports
  • Next by Date: Apple Opens Up: Kernel, Mac OS Forge, iCal Server, Bonjour, Launchd
  • Previous by thread: Re: Problems with open() and close()
  • Next by thread: Total RAM slot count obtained programatically
  • Index(es):
    • Date
    • Thread