Handling fcntl constants on windows

As part of my GSoC project of implementing the Tiff class, I want to prevent the user from calling methods that modify the image like write or setTag if the image is opened in read-only mode.

LibTIFF stores and returns the file mode using constants like O_RDONLY and O_RDRW which are defined in the fcntl.h header file which, AFAIK, doesn’t exist on windows.

I found that Octave has wrappers for these constants (e.g. octave_o_rdonly_wrapper) and they seem to return the right values on windows. But the source code of the wrappers seems to have a failure case if it fails to find the constants and I’m not sure when would such case occur and I wouldn’t like my implementation to have a hidden dependency for something as minor as this.

So I wanted to ask if someone knows more information about this and what is the right thing to do for windows in this situation.

so the read/write state is not a property of the class stored upon object creation? if that could be done it would be fairly simple to have write, setTag, etc. fail if e.g., propRW=‘r’.

1 Like

I understand what you propose but I am trying to avoid this method because nearly all the implementation is in C++ so having a lot of logic on the Octave side is not ideal because I would need to keep wrapping and unwrapping data needed in both sides in octave_values, and I can’t store properties from the C++ side so this property will have to be on the Octave side.

Basically I think the LibTIFF approach will be cleaner if it is reliable, but if it isn’t then I think I will have to go with the method you mentioned.

It’s complicated, but Octave uses gnulib which is a cross-platform tool that provides working implementations for common UNIX code. Octave is guaranteed to have a working fcntl.h available and you can use O_RDONLY, etc. always.

1 Like

To avoid including fcntl.h directly in Octave sources and possibly importing undesirable macro definitions, we have wrapper functions for those constants. So please use the wrapper functions to get the values instead of using the macros directly.

2 Likes

Since the reporter is writing code in C++, does this mean

  static int O_RDONLY = octave_o_rdonly_wrapper ();

at the top of a C++ file to create file static variable with the necessary value? Or is there some other construct that is clearer/easier?

So please use the wrapper functions to get the values instead of using the macros directly.

I think that’s a good way, yes. Maybe static const int? I’m not sure whether we make that (small) optimization in the Octave sources, but it would be reasonable to do so.

We don’t make that minor modification, but we could. This is an example from syscalls.cc

  static int val = octave_f_dupfd_wrapper ();

The function itself is in liboctave/wrappers/fcntl-wrappers.[c|h]

extern OCTAVE_API int octave_f_dupfd_wrapper (void);

with implementation

int
octave_f_dupfd_wrapper (void)
{
#if defined (F_DUPFD)
  return F_DUPFD;
#else
  return -1;
#endif
}

Since everything is known at compile-time, it would be best if we could use constexpr back in syscalls.cc, but this produces a compile error because the function hasn’t been defined with that attribute. And, since this is gnulib and we are specifically using C compilation; I don’t think that can change (correct?). So, I believe the best we could do is write

  static const int val = octave_f_dupfd_wrapper ();

The only thing this buys us is clarity that this value is supposed to be const, read-only and calculated once. That’s not a bad thing, but I don’t think we can get the compiler to move this out of a run-time calculation and initialization of a variable and instead just have a RO constant in the program file.

Edit (8/13/22): I added the const keyword in this changeset octave: 0a2bf14dd400.

1 Like