Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <4154233B.2000305@tcd.ie> Date: Fri, 24 Sep 2004 14:38:03 +0100 From: david moloney User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.3) Gecko/20040910 MIME-Version: 1.0 To: david moloney Cc: cygwin AT cygwin DOT com Subject: Re: Porting question: cygwin equivalent of Linux getdirentries()? References: <4154231F DOT 8050303 AT tcd DOT ie> In-Reply-To: <4154231F.8050303@tcd.ie> Content-Type: multipart/mixed; boundary="------------000402030208010603020006" X-AntiVirus: checked by Vexira MailArmor (version: 2.0.1.16; VAE: 6.27.0.12; VDF: 6.27.0.71; host: smtp3.tcd.ie) --------------000402030208010603020006 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Whoops ... forgot the code. - D. david moloney wrote: > I have a piece of Linux code I'm trying to port to cygwin which uses > sgtty.h (ioctl) and dirent.h (getdirentries) functions which are not > present in cygwin. Also endian.h was missing but I copied it over > from RedHat and that seems to work. I got round the sgetty problems > by using #ifdef __CYGWIN__ to patch in termios.h equivalents. But on > the dirent.h front the dirent struct in Cygwin is different from Linux > in that it has a long where Linux has an unsigned short ... I patched > it anyway and it compiles OK > > #ifndef __CYGWIN__ > counter < READ_GPR(V0_REG) && direntp->d_reclen > 0; > i++, counter += direntp->d_reclen, direntp=(struct dirent > *)(buffer+counter)) { > #else > counter < READ_GPR(V0_REG) && direntp->d_fd > 0; > i++, counter += direntp->d_fd, direntp=(struct dirent > *)(buffer+counter)) { > #endif > > The only problem remaining is I cannot find a cygwin equivalent of > getdirentries in Linux dirent.h and the program fails to link. I have > patched out the reference in the attached file and it compiles but > will obviously not work. > > Do any of you know what cygwin function I could use in place of > getdirentries()? > > I've tried googling for the past day and a half to no avail. > > Many thanks, > > - David > --------------000402030208010603020006 Content-Type: text/plain; name="sys_call.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sys_call.c" /*************************************************************************** sys_call.c - Alpha OS system calls emulation ------------------- begin : Mar 22 2003 copyright : (C) 2003 CEA and Universite Paris Sud author : Daniel Gracia Perez email : gracia AT lri DOT fr ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /** @brief Alpha OS system call emulator @file sys_call.c */ #ifdef linux #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #endif #include #include #include #include #include #include #include #include #include #include #ifndef __CYGWIN__ #include #include #else //#define __CYGWIN_USE_BIG_TYPES__ #endif #include #include #include #include #define MEM_WRITE(addr,buf,size) handler->mem_write_buf(handler->instance,addr,buf,size) #define MEM_READ(buf,addr,size) handler->mem_read_buf(handler->instance,buf,addr,size) #define READ_GPR(i) handler->read_gpr(handler->instance, i) #define WRITE_GPR(i,x) handler->write_gpr(handler->instance, i, x) #define SYSCALL_NUM READ_GPR(0) /** syscall ids */ #define SYSCALL_syscall 0 #define SYSCALL_exit 1 #define SYSCALL_read 3 #define SYSCALL_write 4 #define SYSCALL_close 6 #define SYSCALL_unlink 10 #define SYSCALL_obreak 17 #define SYSCALL_lseek 19 #define SYSCALL_getpid 20 #define SYSCALL_getuid 24 #define SYSCALL_dup 41 #define SYSCALL_open 45 #define SYSCALL_getgid 47 #define SYSCALL_sigprocmask 48 #define SYSCALL_ioctl 54 #define SYSCALL_getpagesize 64 #define SYSCALL_stat 67 #define SYSCALL_lstat 68 #define SYSCALL_mmap 71 #define SYSCALL_table 85 #define SYSCALL_fstat 91 #define SYSCALL_fcntl 92 #define SYSCALL_gettimeofday 116 #define SYSCALL_getrusage 117 #define SYSCALL_rename 128 #define SYSCALL_ftruncate 130 #define SYSCALL_getrlimit 144 #define SYSCALL_setrlimit 145 #define SYSCALL_sigaction 156 #define SYSCALL_getdirentries 159 #define SYSCALL_statfs 160 #define SYSCALL_usleep_thread 251 #define SYSCALL_setsysinfo 257 /** ALPHA OSF ioctl() identifiers */ #define ALPHA_TIOCGETP 0x40067408 #define ALPHA_FIONREAD 0x4004667f #define ALPHA_SIG_BLOCK 1 #define ALPHA_SIG_UNBLOCK 2 #define ALPHA_SIG_SETMASK 3 /** emulated alpha signal mask */ uint64_t sigmask = 0; #define BUFFER_SIZE 1024 /** alpha open flags */ #define ALPHA_O_RDONLY 0x0000 #define ALPHA_O_WRONLY 0x0001 #define ALPHA_O_RDWR 0x0002 #define ALPHA_O_NONBLOCK 0x0004 #define ALPHA_O_APPEND 0x0008 #define ALPHA_O_CREAT 0x0200 #define ALPHA_O_TRUNC 0x0400 #define ALPHA_O_EXCL 0x0800 #define ALPHA_O_NOCTTY 0x1000 #define ALPHA_O_SYNC 0x4000 /** alpha open flags translation table */ struct { int alpha_flag; int local_flag; } alpha_flag_table[] = { { ALPHA_O_RDONLY, O_RDONLY }, { ALPHA_O_WRONLY, O_WRONLY }, { ALPHA_O_RDWR, O_RDWR }, { ALPHA_O_APPEND, O_APPEND }, { ALPHA_O_CREAT, O_CREAT }, { ALPHA_O_TRUNC, O_TRUNC }, { ALPHA_O_EXCL, O_EXCL }, { ALPHA_O_NONBLOCK, O_NONBLOCK }, { ALPHA_O_NOCTTY, O_NOCTTY }, { ALPHA_O_SYNC, O_SYNC } }; #define ALPHA_NFLAGS 10 /** alpha statbuf structure */ struct alpha_statbuf { uint32_t st_dev; uint32_t st_ino; uint32_t st_mode; uint16_t st_nlink; uint16_t nothing0; uint32_t st_uid; int32_t st_gid; uint32_t st_rdev; uint32_t nothing1; uint64_t st_size; uint32_t st_atim; uint32_t st_spare1; uint32_t st_mtim; uint32_t st_spare2; uint32_t st_ctim; uint32_t st_spare3; uint32_t st_blksize; uint32_t st_blocks; uint32_t st_gennum; uint32_t st_spare4; }; /** alpha statfs structure */ struct alpha_statfs { int16_t f_type; int16_t f_flags; uint32_t f_fsize; uint32_t f_bsize; uint32_t f_blocks; uint32_t f_bfree; uint32_t f_bavail; uint32_t f_files; uint32_t f_ffree; uint64_t f_fsid; uint32_t f_spare[9]; }; /** alpha timeval structure */ struct alpha_timeval { int16_t tv_sec; int16_t tv_usec; }; /** alpha timezone structure */ struct alpha_timezone { int16_t tz_minuteswest; int16_t tz_dsttime; }; /** alpha rusage structure */ struct alpha_rusage { struct alpha_timeval ru_utime; struct alpha_timeval ru_stime; int32_t ru_maxrss; int32_t ru_ixrss; int32_t ru_idrss; int32_t ru_isrss; int32_t ru_minflt; int32_t ru_majflt; int32_t ru_nswap; int32_t ru_inblock; int32_t ru_oublock; int32_t ru_msgsnd; int32_t ru_msgrcv; int32_t ru_nsignals; int32_t ru_nvcsw; int32_t ru_nivcsw; }; #define ALPHA_NSIG 32 /** emulated alpha signal action vector */ uint64_t signal_action_vector[ALPHA_NSIG] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* returns size of alpha_dirent structure */ #define DIRENT_SZ(STR) (sizeof(uint32_t) + 2*sizeof(uint16_t) + (((strlen(STR) + 1) + 3)/4)*4) /** alpha dirent structure */ struct alpha_dirent { uint32_t d_ino; uint16_t d_reclen; uint16_t d_namlen; char d_name[256]; }; /** alpha rlimit structure */ struct alpha_rlimit { uint64_t rlim_cur; uint64_t rlim_max; }; #define ALPHA_TBL_SYSINFO 12 /** alpha tbl_sysinfo structure hello */ struct alpha_tbl_sysinfo { int16_t si_user; int16_t si_nice; int16_t si_sys; int16_t si_idle; int16_t si_hz; int16_t si_phz; int16_t si_boottime; int16_t wait; }; /** From a system call number identification return its name. @param num the system call number identification @return the name of the system call */ static char *alpha_get_syscall_name(int num) { char buffer[256]; switch(num) { case SYSCALL_syscall: return "syscall"; case SYSCALL_exit: return "exit"; case SYSCALL_read: return "read"; case SYSCALL_write: return "write"; case SYSCALL_close: return "close"; case SYSCALL_unlink: return "unlink"; case SYSCALL_obreak: return "obreak"; case SYSCALL_lseek: return "lseek"; case SYSCALL_getpid: return "getpid"; case SYSCALL_getuid: return "getuid"; case SYSCALL_open: return "open"; case SYSCALL_sigprocmask: return "sigprocmask"; case SYSCALL_ioctl: return "ioctl"; case SYSCALL_getpagesize: return "getpagesize"; case SYSCALL_fstat: return "fstat"; case SYSCALL_getgid: return "getgid"; case SYSCALL_stat: return "stat"; case SYSCALL_lstat: return "lstat"; case SYSCALL_fcntl: return "fcntl"; case SYSCALL_gettimeofday: return "gettimeofday"; case SYSCALL_getrusage: return "getrusage"; case SYSCALL_ftruncate: return "ftruncate"; case SYSCALL_getrlimit: return "getrlimit"; case SYSCALL_setrlimit: return "setrlimit"; case SYSCALL_sigaction: return "sigaction"; case SYSCALL_getdirentries: return "getdirentries"; case SYSCALL_statfs: return "statfs"; case SYSCALL_usleep_thread: return "usleep_thread"; case SYSCALL_setsysinfo: return "setsysinfo"; case SYSCALL_table: return "table"; case SYSCALL_rename: return "rename"; case SYSCALL_dup: return "dup"; case SYSCALL_mmap: return "mmap"; default: sprintf(buffer,"Unknow syscall. Syscall num: %u\n",num); error(buffer); } return NULL; } /** Implementation of alpha exit system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_exit(system_handler_t *handler) { running = FALSE; return TRUE; } /** Implementation of alpha read system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_read(system_handler_t *handler) { char *buffer; uint64_t nbytes; uint64_t file_descriptor; uint64_t buffer_address; uint64_t val64; nbytes = READ_GPR(A2_REG); file_descriptor = READ_GPR(A0_REG); buffer_address = READ_GPR(A1_REG); /* allocate temporary buffer */ buffer = (char *)calloc(nbytes, sizeof(char)); if(!buffer) error("syscall_read: calloc error\n"); /* perform read */ do { WRITE_GPR(V0_REG, read(file_descriptor, buffer, nbytes)); } while (READ_GPR(V0_REG) == -1 && errno == EAGAIN); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } MEM_WRITE(buffer_address, buffer, nbytes); free(buffer); return TRUE; } /** Implementation of alpha write system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_write(system_handler_t *handler) { char *buffer; uint64_t nbytes; uint64_t file_descriptor; uint64_t buffer_address; uint64_t val64; nbytes = READ_GPR(A2_REG); file_descriptor = READ_GPR(A0_REG); buffer_address = READ_GPR(A1_REG); /* allocate temporary buffer */ buffer = (char *)calloc(nbytes, sizeof(char)); if(!buffer) error("syscall_write: calloc error\n"); /* read the emulator/simulator memory */ MEM_READ(buffer, buffer_address, nbytes); do { WRITE_GPR(V0_REG, write(file_descriptor, buffer, nbytes)); } while (READ_GPR(V0_REG) == -1 && errno == EAGAIN); if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } free(buffer); return TRUE; } /** Implementation of alpha exit system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_close(system_handler_t *handler) { uint64_t file_descriptor; uint64_t val64; file_descriptor = READ_GPR(A0_REG); /* check file descriptor to avoid closing stderr, stdin and stdout */ switch(file_descriptor) { case 0: case 1: case 2: WRITE_GPR(A3_REG,0); return TRUE; break; default: /* file descriptor is ok */ break; } /* close file */ WRITE_GPR(V0_REG,close(file_descriptor)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } return TRUE; } /** Implementation of alpha exit system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_obreak(system_handler_t *handler) { address_t addr; uint64_t val64; addr = READ_GPR(A0_REG); break_pointer = addr; WRITE_GPR(V0_REG,break_pointer); WRITE_GPR(A3_REG,0); return TRUE; } /** Implementation of alpha lseek system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_lseek(system_handler_t *handler) { uint64_t file_descriptor; uint64_t offset; uint64_t whence; uint64_t val64; file_descriptor = READ_GPR(A0_REG); offset = READ_GPR(A1_REG); whence = READ_GPR(A2_REG); /* perform seek */ WRITE_GPR(V0_REG, lseek(file_descriptor, offset, whence)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } return TRUE; } /** Implementation of alpha getpid system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_getpid(system_handler_t *handler) { uint64_t val64; /* id of the proccess */ WRITE_GPR(V0_REG, getpid()); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } return TRUE; } /** Implementation of alpha setpid system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_getuid(system_handler_t *handler) { uint64_t val64; /* get user id */ WRITE_GPR(V0_REG,getuid()); WRITE_GPR(A4_REG,geteuid()); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } return TRUE; } /** Implementation of alpha open system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_open(system_handler_t *handler) { char buf[BUFFER_SIZE]; unsigned int i; int alpha_flags , local_flags; uint64_t file_name; uint64_t mode; uint64_t val64; file_name = READ_GPR(A0_REG); alpha_flags = READ_GPR(A1_REG); mode = READ_GPR(A2_REG); local_flags = 0; /* read file name */ mem_read_str(handler, file_name, buf); /* alpha flags -> local flags * and afterwards check that all flags have been decoded */ for (i=0; i < ALPHA_NFLAGS; i++) { if(alpha_flags & alpha_flag_table[i].alpha_flag) { alpha_flags &= ~alpha_flag_table[i].alpha_flag; local_flags |= alpha_flag_table[i].local_flag; } } if(alpha_flags != 0) error("syscall_open: could not decode all alpha flags\n"); WRITE_GPR(V0_REG,open(buf, local_flags, mode)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } return TRUE; } /** Implementation of alpha sigprocmask system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_sigprocmask(system_handler_t *handler) { uint64_t val64; WRITE_GPR(V0_REG,sigmask); WRITE_GPR(A3_REG, 0); switch (READ_GPR(A0_REG)) { case ALPHA_SIG_BLOCK: sigmask |= READ_GPR(A1_REG); break; case ALPHA_SIG_UNBLOCK: sigmask &= ~READ_GPR(A1_REG); break; case ALPHA_SIG_SETMASK: sigmask = READ_GPR(A1_REG); break; default: WRITE_GPR(V0_REG, EINVAL); WRITE_GPR(A3_REG, 1); } return TRUE; } /** Implementation of alpha ioctl system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_ioctl(system_handler_t *handler) { uint64_t request; uint64_t buffer_address; uint64_t file_descriptor; int nread; struct termios local_buffer; struct osf_sgttyb buffer; uint64_t val64; request = READ_GPR(A1_REG); buffer_address = READ_GPR(A2_REG); file_descriptor = READ_GPR(A0_REG); switch (request) { case ALPHA_TIOCGETP: WRITE_GPR(V0_REG, tcgetattr((int)file_descriptor, &local_buffer)); /* translation */ buffer.sg_ispeed = local_buffer.c_ispeed; buffer.sg_ospeed = local_buffer.c_ospeed; buffer.sg_erase = local_buffer.c_cc[VERASE]; buffer.sg_kill = local_buffer.c_cc[VKILL]; buffer.sg_flags = 0; MEM_WRITE(buffer_address, &buffer, sizeof(struct osf_sgttyb)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } case ALPHA_FIONREAD: #ifndef __CYGWIN__ request = FIONREAD; #else request = TIOCINQ; #endif WRITE_GPR(V0_REG, ioctl(file_descriptor, request, &nread)); MEM_WRITE(buffer_address, &nread, sizeof(nread)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } break; default: warning("ioctl call not supported\n"); WRITE_GPR(A3_REG, 0); break; } return TRUE; } /** Implementation of alpha getgid system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_getgid(system_handler_t *handler) { uint64_t val64; /* get group id */ WRITE_GPR(V0_REG, getgid()); WRITE_GPR(A4_REG, getegid()); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } return TRUE; } /** Implementation of alpha getpagesize system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_getpagesize(system_handler_t *handler) { uint64_t val64; WRITE_GPR(V0_REG,MEMORY_PAGE_SIZE); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } return TRUE; } /** Implementation of alpha fstat system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_fstat(system_handler_t *handler) { uint64_t file_descriptor; uint64_t buffer_address; struct alpha_statbuf alpha_sbuf; struct stat sbuf; uint64_t val64; file_descriptor = READ_GPR(A0_REG); buffer_address = READ_GPR(A1_REG); WRITE_GPR(V0_REG, fstat(file_descriptor, &sbuf)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } /* stat -> alpha_stat * and write it to the emulator/simulator memory */ alpha_sbuf.st_dev = SWAP32(sbuf.st_dev); alpha_sbuf.st_ino = SWAP32(sbuf.st_ino); alpha_sbuf.st_mode = SWAP32(sbuf.st_mode); alpha_sbuf.st_nlink = SWAP16(sbuf.st_nlink); alpha_sbuf.st_uid = SWAP32(sbuf.st_uid); alpha_sbuf.st_gid = SWAP32(sbuf.st_gid); alpha_sbuf.st_rdev = SWAP32(sbuf.st_rdev); alpha_sbuf.st_size = SWAP64(sbuf.st_size); alpha_sbuf.st_atim = SWAP32(sbuf.st_atime); alpha_sbuf.st_mtim = SWAP32(sbuf.st_mtime); alpha_sbuf.st_ctim = SWAP32(sbuf.st_ctime); alpha_sbuf.st_blksize = SWAP32(sbuf.st_blksize); alpha_sbuf.st_blocks = SWAP32(sbuf.st_blocks); MEM_WRITE(buffer_address,&alpha_sbuf,sizeof(struct alpha_statbuf)); return TRUE; } /** Implementation of alpha fcntl system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_fcntl(system_handler_t *handler) { uint64_t file_descriptor; uint64_t command; uint64_t arg; uint64_t val64; file_descriptor = READ_GPR(A0_REG); command = READ_GPR(A1_REG); arg = READ_GPR(A2_REG); WRITE_GPR(V0_REG, fcntl(file_descriptor, command, arg)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG,0); } else { WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG,errno); } return TRUE; } /** Implementation of alpha gettimeofday system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_gettimeofday(system_handler_t *handler) { uint64_t timeval; uint64_t timezone; struct alpha_timeval alpha_tv; struct timeval tv, *tvp; struct alpha_timezone alpha_tz; struct timezone tz, *tzp; timeval = READ_GPR(A0_REG); timezone = READ_GPR(A1_REG); if(timeval != 0) { MEM_READ(&alpha_tv, timeval, sizeof(struct alpha_timeval)); /* alpha tv -> tv */ tv.tv_sec = SWAP32(alpha_tv.tv_sec); tv.tv_usec = SWAP32(alpha_tv.tv_usec); tvp = &tv; } else tvp = NULL; if(timezone != 0) { MEM_READ(&alpha_tz, timezone, sizeof(struct alpha_timezone)); /* alpha tz -> tz */ tz.tz_minuteswest = SWAP32(alpha_tz.tz_minuteswest); tz.tz_dsttime = SWAP32(alpha_tz.tz_dsttime); tzp = &tz; } else tzp = NULL; WRITE_GPR(V0_REG, gettimeofday(tvp, tzp)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } if(timeval != 0) { /* tv -> alpha tv */ alpha_tv.tv_sec = SWAP32(tv.tv_sec); alpha_tv.tv_usec = SWAP32(tv.tv_usec); MEM_WRITE(timeval, &alpha_tv, sizeof(struct alpha_timeval)); } if(timezone != 0) { /* tz -> alpha tz */ alpha_tz.tz_minuteswest = SWAP32(tz.tz_minuteswest); alpha_tz.tz_dsttime = SWAP32(tz.tz_dsttime); MEM_WRITE(timezone,&alpha_tz,sizeof(struct alpha_timezone)); } return TRUE; } /** Implementation of alpha getrlimit system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_getrlimit(system_handler_t *handler) { struct alpha_rlimit alpha_rl; struct rlimit rl; MEM_READ(&alpha_rl,READ_GPR(A1_REG), sizeof(struct alpha_rlimit)); /* alpha rl -> rl */ rl.rlim_cur = SWAP64(alpha_rl.rlim_cur); rl.rlim_max = SWAP64(alpha_rl.rlim_max); WRITE_GPR(V0_REG, getrlimit(READ_GPR(A0_REG), &rl)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } /* rl -> alpha rl */ alpha_rl.rlim_cur = SWAP64(rl.rlim_cur); alpha_rl.rlim_max = SWAP64(rl.rlim_max); MEM_WRITE(READ_GPR(A1_REG), &alpha_rl, sizeof(struct alpha_rlimit)); return TRUE; } /** Implementation of alpha setrlimit system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_setrlimit(system_handler_t *handler) { uint64_t rl_address; uint64_t rl_limit; struct alpha_rlimit alpha_rl; struct rlimit rl; rl_limit = READ_GPR(A0_REG); rl_address = READ_GPR(A1_REG); MEM_READ(&alpha_rl, rl_address, sizeof(struct alpha_rlimit)); /* alpha rl -> rl */ rl.rlim_cur = SWAP64(alpha_rl.rlim_cur); rl.rlim_max = SWAP64(alpha_rl.rlim_max); WRITE_GPR(V0_REG, setrlimit(rl_limit, &rl)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } /* rl -> alpha rl */ alpha_rl.rlim_cur = SWAP64(rl.rlim_cur); alpha_rl.rlim_max = SWAP64(rl.rlim_max); MEM_WRITE(rl_address, &alpha_rl, sizeof(struct alpha_rlimit)); return TRUE; } /** Implementation of alpha getdirentries system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_getdirentries(system_handler_t *handler) { int i, counter, alpha_counter; struct dirent *direntp; int32_t fd = READ_GPR(A0_REG); address_t alpha_buffer = READ_GPR(A1_REG); char *buffer; int32_t alpha_nbytes = READ_GPR(A2_REG); address_t alpha_pbase = READ_GPR(A3_REG); int64_t alpha_base; long base = 0; /* number of entries to get */ if(!alpha_nbytes) warning("syscall_getdirentries getting 0 directory entries...\n"); /* allocate buffer */ buffer = calloc(1, alpha_nbytes); if(!buffer) error("syscall_getdirentries: calloc could not be done\n"); #ifndef __CYGWIN__ WRITE_GPR(V0_REG, getdirentries((int)fd, buffer, (size_t)alpha_nbytes, &base)); #endif /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) { WRITE_GPR(A3_REG, 0); /* copy back? */ if(READ_GPR(V0_REG) > 0) { /* copy entries */ for (i=0, counter=0, alpha_counter=0, direntp=(struct dirent *)buffer; #ifndef __CYGWIN__ counter < READ_GPR(V0_REG) && direntp->d_reclen > 0; i++, counter += direntp->d_reclen, direntp=(struct dirent *)(buffer+counter)) { #else counter < READ_GPR(V0_REG) && direntp->d_fd > 0; i++, counter += direntp->d_fd, direntp=(struct dirent *)(buffer+counter)) { #endif struct alpha_dirent alpha_dirent; alpha_dirent.d_ino = SWAP32(direntp->d_ino); alpha_dirent.d_namlen = SWAP16(strlen(direntp->d_name)); strcpy(alpha_dirent.d_name, direntp->d_name); alpha_dirent.d_reclen = SWAP16(DIRENT_SZ(direntp->d_name)); MEM_WRITE(alpha_buffer + alpha_counter, &alpha_dirent, DIRENT_SZ(direntp->d_name)); alpha_counter += DIRENT_SZ(direntp->d_name); } if(alpha_pbase != 0) { alpha_base = (int64_t)base; MEM_WRITE(alpha_pbase, &alpha_base, sizeof(alpha_base)); } /* V0 = translated read length */ WRITE_GPR(V0_REG, alpha_counter); } } else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } free(buffer); return TRUE; } /** Implementation of alpha sigaction system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_sigaction(system_handler_t *handler) { int signum; uint64_t action; uint64_t dest; signum = READ_GPR(A0_REG); action = READ_GPR(A1_REG); dest = READ_GPR(A2_REG); if(READ_GPR(A1_REG) != 0) signal_action_vector[signum] = action; if(dest != 0) WRITE_GPR(A2_REG, signal_action_vector[signum]); WRITE_GPR(V0_REG, 0); WRITE_GPR(A3_REG, 0); return TRUE; } /** Implementation of alpha usleep system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_usleep_thread(system_handler_t *handler) { uint64_t usleep_time; usleep_time = READ_GPR(A0_REG); usleep((unsigned int)usleep_time); WRITE_GPR(V0_REG, 0); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } return TRUE; } /** Implementation of alpha setsysinfo system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_setsysinfo(system_handler_t *handler) { warning("setsysinfo() is not supported\n"); WRITE_GPR(V0_REG, 0); return TRUE; } /** Implementation of alpha stat system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_stat(system_handler_t *handler) { char buffer[BUFFER_SIZE]; struct alpha_statbuf alpha_sbuf; struct stat sbuf; uint64_t name_address; uint64_t buffer_address; name_address = READ_GPR(A0_REG); buffer_address = READ_GPR(A1_REG); /* get filename */ mem_read_str(handler, name_address, buffer); /* perform stat */ WRITE_GPR(V0_REG, stat(buffer, &sbuf)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } /* stat -> alpha stat */ alpha_sbuf.st_dev = SWAP32(sbuf.st_dev); alpha_sbuf.st_ino = SWAP32(sbuf.st_ino); alpha_sbuf.st_mode = SWAP32(sbuf.st_mode); alpha_sbuf.st_nlink = SWAP16(sbuf.st_nlink); alpha_sbuf.st_uid = SWAP32(sbuf.st_uid); alpha_sbuf.st_gid = SWAP32(sbuf.st_gid); alpha_sbuf.st_rdev = SWAP32(sbuf.st_rdev); alpha_sbuf.st_size = SWAP64(sbuf.st_size); alpha_sbuf.st_atim = SWAP32(sbuf.st_atime); alpha_sbuf.st_mtim = SWAP32(sbuf.st_mtime); alpha_sbuf.st_ctim = SWAP32(sbuf.st_ctime); alpha_sbuf.st_blksize = SWAP32(sbuf.st_blksize); alpha_sbuf.st_blocks = SWAP32(sbuf.st_blocks); /* copy results to emulator/simulator memory */ MEM_WRITE(buffer_address, &alpha_sbuf, sizeof(struct alpha_statbuf)); return TRUE; } /** Implementation of alpha statfs system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_statfs(system_handler_t *handler) { char buffer[BUFFER_SIZE]; struct alpha_statfs alpha_sbuf; struct statfs sbuf; uint64_t name_address; uint64_t buffer_address; name_address = READ_GPR(A0_REG); buffer_address = READ_GPR(A1_REG); /* get filename */ mem_read_str(handler, name_address, buffer); /* perform statfs */ WRITE_GPR(V0_REG, statfs(buffer, &sbuf)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } /* statfs -> alpha statfs */ alpha_sbuf.f_type = SWAP16(sbuf.f_type); alpha_sbuf.f_fsize = SWAP32(sbuf.f_bsize); alpha_sbuf.f_blocks = SWAP32(sbuf.f_blocks); alpha_sbuf.f_bfree = SWAP32(sbuf.f_bfree); alpha_sbuf.f_bavail = SWAP32(sbuf.f_bavail); alpha_sbuf.f_files = SWAP32(sbuf.f_files); alpha_sbuf.f_ffree = SWAP32(sbuf.f_ffree); /* copy results to emulator/simulator memory */ MEM_WRITE(buffer_address, &alpha_sbuf, sizeof(struct alpha_statbuf)); return TRUE; } /** Implementation of alpha lstat system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_lstat(system_handler_t *handler) { char buffer[BUFFER_SIZE]; struct alpha_statbuf alpha_sbuf; struct stat sbuf; uint64_t name_address; uint64_t buffer_address; name_address = READ_GPR(A0_REG); buffer_address = READ_GPR(A1_REG); /* get filename */ mem_read_str(handler, name_address, buffer); /* perform lstat */ WRITE_GPR(V0_REG, lstat(buffer, &sbuf)); /* errors */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } /* stat -> alpha stat */ alpha_sbuf.st_dev = SWAP32(sbuf.st_dev); alpha_sbuf.st_ino = SWAP32(sbuf.st_ino); alpha_sbuf.st_mode = SWAP32(sbuf.st_mode); alpha_sbuf.st_nlink = SWAP16(sbuf.st_nlink); alpha_sbuf.st_uid = SWAP32(sbuf.st_uid); alpha_sbuf.st_gid = SWAP32(sbuf.st_gid); alpha_sbuf.st_rdev = SWAP32(sbuf.st_rdev); alpha_sbuf.st_size = SWAP64(sbuf.st_size); alpha_sbuf.st_atim = SWAP32(sbuf.st_atime); alpha_sbuf.st_mtim = SWAP32(sbuf.st_mtime); alpha_sbuf.st_ctim = SWAP32(sbuf.st_ctime); alpha_sbuf.st_blksize = SWAP32(sbuf.st_blksize); alpha_sbuf.st_blocks = SWAP32(sbuf.st_blocks); /* copy results to emulator simulator memory */ MEM_WRITE(buffer_address, &alpha_sbuf, sizeof(struct alpha_statbuf)); return TRUE; } /** Implementation of alpha ftruncate system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_ftruncate(system_handler_t *handler) { uint64_t file_descriptor; uint64_t length; file_descriptor = READ_GPR(A0_REG); length = READ_GPR(A1_REG); /* perform ftruncate */ WRITE_GPR(V0_REG, ftruncate((int)file_descriptor, (size_t)length)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } return TRUE; } /** Implementation of alpha getrusage system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_getrusage(system_handler_t *handler) { uint64_t rusageid; uint64_t buffer_address; struct rusage local_rusage; struct alpha_rusage rusage; rusageid = READ_GPR(A0_REG); buffer_address = READ_GPR(A1_REG); /* perform getrusage */ WRITE_GPR(V0_REG, getrusage(rusageid, &local_rusage)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } /* rusage -> alpha rusage */ rusage.ru_utime.tv_sec = SWAP32(local_rusage.ru_utime.tv_sec); rusage.ru_utime.tv_usec = SWAP32(local_rusage.ru_utime.tv_usec); rusage.ru_utime.tv_sec = SWAP32(local_rusage.ru_utime.tv_sec); rusage.ru_utime.tv_usec = SWAP32(local_rusage.ru_utime.tv_usec); rusage.ru_stime.tv_sec = SWAP32(local_rusage.ru_stime.tv_sec); rusage.ru_stime.tv_usec = SWAP32(local_rusage.ru_stime.tv_usec); rusage.ru_stime.tv_sec = SWAP32(local_rusage.ru_stime.tv_sec); rusage.ru_stime.tv_usec = SWAP32(local_rusage.ru_stime.tv_usec); rusage.ru_maxrss = SWAP32(local_rusage.ru_maxrss); rusage.ru_ixrss = SWAP32(local_rusage.ru_ixrss); rusage.ru_idrss = SWAP32(local_rusage.ru_idrss); rusage.ru_isrss = SWAP32(local_rusage.ru_isrss); rusage.ru_minflt = SWAP32(local_rusage.ru_minflt); rusage.ru_majflt = SWAP32(local_rusage.ru_majflt); rusage.ru_nswap = SWAP32(local_rusage.ru_nswap); rusage.ru_inblock = SWAP32(local_rusage.ru_inblock); rusage.ru_oublock = SWAP32(local_rusage.ru_oublock); rusage.ru_msgsnd = SWAP32(local_rusage.ru_msgsnd); rusage.ru_msgrcv = SWAP32(local_rusage.ru_msgrcv); rusage.ru_nsignals = SWAP32(local_rusage.ru_nsignals); rusage.ru_nvcsw = SWAP32(local_rusage.ru_nvcsw); rusage.ru_nivcsw = SWAP32(local_rusage.ru_nivcsw); /* write results to emulator/simulator memory */ MEM_WRITE(buffer_address, &rusage, sizeof(struct alpha_rusage)); return TRUE; } /** Implementation of alpha unlink system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_unlink(system_handler_t *handler) { uint64_t name_address; char buffer[BUFFER_SIZE]; name_address = READ_GPR(A0_REG); /* get filename */ mem_read_str(handler, name_address, buffer); /* delete file */ WRITE_GPR(V0_REG, unlink(buffer)); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } return TRUE; } /** Implementation of alpha table system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_table(system_handler_t *handler) { uint64_t table_id, table_index, buf_addr, num_elem, size_elem; struct alpha_tbl_sysinfo sysinfo; struct rusage rusage_info; table_id = READ_GPR(A1_REG); table_index = READ_GPR(A2_REG); buf_addr = READ_GPR(A3_REG); num_elem = READ_GPR(A4_REG); size_elem = READ_GPR(A5_REG); switch(table_id) { case ALPHA_TBL_SYSINFO: if(table_index != 0) { error("syscall_table: table id must be 0\n"); } else { if(num_elem != 1) { error("syscall_table: num elem must be 1\n"); } else { /* determine user & system time */ if(getrusage(RUSAGE_SELF, &rusage_info) < 0) { /* error */ WRITE_GPR(A3_REG,-1); WRITE_GPR(V0_REG, errno); break; } /* get clock tick frequency */ sysinfo.si_hz = sysconf(_SC_CLK_TCK); /* clock ticks from user and system time */ sysinfo.si_user = rusage_info.ru_utime.tv_sec * sysinfo.si_hz + (rusage_info.ru_utime.tv_usec * sysinfo.si_hz) / 1000000UL; sysinfo.si_sys = rusage_info.ru_stime.tv_sec * sysinfo.si_hz + (rusage_info.ru_stime.tv_usec * sysinfo.si_hz) / 1000000UL; sysinfo.si_nice = 0; sysinfo.si_idle = 0; sysinfo.si_phz = 0; sysinfo.si_boottime = 0; sysinfo.wait = 0; /* write results */ MEM_WRITE(buf_addr,&sysinfo,sizeof(struct alpha_tbl_sysinfo)); WRITE_GPR(A3_REG, 0); } break; default: warning("table: unsupported table id\n"); WRITE_GPR(A3_REG, 0); } } return TRUE; } /** Implementation of alpha rename system call. @param handler the emulator state access handler @return TRUE(1) if succeded, FALSE(0) if not */ BOOL syscall_rename(system_handler_t *handler) { /* ???? */ return TRUE; } BOOL syscall_dup(system_handler_t *handler) { /* performs a dup */ WRITE_GPR(V0_REG, dup(READ_GPR(A0_REG))); /* errors??? */ if(READ_GPR(V0_REG) != (uint64_t)-1) WRITE_GPR(A3_REG, 0); else { WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, errno); } } /** */ void do_syscall(system_handler_t *handler) { int syscall_num; BOOL ret = FALSE; syscall_num = SYSCALL_NUM; if(syscall_num==SYSCALL_syscall) syscall_num = READ_GPR(A0_REG); if(verbose) fprintf(verbose, "got a system call (number : %u; name : %s)\n", syscall_num, alpha_get_syscall_name(syscall_num)); if(syscall_num==SYSCALL_syscall) syscall_num = READ_GPR(A0_REG); switch(syscall_num) { case SYSCALL_exit: ret=syscall_exit(handler); break; case SYSCALL_read: ret=syscall_read(handler); break; case SYSCALL_write: ret=syscall_write(handler); break; case SYSCALL_close: ret=syscall_close(handler); break; case SYSCALL_unlink: ret=syscall_unlink(handler); break; case SYSCALL_obreak: ret=syscall_obreak(handler); break; case SYSCALL_lseek: ret=syscall_lseek(handler); break; case SYSCALL_getpid: ret=syscall_getpid(handler); break; case SYSCALL_getuid: ret=syscall_getuid(handler); break; case SYSCALL_open: ret=syscall_open(handler); break; case SYSCALL_getdirentries: ret=syscall_getdirentries(handler); break; case SYSCALL_sigprocmask: ret=syscall_sigprocmask(handler); break; case SYSCALL_ioctl: ret=syscall_ioctl(handler); break; case SYSCALL_getgid: ret=syscall_getgid(handler); break; case SYSCALL_getpagesize: ret=syscall_getpagesize(handler); break; case SYSCALL_fstat: ret=syscall_fstat(handler); break; case SYSCALL_fcntl: ret=syscall_fcntl(handler); break; case SYSCALL_gettimeofday: ret=syscall_gettimeofday(handler); break; case SYSCALL_getrlimit: ret=syscall_getrlimit(handler); break; case SYSCALL_setrlimit: ret=syscall_setrlimit(handler); break; case SYSCALL_usleep_thread: ret=syscall_usleep_thread(handler); break; case SYSCALL_sigaction: ret=syscall_sigaction(handler); break; case SYSCALL_setsysinfo: ret=syscall_setsysinfo(handler); break; case SYSCALL_stat: ret=syscall_stat(handler); break; case SYSCALL_statfs: ret=syscall_statfs(handler); break; case SYSCALL_lstat: ret=syscall_lstat(handler); break; case SYSCALL_ftruncate: ret=syscall_ftruncate(handler); break; case SYSCALL_getrusage: ret=syscall_getrusage(handler); break; case SYSCALL_table: ret=syscall_table(handler); break; case SYSCALL_rename: ret=syscall_rename(handler); break; case SYSCALL_dup: ret=syscall_dup(handler); break; default: fprintf(stderr,"syscall not implemented (number:%u; name: %s)\n", syscall_num, alpha_get_syscall_name(syscall_num)); //exit(-1); WRITE_GPR(A3_REG, -1); WRITE_GPR(V0_REG, 0); break; } if(!ret) { } else { } } void sc_impl(int complete, state_t *state, memory_t *mem) { ((emulstate_t *)emul_handler.instance)->state = state; ((emulstate_t *)emul_handler.instance)->mem = mem; ((emulstate_t *)emul_handler.instance)->complete = complete; do_syscall(&emul_handler); } --------------000402030208010603020006 Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --------------000402030208010603020006--