mc-4.8.20 vs AIX7

Nem fordul, nyilván; AIX6-on fordul, de ez ugye AIX7.


file.c: In function 'get_times':
file.c:668:17: error: incompatible types when assigning to type 'struct timespec' from type 'st_timespec_t' {aka 'const struct st_timespec'}
     (*times)[0] = sb->st_atim;
                 ^
file.c:669:17: error: incompatible types when assigning to type 'struct timespec' from type 'st_timespec_t' {aka 'const struct st_timespec'}
     (*times)[1] = sb->st_mtim;

Hozzászólások

Benéztem volna valamit? Nekem ez sima struct-copynak tűnik, ha pedig a két struct-ban ugyanaz van, akkor copy-hoz a typecast, vagy a memcpy() is jó. Ha nem ugyanaz van a két struct-ban, akkor nyilván nem jó, de épp ezért kérdeztem rá, hogy ugyanaz van-e bennük. Ha meg az a baj, hogy gány...hát ezért mondtam, hogy hotfixnek, hogy leforduljon, nem azt, hogy ezt merge-eljék.

Szól érte:

typedef struct struct1
{
	int sub1, sub2;
} struct1_t;

typedef struct struct2
{
	int sub1, sub2;
} struct2_t;

int main(int argc, char *argv[])
{
	struct1_t s1;
	struct2_t s2;

	s1 = s2;
}
# gcc x.c
x.c: In function ‘main’:
x.c:16:7: error: incompatible types when assigning to type ‘struct1_t’ {aka ‘struct struct1’} from type ‘struct2_t’ {aka ‘struct struct2’}
   16 |  s1 = s2;
      |       ^~

Ottan a time_t/long/int stb videken lehet a kutya elasva. Az egyiknel int, a maskinal long a nanosec, cserebe az int meg a long mar nem ugyanaz. Peldaul.  

Szerkesztve: 2023. 04. 15., szo – 16:21
    664 static void
    665 get_times (const struct stat *sb, mc_timesbuf_t * times)
    666 {
    667 #ifdef HAVE_UTIMENSAT
    668     (*times)[0] = sb->st_atim;
    669     (*times)[1] = sb->st_mtim;
    670 #else
    671     times->actime = sb->st_atime;
    672     times->modtime = sb->st_mtime;
    673 #endif
    674 }

Ez lenne az:


       int utimensat (DirFileDescriptor, Path, Times, Flag)
       int DirFileDescriptor;
       char *Path;
       struct timespec Times[2];
       int Flag;

struct timespec {
 time_t tv_sec;
 long tv_nsec;
};

Valamint ez:

typedef struct st_timespec {
 time_t tv_sec;
 int tv_nsec;
} st_timespec_t;
Szerkesztve: 2023. 04. 15., szo – 16:25

Valamint ez:


struct stat
{
 dev_t st_dev;
 ino_t st_ino;
 mode_t st_mode;
 nlink_t st_nlink;
 ushort_t st_flag;
 uid_t st_uid;
 gid_t st_gid;
 dev_t st_rdev;
 soff_t st_ssize;
 st_timespec_t st_atim;
 st_timespec_t st_mtim;
 st_timespec_t st_ctim;
 blksize_t st_blksize;
 blkcnt_t st_blocks;
 int st_vfstype;
 uint_t st_vfs;
 uint_t st_type;
 uint_t st_gen;
 uint_t st_reserved[10];
 off64_t st_size;
};

Szinte biztos, hogy ez a kavarás a 'timespec'-cel és 'st_timespec_t'-vel valamilyen kompatibilitási probléma megoldására van.

Köszönöm, végül ez lett a megoldás, ilyesmi:

sed 's/(\*times)\[0\] = sb->st_atim;/(*times)[0].tv_sec = sb->st_atim.tv_sec;(*times)[0].tv_nsec = sb->st_atim.tv_nsec;/
     s/(\*times)\[1\] = sb->st_mtim;/(*times)[1].tv_sec = sb->st_mtim.tv_sec;(*times)[1].tv_nsec = sb->st_mtim.tv_nsec;/
    ' src/filemanager/file.c.orig >src/filemanager/file.c

Van is egy ilyen okosság a sys/stat.h-ban:

#if _XOPEN_SOURCE>=700
#ifdef _ALL_SOURCE
  st_timespec_t st_atim;  /* Time of last access */
  st_timespec_t st_mtim;  /* Time of last data modification */
  st_timespec_t st_ctim;  /* Time of last file status change */
#else
  struct timespec st_atim;/* Time of last access */
  struct timespec st_mtim;/* Time of last data modification */
  struct timespec st_ctim;/* Time of last file status change */
#endif
#else
  time_t st_atime;        /* Time of last access */
  int    st_atime_n;
  time_t st_mtime;        /* Time of last data modification */
  int    st_mtime_n;
  time_t st_ctime;        /* Time of last file status change */
  int    st_ctime_n;
#endif

Hogy milyen jól sikerült a kompatibilitási probléma megoldása, azt tesztprogrammal is bebizonyíthatjuk:


/* default:                         mtime=1681573187.209315433
   _ALL_SOURCE=1:                   mtime=1681573187.209315433
   _XOPEN_SOURCE=700:               mtime=1681573187.899002939283079168
   _XOPEN_SOURCE=700 _ALL_SOURCE=1: mtime=1681573187.209315433
 */
#include 
#include 

int main(void) {
    struct stat stbuff;
    stat("Makefile", &stbuff);
    printf("%s: mtime=%lld.%lld\n"
           , "Makefile"
           , (long long)stbuff.st_mtim.tv_sec
           , (long long)stbuff.st_mtim.tv_nsec);
    return 0;
}

Az újabb mc verziókban van egy ilyen rész a configure.ac-ben:

dnl utimensat is supported since glibc 2.6 and specified in POSIX.1-2008
dnl utimensat() causes different timespec structures to cause failures on IBM i and AIX
case $host_os in
*os400 | aix*)
    ;;

A 'struct stat' a sys/stat.h-ból jön, sajnos különféle define-októl függ a tartalma, van fentebb egy példa arra, hogy bizonyos opciók esetén `long` (int64_t) a nanosec, ami jószándékra vall ugyan, de nem kompatibilis a stat-rendszerhívás által visszaadott `int`-tel (int32_t). (Az illesztési követelmény miatt (time_t=int64_t) az egyes nanosec mezők ugyanott vannak, tehát little endian platformon még menne is a dolog, de ez big endian, itt nem jó.)

A 'mc_timesbuf_t' a Mindnight Commander tipusa (egyébként kétségtelenül igyekeznek ők mindenféle platformot szupportálni, de azért azt látni kell, hogy nem az Aix a figyelem fókusza).

A stat.h tartamát a POSIX írja elő?
Arra gondolok, hogy ha már arra hivatkoznak, hogy POSIX.1-2008-tól van utimensat, akkor nézzük már meg, hogy a POSIX.1-2008 mit tartalmaz stat.h téren.

https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/

Itt bizony az van, hogy az st_atim és st_mtim-nek struct timespec a típusa.

Azaz ha nálad st_timespec_t van, és az nem ugyanaz, mint a struct timespec, akkor bizony az AIX a ludas.

Ugyebár az AIX 7 az UNIX V7 certified: https://www.opengroup.org/openbrand/register/ibm.htm

Ami pedig ugye POSIX.1-2017-et jelent.

Ez az st_timespec_t nem is értem, hogy honnan jön, ilyet a POSIX nem ismer. Minek ez, ha ott a timespec, ami a szabványos struktúra.

Én itt most az AIX-ra haragudnék, nem az mc-re.

A fent idézett #ifdef __ALL_SOURCE totál értelmetlennek tűnik nekem.

Pontosabban mondva, a tényleges rendszerhívás ilyen szerkezetben adja vissza az információt:

sec 64-bit
nsec 32-bit
unused 32-bit (gondolom, kinullázza)

Posix barátunk a következőt írja elő (timespec):

sec 64-bit
nsec 64-bit (ebből a felső 33 bit mindig nulla)

Ez a kettő big endian platformon sosem lesz kompatibilis, pl. az 1025ns így jön ki a rendszerhívásból: 00 00 04 01 00 00 00 00, ami 64 bitesen értelmezve 1025*2^32

Szerkesztve: 2023. 04. 17., h – 13:14

Ez miért nem felelt meg?

"
:/home/root] # dnf search mc
=========================================================== Name Exactly Matched: mc ===========================================================
mc.ppc : User-friendly text console file manager and visual shell.

"

/home/root] # oslevel -s
7200-05-03-2147